@hahnpro/ms-speech-sdk
Version:
Microsoft Cognitive Services Speech SDK for JavaScript
1 lines • 57.7 kB
Source Map (JSON)
{"version":3,"sources":["src/sdk/Transcription/Conversation.ts"],"names":[],"mappings":"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","file":"Conversation.d.ts","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n// Multi-device Conversation is a Preview feature.\n\n/* eslint-disable max-classes-per-file */\n\nimport {\n ConversationConnectionConfig,\n ConversationManager,\n ConversationReceivedTranslationEventArgs,\n ConversationRecognizer,\n ConversationRecognizerFactory,\n ConversationTranslatorCommandTypes,\n ConversationTranslatorMessageTypes,\n IAuthentication,\n IInternalConversation,\n IInternalParticipant,\n InternalParticipants,\n MuteAllEventArgs,\n ParticipantAttributeEventArgs,\n ParticipantEventArgs,\n ParticipantsListEventArgs,\n TranscriberRecognizer\n} from \"../../common.speech/Exports.js\";\nimport {\n IDisposable,\n IErrorMessages,\n marshalPromiseToCallbacks\n} from \"../../common/Exports.js\";\nimport { Contracts } from \"../Contracts.js\";\nimport {\n ConnectionEventArgs,\n ConversationExpirationEventArgs,\n ConversationParticipantsChangedEventArgs,\n ConversationTranslationCanceledEventArgs,\n ConversationTranslationEventArgs,\n ConversationTranslator,\n Participant,\n ParticipantChangedReason,\n ProfanityOption,\n PropertyCollection,\n PropertyId,\n SpeechTranslationConfig,\n} from \"../Exports.js\";\nimport { SpeechTranslationConfigImpl } from \"../SpeechTranslationConfig.js\";\nimport { Callback, ConversationInfo, ConversationProperties, IConversation } from \"./IConversation.js\";\nimport { IParticipant, IUser, TranscriptionParticipant } from \"./IParticipant.js\";\n\nexport abstract class Conversation implements IConversation {\n\n protected constructor() {\n return;\n }\n\n public abstract get authorizationToken(): string;\n\n public abstract get config(): SpeechTranslationConfig;\n\n public abstract get conversationId(): string;\n public abstract get conversationInfo(): ConversationInfo;\n public abstract get properties(): PropertyCollection;\n public abstract get speechRecognitionLanguage(): string;\n public abstract get participants(): Participant[];\n public abstract set authorizationToken(value: string);\n public abstract get isConnected(): boolean;\n\n /**\n * Create a conversation\n * @param speechConfig\n * @param cb\n * @param err\n */\n public static createConversationAsync(speechConfig: SpeechTranslationConfig, arg2?: string | Callback, arg3?: Callback, arg4?: Callback): Conversation {\n Contracts.throwIfNullOrUndefined(speechConfig, ConversationConnectionConfig.restErrors.invalidArgs.replace(\"{arg}\", \"config\"));\n Contracts.throwIfNullOrUndefined(speechConfig.region, ConversationConnectionConfig.restErrors.invalidArgs.replace(\"{arg}\", \"SpeechServiceConnection_Region\"));\n if (!speechConfig.subscriptionKey && !speechConfig.getProperty(PropertyId[PropertyId.SpeechServiceAuthorization_Token])) {\n Contracts.throwIfNullOrUndefined(speechConfig.subscriptionKey, ConversationConnectionConfig.restErrors.invalidArgs.replace(\"{arg}\", \"SpeechServiceConnection_Key\"));\n }\n let conversationImpl: ConversationImpl;\n let cb: Callback;\n let err: Callback;\n if (typeof arg2 === \"string\") {\n conversationImpl = new ConversationImpl(speechConfig, arg2);\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n marshalPromiseToCallbacks((async (): Promise<void> => {})(), arg3, arg4);\n } else {\n conversationImpl = new ConversationImpl(speechConfig);\n cb = arg2;\n err = arg3;\n conversationImpl.createConversationAsync(\n ((): void => {\n if (!!cb) {\n cb();\n }\n }),\n (error: any): void => {\n if (!!err) {\n err(error);\n }\n });\n }\n return conversationImpl;\n\n }\n\n /** Start a conversation. */\n public abstract startConversationAsync(cb?: Callback, err?: Callback): void;\n\n /** Delete a conversation. After this no one will be able to join the conversation. */\n public abstract deleteConversationAsync(cb?: Callback, err?: Callback): void;\n\n /** End a conversation. */\n public abstract endConversationAsync(cb?: Callback, err?: Callback): void;\n\n /** Lock a conversation. This will prevent new participants from joining. */\n public abstract lockConversationAsync(cb?: Callback, err?: Callback): void;\n\n /** Add Participant to Conversation. */\n public abstract addParticipantAsync(participant: IParticipant, cb?: Callback, err?: Callback): void;\n\n /**\n * Mute all other participants in the conversation. After this no other participants will\n * have their speech recognitions broadcast, nor be able to send text messages.\n */\n public abstract muteAllParticipantsAsync(cb?: Callback, err?: Callback): void;\n\n /**\n * Mute a participant.\n * @param userId A user identifier\n */\n public abstract muteParticipantAsync(userId: string, cb?: Callback, err?: Callback): void;\n\n /**\n * Remove a participant from a conversation using the user id, Participant or User object\n * @param userId A user identifier\n */\n public abstract removeParticipantAsync(userId: string | IParticipant | IUser, cb?: Callback, err?: Callback): void;\n\n /** Unlocks a conversation. */\n public abstract unlockConversationAsync(cb?: Callback, err?: Callback): void;\n\n /** Unmute all other participants in the conversation. */\n public abstract unmuteAllParticipantsAsync(cb?: Callback, err?: Callback): void;\n\n /**\n * Unmute a participant.\n * @param userId A user identifier\n */\n public abstract unmuteParticipantAsync(userId: string, cb?: Callback, err?: Callback): void;\n}\n\nexport class ConversationImpl extends Conversation implements IDisposable {\n\n private privConfig: SpeechTranslationConfig;\n private privProperties: PropertyCollection;\n private privLanguage: string;\n private privToken: string;\n private privIsDisposed: boolean;\n private privRoom: IInternalConversation;\n private privManager: ConversationManager;\n private privConversationRecognizer: ConversationRecognizer;\n private privIsConnected: boolean;\n private privParticipants: InternalParticipants;\n private privIsReady: boolean;\n private privConversationTranslator: ConversationTranslator;\n private privTranscriberRecognizer: TranscriberRecognizer;\n private privErrors: IErrorMessages = ConversationConnectionConfig.restErrors;\n private privConversationId: string;\n private readonly privTextMessageMaxLength: number;\n\n /**\n * Create a conversation impl\n * @param speechConfig\n * @param {string} id - optional conversationId\n */\n public constructor(speechConfig: SpeechTranslationConfig, id?: string) {\n super();\n this.privIsConnected = false;\n this.privIsDisposed = false;\n this.privConversationId = \"\";\n this.privProperties = new PropertyCollection();\n this.privManager = new ConversationManager();\n\n // check the speech language\n const language: string = speechConfig.getProperty(PropertyId[PropertyId.SpeechServiceConnection_RecoLanguage]);\n if (!language) {\n speechConfig.setProperty(PropertyId[PropertyId.SpeechServiceConnection_RecoLanguage], ConversationConnectionConfig.defaultLanguageCode);\n }\n this.privLanguage = speechConfig.getProperty(PropertyId[PropertyId.SpeechServiceConnection_RecoLanguage]);\n\n if (!id) {\n // check the target language(s)\n if (speechConfig.targetLanguages.length === 0) {\n speechConfig.addTargetLanguage(this.privLanguage);\n }\n\n // check the profanity setting: speech and conversationTranslator should be in sync\n const profanity: string = speechConfig.getProperty(PropertyId[PropertyId.SpeechServiceResponse_ProfanityOption]);\n if (!profanity) {\n speechConfig.setProfanity(ProfanityOption.Masked);\n }\n // check the nickname: it should pass this regex: ^\\w+([\\s-][\\w\\(\\)]+)*$\"\n // TODO: specify the regex required. Nicknames must be unique or get the duplicate nickname error\n // TODO: check what the max length is and if a truncation is required or if the service handles it without an error\n let hostNickname: string = speechConfig.getProperty(PropertyId[PropertyId.ConversationTranslator_Name]);\n if (hostNickname === undefined || hostNickname === null) {\n hostNickname = \"Host\";\n }\n Contracts.throwIfNullOrTooLong(hostNickname, \"nickname\", 50);\n Contracts.throwIfNullOrTooShort(hostNickname, \"nickname\", 2);\n speechConfig.setProperty(PropertyId[PropertyId.ConversationTranslator_Name], hostNickname);\n\n } else {\n this.privConversationId = id;\n }\n\n // save the speech config for future usage\n this.privConfig = speechConfig;\n\n // save the config properties\n const configImpl = speechConfig as SpeechTranslationConfigImpl;\n Contracts.throwIfNull(configImpl, \"speechConfig\");\n this.privProperties = configImpl.properties.clone();\n this.privIsConnected = false;\n this.privParticipants = new InternalParticipants();\n this.privIsReady = false;\n this.privTextMessageMaxLength = 1000;\n }\n\n // get the internal data about a conversation\n public get room(): IInternalConversation {\n return this.privRoom;\n }\n\n // get the wrapper for connecting to the websockets\n public get connection(): ConversationRecognizer {\n return this.privConversationRecognizer; // this.privConnection;\n }\n\n // get the config\n public get config(): SpeechTranslationConfig {\n return this.privConfig;\n }\n\n // get the conversation Id\n public get conversationId(): string {\n return this.privRoom ? this.privRoom.roomId : this.privConversationId;\n }\n\n // get the properties\n public get properties(): PropertyCollection {\n return this.privProperties;\n }\n\n // get the speech language\n public get speechRecognitionLanguage(): string {\n return this.privLanguage;\n }\n\n public get isMutedByHost(): boolean {\n return this.privParticipants.me?.isHost ? false : this.privParticipants.me?.isMuted;\n }\n\n public get isConnected(): boolean {\n return this.privIsConnected && this.privIsReady;\n }\n\n public get participants(): Participant[] {\n return this.toParticipants(true);\n }\n\n public get me(): Participant {\n return this.toParticipant(this.privParticipants.me);\n }\n\n public get host(): Participant {\n return this.toParticipant(this.privParticipants.host);\n }\n\n public get transcriberRecognizer(): TranscriberRecognizer {\n return this.privTranscriberRecognizer;\n }\n\n public get conversationInfo(): ConversationInfo {\n const convId: string = this.conversationId;\n const p: TranscriptionParticipant[] = this.participants.map((part: Participant): TranscriptionParticipant => (\n {\n id: part.id,\n preferredLanguage: part.preferredLanguage,\n voice: part.voice\n }\n ));\n const props: ConversationProperties = {};\n for (const key of ConversationConnectionConfig.transcriptionEventKeys) {\n const val: string = this.properties.getProperty(key, \"\");\n if (val !== \"\") {\n props[key] = val;\n }\n }\n const info: ConversationInfo = { id: convId, participants: p, conversationProperties: props };\n return info;\n }\n\n private get canSend(): boolean {\n return this.privIsConnected && !this.privParticipants.me?.isMuted;\n }\n\n private get canSendAsHost(): boolean {\n return this.privIsConnected && this.privParticipants.me?.isHost;\n }\n\n // get / set the speech auth token\n // eslint-disable-next-line @typescript-eslint/member-ordering\n public get authorizationToken(): string {\n return this.privToken;\n }\n\n public set authorizationToken(value: string) {\n Contracts.throwIfNullOrWhitespace(value, \"authorizationToken\");\n this.privToken = value;\n }\n\n public set conversationTranslator(conversationTranslator: ConversationTranslator) {\n this.privConversationTranslator = conversationTranslator;\n }\n\n public onToken(token: IAuthentication): void {\n this.privConversationTranslator.onToken(token);\n }\n\n /**\n * Create a new conversation as Host\n * @param cb\n * @param err\n */\n public createConversationAsync(cb?: Callback, err?: Callback): void {\n try {\n if (!!this.privConversationRecognizer) {\n this.handleError(new Error(this.privErrors.permissionDeniedStart), err);\n }\n this.privManager.createOrJoin(this.privProperties, undefined,\n ((room: IInternalConversation): void => {\n if (!room) {\n this.handleError(new Error(this.privErrors.permissionDeniedConnect), err);\n }\n this.privRoom = room;\n this.handleCallback(cb, err);\n }),\n ((error: any): void => {\n this.handleError(error, err);\n }));\n } catch (error) {\n this.handleError(error, err);\n }\n }\n\n /**\n * Starts a new conversation as host.\n * @param cb\n * @param err\n */\n public startConversationAsync(cb?: Callback, err?: Callback): void {\n try {\n // check if there is already a recognizer\n if (!!this.privConversationRecognizer) {\n this.handleError(new Error(this.privErrors.permissionDeniedStart), err);\n }\n // check if there is conversation data available\n Contracts.throwIfNullOrUndefined(this.privRoom, this.privErrors.permissionDeniedConnect);\n // connect to the conversation websocket\n this.privParticipants.meId = this.privRoom.participantId;\n this.privConversationRecognizer = ConversationRecognizerFactory.fromConfig(this, this.privConfig);\n\n // Because ConversationTranslator manually sets up and manages the connection, Conversation\n // has to forward serviceRecognizer connection events that usually get passed automatically\n this.privConversationRecognizer.connected = this.onConnected;\n this.privConversationRecognizer.disconnected = this.onDisconnected;\n this.privConversationRecognizer.canceled = this.onCanceled;\n\n this.privConversationRecognizer.participantUpdateCommandReceived = this.onParticipantUpdateCommandReceived;\n this.privConversationRecognizer.lockRoomCommandReceived = this.onLockRoomCommandReceived;\n this.privConversationRecognizer.muteAllCommandReceived = this.onMuteAllCommandReceived;\n this.privConversationRecognizer.participantJoinCommandReceived = this.onParticipantJoinCommandReceived;\n this.privConversationRecognizer.participantLeaveCommandReceived = this.onParticipantLeaveCommandReceived;\n this.privConversationRecognizer.translationReceived = this.onTranslationReceived;\n this.privConversationRecognizer.participantsListReceived = this.onParticipantsListReceived;\n this.privConversationRecognizer.conversationExpiration = this.onConversationExpiration;\n\n this.privConversationRecognizer.connect(this.privRoom.token,\n ((): void => {\n this.handleCallback(cb, err);\n }),\n ((error: any): void => {\n this.handleError(error, err);\n }));\n } catch (error) {\n this.handleError(error, err);\n }\n }\n\n /**\n * Join a conversation as a participant.\n * @param { IParticipant } participant - participant to add\n * @param cb\n * @param err\n */\n public addParticipantAsync(participant: IParticipant, cb?: Callback, err?: Callback): void {\n Contracts.throwIfNullOrUndefined(participant, \"Participant\");\n marshalPromiseToCallbacks(this.addParticipantImplAsync(participant), cb, err);\n }\n\n /**\n * Join a conversation as a participant.\n * @param conversation\n * @param nickname\n * @param lang\n * @param cb\n * @param err\n */\n public joinConversationAsync(conversationId: string, nickname: string, lang: string, cb?: Callback, err?: Callback): void {\n try {\n // TODO\n // if (!!this.privConversationRecognizer) {\n // throw new Error(this.privErrors.permissionDeniedStart);\n // }\n Contracts.throwIfNullOrWhitespace(conversationId, this.privErrors.invalidArgs.replace(\"{arg}\", \"conversationId\"));\n Contracts.throwIfNullOrWhitespace(nickname, this.privErrors.invalidArgs.replace(\"{arg}\", \"nickname\"));\n Contracts.throwIfNullOrWhitespace(lang, this.privErrors.invalidArgs.replace(\"{arg}\", \"language\"));\n // join the conversation\n this.privManager.createOrJoin(this.privProperties, conversationId,\n ((room: IInternalConversation): void => {\n Contracts.throwIfNullOrUndefined(room, this.privErrors.permissionDeniedConnect);\n this.privRoom = room;\n this.privConfig.authorizationToken = room.cognitiveSpeechAuthToken;\n // join callback\n if (!!cb) {\n cb(room.cognitiveSpeechAuthToken);\n }\n }),\n ((error: any): void => {\n this.handleError(error, err);\n }));\n } catch (error) {\n this.handleError(error, err);\n }\n }\n\n /**\n * Deletes a conversation\n * @param cb\n * @param err\n */\n public deleteConversationAsync(cb?: Callback, err?: Callback): void {\n marshalPromiseToCallbacks(this.deleteConversationImplAsync(), cb, err);\n }\n\n public async deleteConversationImplAsync(): Promise<void> {\n Contracts.throwIfNullOrUndefined(this.privProperties, this.privErrors.permissionDeniedConnect);\n Contracts.throwIfNullOrWhitespace(this.privRoom.token, this.privErrors.permissionDeniedConnect);\n await this.privManager.leave(this.privProperties, this.privRoom.token);\n\n this.dispose();\n }\n\n /**\n * Issues a request to close the client websockets\n * @param cb\n * @param err\n */\n public endConversationAsync(cb?: Callback, err?: Callback): void {\n marshalPromiseToCallbacks(this.endConversationImplAsync(), cb, err);\n }\n\n public endConversationImplAsync(): Promise<void> {\n return this.close(true);\n }\n\n /**\n * Issues a request to lock the conversation\n * @param cb\n * @param err\n */\n public lockConversationAsync(cb?: Callback, err?: Callback): void {\n try {\n Contracts.throwIfDisposed(this.privIsDisposed);\n Contracts.throwIfDisposed(this.privConversationRecognizer.isDisposed());\n Contracts.throwIfNullOrUndefined(this.privRoom, this.privErrors.permissionDeniedSend);\n if (!this.canSendAsHost) {\n this.handleError(new Error(this.privErrors.permissionDeniedConversation.replace(\"{command}\", \"lock\")), err);\n }\n if (!!this.privConversationRecognizer) {\n this.privConversationRecognizer.sendRequest(this.getLockCommand(true),\n ((): void => {\n this.handleCallback(cb, err);\n }),\n ((error: any): void => {\n this.handleError(error, err);\n }));\n }\n } catch (error) {\n this.handleError(error, err);\n }\n }\n\n /**\n * Issues a request to mute the conversation\n * @param cb\n * @param err\n */\n public muteAllParticipantsAsync(cb?: Callback, err?: Callback): void {\n try {\n Contracts.throwIfDisposed(this.privIsDisposed);\n Contracts.throwIfDisposed(this.privConversationRecognizer.isDisposed());\n Contracts.throwIfNullOrUndefined(this.privConversationRecognizer, this.privErrors.permissionDeniedSend);\n Contracts.throwIfNullOrUndefined(this.privRoom, this.privErrors.permissionDeniedSend);\n // check the user's permissions\n if (!this.canSendAsHost) {\n this.handleError(new Error(this.privErrors.permissionDeniedConversation.replace(\"{command}\", \"mute\")), err);\n }\n if (!!this.privConversationRecognizer) {\n this.privConversationRecognizer.sendRequest(this.getMuteAllCommand(true),\n ((): void => {\n this.handleCallback(cb, err);\n }),\n ((error: any): void => {\n this.handleError(error, err);\n }));\n }\n } catch (error) {\n this.handleError(error, err);\n }\n }\n\n /**\n * Issues a request to mute a participant in the conversation\n * @param userId\n * @param cb\n * @param err\n */\n public muteParticipantAsync(userId: string, cb?: Callback, err?: Callback): void {\n try {\n Contracts.throwIfDisposed(this.privIsDisposed);\n Contracts.throwIfDisposed(this.privConversationRecognizer.isDisposed());\n Contracts.throwIfNullOrWhitespace(userId, this.privErrors.invalidArgs.replace(\"{arg}\", \"userId\"));\n Contracts.throwIfNullOrUndefined(this.privRoom, this.privErrors.permissionDeniedSend);\n // check the connection is open (host + participant can perform the mute command)\n if (!this.canSend) {\n this.handleError(new Error(this.privErrors.permissionDeniedSend), err);\n }\n // if not host, check the participant is not muting another participant\n if (!this.me.isHost && this.me.id !== userId) {\n this.handleError(new Error(this.privErrors.permissionDeniedParticipant.replace(\"{command}\", \"mute\")), err);\n }\n // check the user exists\n const exists: number = this.privParticipants.getParticipantIndex(userId);\n if (exists === -1) {\n this.handleError(new Error(this.privErrors.invalidParticipantRequest), err);\n }\n if (!!this.privConversationRecognizer) {\n this.privConversationRecognizer.sendRequest(this.getMuteCommand(userId, true), ((): void => {\n this.handleCallback(cb, err);\n }),\n ((error: any): void => {\n this.handleError(error, err);\n }));\n }\n } catch (error) {\n this.handleError(error, err);\n }\n }\n\n /**\n * Issues a request to remove a participant from the conversation\n * @param userId\n * @param cb\n * @param err\n */\n public removeParticipantAsync(userId: string | IParticipant | IUser, cb?: Callback, err?: Callback): void {\n try {\n Contracts.throwIfDisposed(this.privIsDisposed);\n if (!!this.privTranscriberRecognizer && userId.hasOwnProperty(\"id\")) {\n // Assume this is a transcription participant\n marshalPromiseToCallbacks(this.removeParticipantImplAsync(userId as IParticipant), cb, err);\n } else {\n Contracts.throwIfDisposed(this.privConversationRecognizer.isDisposed());\n Contracts.throwIfNullOrUndefined(this.privRoom, this.privErrors.permissionDeniedSend);\n if (!this.canSendAsHost) {\n this.handleError(new Error(this.privErrors.permissionDeniedParticipant.replace(\"{command}\", \"remove\")), err);\n }\n let participantId = \"\";\n if (typeof userId === \"string\") {\n participantId = userId;\n } else if (userId.hasOwnProperty(\"id\")) {\n const participant: IParticipant = userId as IParticipant;\n participantId = participant.id;\n } else if (userId.hasOwnProperty(\"userId\")) {\n const user: IUser = userId as IUser;\n participantId = user.userId;\n }\n Contracts.throwIfNullOrWhitespace(participantId, this.privErrors.invalidArgs.replace(\"{arg}\", \"userId\"));\n // check the participant exists\n const index: number = this.participants.findIndex((p: Participant): boolean => p.id === participantId);\n if (index === -1) {\n this.handleError(new Error(this.privErrors.invalidParticipantRequest), err);\n }\n if (!!this.privConversationRecognizer) {\n this.privConversationRecognizer.sendRequest(this.getEjectCommand(participantId), ((): void => {\n this.handleCallback(cb, err);\n }),\n ((error: any): void => {\n this.handleError(error, err);\n }));\n }\n }\n } catch (error) {\n this.handleError(error, err);\n }\n }\n\n /**\n * Issues a request to unlock the conversation\n * @param cb\n * @param err\n */\n public unlockConversationAsync(cb?: Callback, err?: Callback): void {\n try {\n Contracts.throwIfDisposed(this.privIsDisposed);\n Contracts.throwIfDisposed(this.privConversationRecognizer.isDisposed());\n Contracts.throwIfNullOrUndefined(this.privRoom, this.privErrors.permissionDeniedSend);\n if (!this.canSendAsHost) {\n this.handleError(new Error(this.privErrors.permissionDeniedConversation.replace(\"{command}\", \"unlock\")), err);\n }\n if (!!this.privConversationRecognizer) {\n this.privConversationRecognizer.sendRequest(this.getLockCommand(false), ((): void => {\n this.handleCallback(cb, err);\n }),\n ((error: any): void => {\n this.handleError(error, err);\n }));\n }\n } catch (error) {\n this.handleError(error, err);\n }\n }\n\n /**\n * Issues a request to unmute all participants in the conversation\n * @param cb\n * @param err\n */\n public unmuteAllParticipantsAsync(cb?: Callback, err?: Callback): void {\n try {\n Contracts.throwIfDisposed(this.privIsDisposed);\n Contracts.throwIfDisposed(this.privConversationRecognizer.isDisposed());\n Contracts.throwIfNullOrUndefined(this.privRoom, this.privErrors.permissionDeniedSend);\n if (!this.canSendAsHost) {\n this.handleError(new Error(this.privErrors.permissionDeniedConversation.replace(\"{command}\", \"unmute all\")), err);\n }\n if (!!this.privConversationRecognizer) {\n this.privConversationRecognizer.sendRequest(this.getMuteAllCommand(false), ((): void => {\n this.handleCallback(cb, err);\n }),\n ((error: any): void => {\n this.handleError(error, err);\n }));\n }\n } catch (error) {\n this.handleError(error, err);\n }\n }\n\n /**\n * Issues a request to unmute a participant in the conversation\n * @param userId\n * @param cb\n * @param err\n */\n public unmuteParticipantAsync(userId: string, cb?: Callback, err?: Callback): void {\n try {\n Contracts.throwIfDisposed(this.privIsDisposed);\n Contracts.throwIfDisposed(this.privConversationRecognizer.isDisposed());\n Contracts.throwIfNullOrWhitespace(userId, this.privErrors.invalidArgs.replace(\"{arg}\", \"userId\"));\n Contracts.throwIfNullOrUndefined(this.privRoom, this.privErrors.permissionDeniedSend);\n // check the connection is open (host + participant can perform the mute command)\n if (!this.canSend) {\n this.handleError(new Error(this.privErrors.permissionDeniedSend), err);\n }\n // if not host, check the participant is not muting another participant\n if (!this.me.isHost && this.me.id !== userId) {\n this.handleError(new Error(this.privErrors.permissionDeniedParticipant.replace(\"{command}\", \"mute\")), err);\n }\n // check the user exists\n const exists: number = this.privParticipants.getParticipantIndex(userId);\n if (exists === -1) {\n this.handleError(new Error(this.privErrors.invalidParticipantRequest), err);\n }\n if (!!this.privConversationRecognizer) {\n this.privConversationRecognizer.sendRequest(this.getMuteCommand(userId, false), ((): void => {\n this.handleCallback(cb, err);\n }),\n ((error: any): void => {\n this.handleError(error, err);\n }));\n }\n } catch (error) {\n this.handleError(error, err);\n }\n }\n\n /**\n * Send a text message\n * @param message\n * @param cb\n * @param err\n */\n public sendTextMessageAsync(message: string, cb?: Callback, err?: Callback): void {\n try {\n Contracts.throwIfDisposed(this.privIsDisposed);\n Contracts.throwIfDisposed(this.privConversationRecognizer.isDisposed());\n Contracts.throwIfNullOrWhitespace(message, this.privErrors.invalidArgs.replace(\"{arg}\", \"message\"));\n Contracts.throwIfNullOrUndefined(this.privRoom, this.privErrors.permissionDeniedSend);\n if (!this.canSend) {\n this.handleError(new Error(this.privErrors.permissionDeniedSend), err);\n }\n // TODO: is a max length check required?\n if (message.length > this.privTextMessageMaxLength) {\n this.handleError(new Error(this.privErrors.invalidArgs.replace(\"{arg}\", \"message length\")), err);\n }\n if (!!this.privConversationRecognizer) {\n this.privConversationRecognizer.sendRequest(this.getMessageCommand(message), ((): void => {\n this.handleCallback(cb, err);\n }),\n ((error: any): void => {\n this.handleError(error, err);\n }));\n }\n } catch (error) {\n this.handleError(error, err);\n }\n }\n\n /**\n * Set translated to languages\n * @param {string[]} languages - languages to translate to\n * @param cb\n * @param err\n */\n public setTranslatedLanguagesAsync(languages: string[], cb?: Callback, err?: Callback): void {\n try {\n Contracts.throwIfDisposed(this.privIsDisposed);\n Contracts.throwIfDisposed(this.privConversationRecognizer.isDisposed());\n Contracts.throwIfArrayEmptyOrWhitespace(languages, this.privErrors.invalidArgs.replace(\"{arg}\", \"languages\"));\n Contracts.throwIfNullOrUndefined(this.privRoom, this.privErrors.permissionDeniedSend);\n if (!this.canSend) {\n this.handleError(new Error(this.privErrors.permissionDeniedSend), err);\n }\n if (!!this.privConversationRecognizer) {\n this.privConversationRecognizer.sendRequest(this.getSetTranslateToLanguagesCommand(languages),\n ((): void => {\n this.handleCallback(cb, err);\n }),\n ((error: any): void => {\n this.handleError(error, err);\n }));\n }\n } catch (error) {\n this.handleError(error, err);\n }\n }\n\n /**\n * Change nickname\n * @param {string} nickname - new nickname for the room\n * @param cb\n * @param err\n */\n public changeNicknameAsync(nickname: string, cb?: Callback, err?: Callback): void {\n try {\n Contracts.throwIfDisposed(this.privIsDisposed);\n Contracts.throwIfDisposed(this.privConversationRecognizer.isDisposed());\n Contracts.throwIfNullOrWhitespace(nickname, this.privErrors.invalidArgs.replace(\"{arg}\", \"nickname\"));\n Contracts.throwIfNullOrUndefined(this.privRoom, this.privErrors.permissionDeniedSend);\n if (!this.canSend) {\n this.handleError(new Error(this.privErrors.permissionDeniedSend), err);\n }\n if (!!this.privConversationRecognizer) {\n this.privConversationRecognizer.sendRequest(this.getChangeNicknameCommand(nickname),\n ((): void => {\n this.handleCallback(cb, err);\n }),\n ((error: any): void => {\n this.handleError(error, err);\n }));\n }\n } catch (error) {\n this.handleError(error, err);\n }\n }\n\n public isDisposed(): boolean {\n return this.privIsDisposed;\n }\n\n public dispose(): void {\n if (this.isDisposed) {\n return;\n }\n this.privIsDisposed = true;\n if (!!this.config) {\n this.config.close();\n }\n this.privConfig = undefined;\n this.privLanguage = undefined;\n this.privProperties = undefined;\n this.privRoom = undefined;\n this.privToken = undefined;\n this.privManager = undefined;\n this.privIsConnected = false;\n this.privIsReady = false;\n this.privParticipants = undefined;\n }\n\n public async connectTranscriberRecognizer(recognizer: TranscriberRecognizer): Promise<void> {\n if (!!this.privTranscriberRecognizer) {\n await this.privTranscriberRecognizer.close();\n }\n await recognizer.enforceAudioGating();\n this.privTranscriberRecognizer = recognizer;\n this.privTranscriberRecognizer.conversation = this;\n }\n\n public getKeepAlive(): string {\n const nickname: string = (!!this.me) ? this.me.displayName : \"default_nickname\";\n return JSON.stringify({\n id: \"0\",\n nickname,\n participantId: this.privRoom.participantId,\n roomId: this.privRoom.roomId,\n type: ConversationTranslatorMessageTypes.keepAlive\n });\n }\n\n /** websocket callbacks */\n /* eslint-disable @typescript-eslint/typedef */\n private onConnected = (e: ConnectionEventArgs): void => {\n this.privIsConnected = true;\n try {\n if (!!this.privConversationTranslator?.sessionStarted) {\n this.privConversationTranslator.sessionStarted(this.privConversationTranslator, e);\n }\n } catch (e) {\n //\n }\n };\n\n private onDisconnected = (e: ConnectionEventArgs): void => {\n try {\n if (!!this.privConversationTranslator?.sessionStopped) {\n this.privConversationTranslator.sessionStopped(this.privConversationTranslator, e);\n }\n } catch (e) {\n //\n } finally {\n void this.close(false);\n }\n };\n\n private onCanceled = (r: ConversationRecognizer, e: ConversationTranslationCanceledEventArgs): void => {\n try {\n if (!!this.privConversationTranslator?.canceled) {\n this.privConversationTranslator.canceled(this.privConversationTranslator, e);\n }\n } catch (e) {\n //\n }\n };\n\n private onParticipantUpdateCommandReceived = (r: ConversationRecognizer, e: ParticipantAttributeEventArgs): void => {\n try {\n const updatedParticipant: IInternalParticipant = this.privParticipants.getParticipant(e.id);\n if (updatedParticipant !== undefined) {\n\n switch (e.key) {\n case ConversationTranslatorCommandTypes.changeNickname:\n updatedParticipant.displayName = e.value as string;\n break;\n case ConversationTranslatorCommandTypes.setUseTTS:\n updatedParticipant.isUsingTts = e.value as boolean;\n break;\n case ConversationTranslatorCommandTypes.setProfanityFiltering:\n updatedParticipant.profanity = e.value as boolean;\n break;\n case ConversationTranslatorCommandTypes.setMute:\n updatedParticipant.isMuted = e.value as boolean;\n break;\n case ConversationTranslatorCommandTypes.setTranslateToLanguages:\n updatedParticipant.translateToLanguages = e.value as string[];\n break;\n }\n this.privParticipants.addOrUpdateParticipant(updatedParticipant);\n\n if (!!this.privConversationTranslator) {\n this.privConversationTranslator.participantsChanged(\n this.privConversationTranslator,\n new ConversationParticipantsChangedEventArgs(ParticipantChangedReason.Updated,\n [this.toParticipant(updatedParticipant)], e.sessionId));\n }\n }\n } catch (e) {\n //\n }\n };\n\n private onLockRoomCommandReceived = (): void => {\n // TODO\n };\n\n private onMuteAllCommandReceived = (r: ConversationRecognizer, e: MuteAllEventArgs): void => {\n try {\n this.privParticipants.participants.forEach((p: IInternalParticipant): boolean => p.isMuted = (p.isHost ? false : e.isMuted));\n if (!!this.privConversationTranslator) {\n this.privConversationTranslator.participantsChanged(\n this.privConversationTranslator,\n new ConversationParticipantsChangedEventArgs(ParticipantChangedReason.Updated,\n this.toParticipants(false), e.sessionId));\n }\n } catch (e) {\n //\n }\n };\n\n private onParticipantJoinCommandReceived = (r: ConversationRecognizer, e: ParticipantEventArgs): void => {\n try {\n const newParticipant: IInternalParticipant = this.privParticipants.addOrUpdateParticipant(e.participant);\n if (newParticipant !== undefined) {\n if (!!this.privConversationTranslator) {\n this.privConversationTranslator.participantsChanged(\n this.privConversationTranslator,\n new ConversationParticipantsChangedEventArgs(ParticipantChangedReason.JoinedConversation,\n [this.toParticipant(newParticipant)], e.sessionId));\n }\n }\n } catch (e) {\n //\n }\n };\n\n private onParticipantLeaveCommandReceived = (r: ConversationRecognizer, e: ParticipantEventArgs): void => {\n try {\n const ejectedParticipant: IInternalParticipant = this.privParticipants.getParticipant(e.participant.id);\n if (ejectedParticipant !== undefined) {\n // remove the participant from the internal participants list\n this.privParticipants.deleteParticipant(e.participant.id);\n if (!!this.privConversationTranslator) {\n // notify subscribers that the participant has left the conversation\n this.privConversationTranslator.participantsChanged(\n this.privConversationTranslator,\n new ConversationParticipantsChangedEventArgs(ParticipantChangedReason.LeftConversation,\n [this.toParticipant(ejectedParticipant)], e.sessionId));\n }\n }\n } catch (e) {\n //\n }\n };\n\n private onTranslationReceived = (r: ConversationRecognizer, e: ConversationReceivedTranslationEventArgs): void => {\n try {\n switch (e.command) {\n case ConversationTranslatorMessageTypes.final:\n if (!!this.privConversationTranslator) {\n this.privConversationTranslator.transcribed(\n this.privConversationTranslator,\n new ConversationTranslationEventArgs(e.payload, undefined, e.sessionId));\n }\n break;\n case ConversationTranslatorMessageTypes.partial:\n if (!!this.privConversationTranslator) {\n this.privConversationTranslator.transcribing(\n this.privConversationTranslator,\n new ConversationTranslationEventArgs(e.payload, undefined, e.sessionId));\n }\n break;\n case ConversationTranslatorMessageTypes.instantMessage:\n if (!!this.privConversationTranslator) {\n this.privConversationTranslator.textMessageReceived(\n this.privConversationTranslator,\n new ConversationTranslationEventArgs(e.payload, undefined, e.sessionId));\n }\n break;\n }\n } catch (e) {\n //\n }\n };\n\n private onParticipantsListReceived = (r: ConversationRecognizer, e: ParticipantsListEventArgs): void => {\n try {\n // check if the session token needs to be updated\n if (e.sessionToken !== undefined && e.sessionToken !== null) {\n this.privRoom.token = e.sessionToken;\n }\n // save the participants\n this.privParticipants.participants = [...e.participants];\n // enable the conversation\n if (this.privParticipants.me !== undefined) {\n this.privIsReady = true;\n }\n if (!!this.privConversationTranslator) {\n this.privConversationTranslator.participantsChanged(\n this.privConversationTranslator,\n new ConversationParticipantsChangedEventArgs(ParticipantChangedReason.JoinedConversation, this.toParticipants(true), e.sessionId));\n }\n // if this is the host, update the nickname if needed\n if (this.me.isHost) {\n const nickname: string = this.privConversationTranslator?.properties.getProperty(PropertyId.ConversationTranslator_Name);\n if (nickname !== undefined && nickname.length > 0 && nickname !== this.me.dis