From 3c611908eda8e6df49a583d623f27bd0f221c86c Mon Sep 17 00:00:00 2001 From: Ravindra Rathor Date: Fri, 29 Dec 2023 22:19:35 +0530 Subject: [PATCH] feat(start-request-params): added the ability to control start request params --- README.md | 27 +++++++++++++++++++ demo/index.ts | 6 +++++ package-lock.json | 40 +++++++++++++++++++++++++--- package.json | 5 +++- src/param_types.ts | 3 +++ src/symbl_transcriptions.ts | 52 +++++++++++++++++++++---------------- 6 files changed, 106 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 6bb2de3..e17990e 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,12 @@ activateTranscriptions({ symblAccessToken: 'ACCESS_TOKEN_FROM_SYMBL_AI', connectionId: 'SOME_ARBITRARY_CONNECTION_ID', // optional, speakerUserId: 'SOME_ARBITRARY_USER_ID_FOR_SPEAKER', // optional + symblStartRequestParams: { // optional. Subset of https://docs.symbl.ai/reference/streaming-api-reference#start_request + noConnectionTimeout: 0, + config: { + sentiment: false, + }, + }, }); ``` @@ -40,6 +46,27 @@ This method internally connects with Symbl using Websocket connection & automati `speakerUserId` field is optional. If not passed, value of `meeting.self.clientSpecificId` will be used as `speakerUserId`. +`symblStartRequestParams` field is optional. In case you want to control Symbl settings further, you can override the values by passing just the fields to override, from https://docs.symbl.ai/reference/streaming-api-reference#start_request. + +We perform deep merge of the passed value with the defaults, therefore no need to construct complete start_request message. For example, If you want to add just the email field to speaker and also want to change noConnectionTimeout to 300, you can do so using the following code snippet. + +```js +activateTranscriptions({ + meeting: meeting, // From DyteClient.init + symblAccessToken: 'ACCESS_TOKEN_FROM_SYMBL_AI', + connectionId: 'SOME_ARBITRARY_CONNECTION_ID', // optional, + speakerUserId: 'SOME_ARBITRARY_USER_ID_FOR_SPEAKER', // optional + symblStartRequestParams: { // optional. Any subset of https://docs.symbl.ai/reference/streaming-api-reference#start_request + noConnectionTimeout: 300, + speaker: { + email: 'test@test.com', + } + } +}); +``` + +Note: If, in case, the passed fields are incorrect or poorly placed, conversation might not get created. In such cases, an error would be logged in developer console for you to debug further. + 4. If you want to show transcriptions to a participant or for `self`, you can do so using the following snippet. diff --git a/demo/index.ts b/demo/index.ts index 8b5831e..208f1e9 100644 --- a/demo/index.ts +++ b/demo/index.ts @@ -43,6 +43,12 @@ const init = async () => { meeting, languageCode: 'en-US', symblAccessToken, + symblStartRequestParams: { // optional. Subset of https://docs.symbl.ai/reference/streaming-api-reference#start_request + noConnectionTimeout: 0, + config: { + sentiment: false, + }, + }, }); await addTranscriptionsListener({ diff --git a/package-lock.json b/package-lock.json index e263517..522d15b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "@dyte-in/symbl-transcription", "version": "2.1.0", "license": "ISC", + "dependencies": { + "lodash-es": "^4.17.21" + }, "devDependencies": { "@commitlint/cli": "^13.1.0", "@commitlint/config-conventional": "^13.1.0", @@ -21,6 +24,7 @@ "@semantic-release/release-notes-generator": "^9.0.3", "@types/events": "^3.0.0", "@types/jest": "^27.0.6", + "@types/lodash-es": "^4.17.12", "@types/long": "4.0.0", "@types/node": "^16.0.0", "@types/uuid": "^8.3.4", @@ -2029,6 +2033,21 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/lodash": { + "version": "4.14.202", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz", + "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==", + "dev": true + }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, "node_modules/@types/long": { "version": "4.0.0", "dev": true, @@ -7648,8 +7667,7 @@ "node_modules/lodash-es": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", - "dev": true + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, "node_modules/lodash.camelcase": { "version": "4.3.0", @@ -20451,6 +20469,21 @@ "version": "3.0.2", "dev": true }, + "@types/lodash": { + "version": "4.14.202", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz", + "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==", + "dev": true + }, + "@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, "@types/long": { "version": "4.0.0", "dev": true @@ -24089,8 +24122,7 @@ "lodash-es": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", - "dev": true + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, "lodash.camelcase": { "version": "4.3.0", diff --git a/package.json b/package.json index b387bea..8342fee 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,9 @@ "peerDepdendencies": { "@dytesdk/web-core": ">=0.26.0" }, - "dependencies": {}, + "dependencies": { + "lodash-es": "^4.17.21" + }, "devDependencies": { "@commitlint/cli": "^13.1.0", "@commitlint/config-conventional": "^13.1.0", @@ -57,6 +59,7 @@ "@semantic-release/release-notes-generator": "^9.0.3", "@types/events": "^3.0.0", "@types/jest": "^27.0.6", + "@types/lodash-es": "^4.17.12", "@types/long": "4.0.0", "@types/node": "^16.0.0", "@types/uuid": "^8.3.4", diff --git a/src/param_types.ts b/src/param_types.ts index d5553fe..1e9ba53 100644 --- a/src/param_types.ts +++ b/src/param_types.ts @@ -7,6 +7,9 @@ export interface ActivateTranscriptionsConfig { languageCode?: string, connectionId?: string, speakerUserId?: string, + symblStartRequestParams?: { // https://docs.symbl.ai/reference/streaming-api-reference#start_request + [key:string]: any, + }, } export interface DeactivateTranscriptionsConfig { diff --git a/src/symbl_transcriptions.ts b/src/symbl_transcriptions.ts index 83e225d..8573e0a 100644 --- a/src/symbl_transcriptions.ts +++ b/src/symbl_transcriptions.ts @@ -1,3 +1,4 @@ +import merge from 'lodash-es/merge'; import audioTranscriptionMiddleware from './audio_middleware'; import { ActivateTranscriptionsConfig, DeactivateTranscriptionsConfig } from './param_types'; import { @@ -7,7 +8,6 @@ import { setTranscriptions, setWebSocket, } from './transcriptions_building_blocks'; - /** * * @param ActivateTranscriptionsConfig Required params to initialise the middleware. @@ -21,6 +21,7 @@ async function activateTranscriptions({ languageCode, connectionId, speakerUserId, + symblStartRequestParams = {}, }: ActivateTranscriptionsConfig) { // As a fail-safe, deactivateTranscriptions if activateTranscriptions function is called twice // eslint-disable-next-line no-use-before-define @@ -35,6 +36,10 @@ async function activateTranscriptions({ // Fired when a message is received from the WebSocket server ws.onmessage = async (event) => { const data = JSON.parse(event.data); + if (data.type === 'error') { + console.error('Symbl error: ', data); + return; + } if (data.type === 'message_response') { data.messages?.forEach((message: any) => { // console.log('Live transcript (more accurate): ', message.payload.content, data); @@ -93,29 +98,32 @@ async function activateTranscriptions({ console.info('Connection to Symbl websocket closed'); }; + // If start_request params are there, they wil be given a top priority + const startRequestParams = merge({ + id: meeting.self.id, + type: 'start_request', + meetingTitle: meeting.meta.meetingTitle, + // insightTypes: ['question', 'action_item'], // Will enable insight generation + config: { + confidenceThreshold: 0.5, + languageCode, // Symbl has bug. This field is not honoured + speechRecognition: { + encoding: 'LINEAR16', + sampleRateHertz: 16000, + }, + }, + speaker: { + // if speaker has email key, transcription gets sent at the end + // speaker supports all arbitary values + userId: speakerUserId || meeting.self.clientSpecificId || meeting.self.id, + name: meeting.self.name, + peerId: meeting.self.id, + }, + }, symblStartRequestParams); + // Fired when the connection succeeds. ws.onopen = () => { - ws.send(JSON.stringify({ - id: meeting.self.id, - type: 'start_request', - meetingTitle: meeting.meta.meetingTitle, - // insightTypes: ['question', 'action_item'], // Will enable insight generation - config: { - confidenceThreshold: 0.5, - languageCode, // Symbl has bug. This field is not honoured - speechRecognition: { - encoding: 'LINEAR16', - sampleRateHertz: 16000, - }, - }, - speaker: { - // if speaker has email key, transcription gets sent at the end - // speaker supports all arbitary values - userId: speakerUserId || meeting.self.clientSpecificId || meeting.self.id, - name: meeting.self.name, - peerId: meeting.self.id, - }, - })); + ws.send(JSON.stringify(startRequestParams)); }; return meeting.self.addAudioMiddleware(audioTranscriptionMiddleware);