/** * Core application class for the SDK. * Application is the parent object holding the list of conversations, the session object. * Provides methods to create conversations and retrieve a list of the user's conversations, while it holds the listeners for * user's invitations * @class Application * @param {NexmoClient} SDK session Object * @param {object} params * @example Accessing the list of conversations * rtc.createSession(token).then((application) => { * console.log(application.conversations); * console.log(application.me.name, application.me.id); * }).catch((error) => { * console.error(error); * }); * @emits Application#member:invited * @emits Application#member:joined * @emits Application#NXM-errors * @emits Application#rtcstats:analytics */ export class Application { log: Logger; session: any; conversations: Map; synced_conversations_count: number; start_sync_time: number; stop_sync_time: number; calls: Map; _call_draft_list: Map; pageConfig: PageConfig; conversations_page_last: ConversationsPage | null; user_sessions_page_last: UserSessionsPage | null; me: User; synced_conversations_percentage: number; sync_progress_buffer: number; activeStreams: MediaStream[]; eventsQueue: EventsQueue; emit: any; on: any; off: any; once: any; /** * Enum for Application getConversation version. * @readonly * @enum {string} * @alias Application.CONVERSATION_API_VERSION */ static CONVERSATION_API_VERSION: { v1: string; v3: string; }; constructor(session: any, params?: Object); /** * Update Conversation instance or create a new one. * * Pre-created conversation exist from getConversations * like initialised templates. When we explicitly ask to * getConversation(), we receive members and other details * * @param {object} payload Conversation payload * @private */ updateOrCreateConversation(payload: any): Conversation; /** * Application listening for member invited events. * * @event Application#member:invited * * @property {Member} member - The invited member * @property {NXMEvent} event - The invitation event * * @example listen for member invited events on Application level * application.on("member:invited",(member, event) => { * console.log("Invited to the conversation: " + event.conversation.display_name || event.conversation.name); * // identify the sender. * console.log("Invited by: " + member.invited_by); * //accept an invitation. * application.conversations.get(event.conversation.id).join(); * //decline the invitation. * application.conversations.get(event.conversation.id).leave(); * }); */ /** * Application listening for member joined events. * * @event Application#member:joined * * @property {Member} member - the member that joined the conversation * @property {NXMEvent} event - the join event * * @example listen for member joined events on Application level * application.on("member:joined",(member, event) => { * console.log("JOINED", "Joined conversation: " + event.conversation.display_name || event.conversation.name); * }); */ /** * Entry point for queing events in Application level * @private */ _enqueueEvent(response: CAPIResponse): Promise; /** * Entry point for events in Application level * @private */ _handleEvent(event: CAPIResponse): Promise; /** * Update user's token that was generated when they were first authenticated. * @param {string} token - the new token * @returns {Promise} * @example listen for expired-token error events and then update the token on Application level * application.on('system:error:expired-token', 'NXM-errors', (error) => { * console.log('token expired'); * application.updateToken(token); * }); */ updateToken(token: string): Promise; /** * Update the event to map local generated events * in case we need a more specific event to pass in the application listener * or f/w the event as it comes * @private */ _handleApplicationEvent(event: CAPIResponse): Promise; /** * Creates a call to specified user/s. * @classdesc creates a call between the defined users * @param {string[]} usernames - the user names for those we want to call * @returns {Promise} a NXMCall object with all the call properties * @example Create a call with users * application.on("call:status:changed", (nxmCall) => { * if (nxmCall.status === nxmCall.CALL_STATUS.STARTED) { * console.log('the call has started'); * } * }); * * application.inAppCall(usernames).then(() => { * console.log('Calling user(s)...'); * }).catch((error) => { * console.error(error); * }); */ inAppCall(usernames: string[]): Promise; /** * Creates a call to phone a number. * The call object is created under application.calls when the call has started. * listen for it with application.on("call:status:changed") * * You don't need to start the stream, the SDK will play the audio for you * * @classdesc creates a call to a phone number * @param {string} user the phone number or the username you want to call * @param {string} [type="phone"] the type of the call you want to have. possible values "phone" or "app" ( is "phone") * @param {object} [custom_data] custom data to be included in the call object, i.e. { yourCustomKey: yourCustomValue } * @returns {Promise} * @example Create a call to a phone * application.on("call:status:changed", (nxmCall) => { * if (nxmCall.status === nxmCall.CALL_STATUS.STARTED) { * console.log('the call has started'); * } * }); * * application.callServer(phone_number).then((nxmCall) => { * console.log('Calling phone ' + phone_number); * console.log('Call Object ': nxmCall); * }).catch((error) => { * console.error(error); * }); */ callServer(user: string, type?: string, custom_data?: Object): Promise; /** * Reconnect a leg to an ongoing call. * You don't need to start the stream, the SDK will play the audio for you * * @classdesc reconnect leg to an ongoing call * @param {string} conversation_id the conversation that you want to reconnect * @param {string} rtc_id the id of the leg that will be reconnected * @param {object} [mediaParams] - MediaStream params (same as Media.enable()) * @returns {Promise} * @example Reconnect a leg to an ongoing call * application.reconnectCall("conversation_id", "rtc_id").then((nxmCall) => { * console.log(nxmCall); * }).catch((error) => { * console.error(error); * }); * * @example Reconnect a leg to an ongoing call without auto playing audio * application.reconnectCall("conversation_id", "rtc_id", { autoPlayAudio: false }).then((nxmCall) => { * console.log(nxmCall); * }).catch((error) => { * console.error(error); * }); * * @example Reconnect a leg to an ongoing call choosing device ID * application.reconnectCall("conversation_id", "rtc_id", { audioConstraints: { deviceId: "device_id" } }).then((nxmCall) => { * console.log(nxmCall); * }).catch((error) => { * console.error(error); * }); */ reconnectCall(conversationId: string, rtcId: string, mediaParams?: Object): Promise; /** * Query the service to create a new conversation * The conversation name must be unique per application. * @param {object} [params] - leave empty to get a GUID as name * @param {string} params.name - the name of the conversation. A UID will be assigned if this is skipped * @param {string} params.display_name - the display_name of the conversation. * @returns {Promise} - the created Conversation * @example Create a conversation and join * application.newConversation().then((conversation) => { * //join the created conversation * conversation.join().then((member) => { * //Get the user's member belonging in this conversation. * //You can also access it via conversation.me * console.log("Joined as " + member.user.name); * }); * }).catch((error) => { * console.error(error); * }); */ newConversation(data?: { name?: string; display_name?: string; }): Promise; /** * Query the service to create a new conversation and join it * The conversation name must be unique per application. * @param {object} [params] - leave empty to get a GUID as name * @param {string} params.name - the name of the conversation. A UID will be assigned if this is skipped * @param {string} params.display_name - the display_name of the conversation. * @returns {Promise} - the created Conversation * @example Create a conversation and join * application.newConversationAndJoin().then((conversation) => { * console.log("Joined as " + conversation.me.display_name); * }).catch((error) => { * console.error("Error creating a conversation and joining ", error); * }); */ newConversationAndJoin(params?: Object): Promise; /** * Query the service to see if this conversation exists with the * logged in user as a member and retrieve the data object * Result added (or updated) in this.conversations * * @param {string} id - the id of the conversation to fetch * @param {string} version=Application.CONVERSATION_API_VERSION.v3 {Application.CONVERSATION_API_VERSION.v1 || Application.CONVERSATION_API_VERSION.v3} - the version of the Conversation Service API to use (v1 includes the full list of the members of the conversation but v3 does not) * @returns {Promise} - the requested conversation * @example Get a conversation * application.getConversation(id).then((conversation) => { * console.log("Retrieved conversation: ", conversation); * }).catch((error) => { * console.error(error); * }); */ getConversation(id: string, version?: string): Promise; /** * Query the service to obtain a complete list of conversations of which the * logged-in user is a member with a state of `JOINED` or `INVITED`. * @param {object} params configure s for paginated conversations query * @param {string} params.order 'asc' or 'desc' ordering of resources based on creation time * @param {number} params.page_size the number of resources returned in a single request list * @param {string} [params.cursor] string to access the starting point of a dataset * * @returns {Promise>>} - Populate Application.conversations. * @example Get Conversations * application.getConversations({ page_size: 20 }).then((conversations_page) => { * conversations_page.items.forEach(conversation => { * render(conversation) * }) * }).catch((error) => { * console.error(error); * }); * */ getConversations(params?: Object): Promise; /** * Application listening for sync status events. * * @event Application#sync:progress * * @property {number} status.sync_progress - Percentage of fetched conversations * @example listen for changes in the synchronisation progress events on Application level * application.on("sync:progress",(status) => { * console.log(status.sync_progress); * }); */ /** * Fetching all the conversations and sync progress events */ syncConversations(conversations: Conversation[]): void; /** * Get Details of a user by using their id. If no id is present, will return your own user details. * @param {string} id - the id of the user to fetch, if skipped, it returns your own user details * @returns {Promise} * @example Get User details * application.getUser(id).then((user) => { * console.log('User details: 'user); * }).catch((error) => { * console.error(error); * }); */ getUser(user_id?: string): Promise; /** * Query the service to obtain a complete list of userSessions of a given user * @param {object} params configure s for paginated user sessions query * @param {string} params.order 'asc' or 'desc' ordering of resources based on creation time * @param {number} params.page_size the number of resources returned in a single request list * @param {string} [params.cursor] string to access the starting point of a dataset * @param {string} [params.user_id] the user id that the sessions are being fetched * * @returns {Promise>>} * @example Get User Sessions * application.getUserSessions({ user_id: "id", page_size: 20 }).then((user_sessions_page) => { * user_sessions_page.items.forEach(user_session => { * render(user_session) * }) * }).catch((error) => { * console.error(error); * }); * */ getUserSessions(params?: Object): Promise; } /** * A single conversation Object. * @class Conversation * @property {Member} me - my Member object that belongs to this conversation * @property {Application} application - the parent Application * @property {string} name - the name of the Conversation (unique) * @property {string} [display_name] - the display_name of the Conversation * @property {Map} [members] - the members of the Conversation keyed by a member's id * @property {Map} [events] - the events of the Conversation keyed by an event's id * @property {number} [sequence_number] - the last event id */ export class Conversation { log: Logger; application: Application; id: string; name: string; display_name: string; timestamp: Object; members?: Map; events: Map; sequence_number: number; pageConfig: PageConfig; events_page_last: EventsPage; members_page_last: MembersPage; conversationEventHandler: ConversationEventHandler; media: Media; me: Member; emit: any; on: any; off: any; once: any; releaseGroup: any; constructor(application: Application, params?: Object); /** Update Conversation object params * @property {object} params the params to update * @private */ _updateObjectInstance(params: { id?: string; name?: string; display_name?: string; members?: Member[]; timestamp?: Object; sequence_number?: number; member_id?: string; state?: string; }): void; /** * Join the given User to this Conversation. Will typically be used this to join * ourselves to a Conversation we create. * Accept an invitation if our Member has state INVITED and no user_id / user_name is given * * @param {object} [params = this.application.me.id] The User to join (s to this) * @param {string} params.user_name the user_name of the User to join * @param {string} params.user_id the user_id of the User to join * @returns {Promise} * * @example join a user to the Conversation * * conversation.join().then((member) => { * console.log("joined as member: ", member) * }).catch((error) => { * console.error("error joining conversation ", error); * }); */ join(params?: { user_name?: string; user_id?: string; }): Promise; /** * Delete a conversation * @returns {Promise} * @example delete the Conversation * * conversation.del().then(() => { * console.log("conversation deleted"); * }).catch((error) => { * console.error("error deleting conversation ", error); * }); */ del(): Promise; /** * Delete an NXMEvent (e.g. Text) * @param {NXMEvent} event * @returns {Promise} * @example delete an Event * * conversation.deleteEvent(eventToBeDeleted).then(() => { * console.log("event was deleted"); * }).catch((error) => { * console.error("error deleting the event ", error); * }); * */ deleteEvent(event: NXMEvent): Promise; /** * Invite the given user (id or name) to this conversation * @param {Member} params * @param {string} [params.id or user_name] - the id or the username of the User to invite * * @returns {Promise} * * @example invite a user to a Conversation * const user_id = 'id of User to invite'; * const user_name = 'username of User to invite'; * * conversation.invite({ * id: user_id, * user_name: user_name * }).then((member) => { * displayMessage(member.state + " user: " + user_id + " " + user_name); * }).catch((error) => { * console.error("error inviting user ", error); * }); * */ invite(params?: InviteParams): Promise; /** * Invite the given user (id or name) to this conversation with media audio * @param {Member} params * @param {string} [params.id or user_name] - the id or the username of the User to invite * * @returns {Promise} * * @example invite a user to a conversation * const user_id = 'id of User to invite'; * const user_name = 'username of User to invite'; * * conversation.inviteWithAudio({ * id: user_id, * user_name: user_name * }).then((member) => { * displayMessage(member.state + " user: " + user_id + " " + user_name); * }).catch((error) => { * console.error("error inviting user ", error); * }); * */ inviteWithAudio(params?: InviteParams): Promise; /** * Leave from the Conversation * @param {object} [reason] the reason for leaving the conversation * @param {string} [reason.reason_code] the code of the reason * @param {string} [reason.reason_text] the description of the reason * @returns {Promise} * @example leave the Conversation * * conversation.leave({reason_code: "mycode", reason_text: "my reason for leaving"}).then(() => { * console.log("successfully left conversation"); * }).catch((error) => { * console.error("error leaving conversation ", error); * }); * */ leave(reason?: { reason_code?: string; reason_text?: string; }): Promise; /** * Send a text message to the conversation, which will be relayed to every other member of the conversation * @param {string} text - the text message to be sent * * @returns {Promise} - the text message that was sent * * @example sending a text * conversation.sendText("Hi Vonage").then((event) => { * console.log("message was sent", event); * }).catch((error)=>{ * console.error("error sending the message ", error); * }); * * @deprecated since version 8.3.0 * */ sendText(text: string): Promise; /** * Send a custom event to the Conversation * @param {object} params - params of the custom event * @param {string} params.type the name of the custom event. Must not exceed 100 char length and contain only alpha numerics and '-' and '_' characters. * @param {object} params.body customizable key value pairs * * @returns {Promise} - the custom event that was sent * * @example sending a custom event * conversation.sendCustomEvent({ type: "my-event", body: { mykey: "my value" }}).then((event) => { * console.log("custom event was sent", event); * }).catch((error)=>{ * console.error("error sending the custom event", error); * }); * */ sendCustomEvent({ type, body }: { type: string; body: Object; }): Promise; /** * Send an ephemeral event to the Conversation * @param {object} body - customizable key value pairs * * @returns {Promise} - the ephemeral event that was sent * * @example sending an ephemeral event * conversation.sendEphemeralEvent({ mykey: "my value" }).then((event) => { * console.log("ephemeral event was sent", event); * }).catch((error)=>{ * console.error("error sending the ephemeral event", error); * }); * */ sendEphemeralEvent(body: Object): Promise; /** * Uploads an Image to Media Service. * implements xhr (https://xhr.spec.whatwg.org/) - this.imageRequest * * @param {File} file single input file (jpeg/jpg) * @param {object} params - params of image sent * @param {string} [params.quality_ratio = 100] a value between 0 and 100. 0 indicates 'maximum compression' and the lowest quality, 100 will result in the highest quality image * @param {string} [params.medium_size_ratio = 50] a value between 1 and 100. 1 indicates the new image is 1% of original, 100 - same size as original * @param {string} [params.thumbnail_size_ratio = 30] a value between 1 and 100. 1 indicates the new image is 1% of original, 100 - same size as original * * @returns {Promise} * * @example uploading an image * const params = { * quality_ratio : "90", * medium_size_ratio: "40", * thumbnail_size_ratio: "20" * } * conversation.uploadImage(fileInput.files[0], params).then((uploadImageRequest) => { * uploadImageRequest.onprogress = (e) => { * console.log("Image request progress: ", e); * console.log("Image progress: " + e.loaded + "/" + e.total); * }; * uploadImageRequest.onabort = (e) => { * console.log("Image request aborted: ", e); * console.log("Image: " + e.type); * }; * uploadImageRequest.onloadend = (e) => { * console.log("Image request successful: ", e); * console.log("Image: " + e.type); * }; * uploadImageRequest.onreadystatechange = () => { * if (uploadImageRequest.readyState === 4 && uploadImageRequest.status === 200) { * const representations = JSON.parse(uploadImageRequest.responseText); * console.log("Original image url: ", representations.original.url); * console.log("Medium image url: ", representations.medium.url); * console.log("Thumbnail image url: ", representations.thumbnail.url); * } * }; * }).catch((error) => { * console.error("error uploading the image ", error); * }); */ uploadImage(fileInput: File, params?: { quality_ratio: string; medium_size_ratio: string; thumbnail_size_ratio: string; }): Promise; /** * Send an Image message to the conversation, which will be relayed to every other member of the conversation. * implements xhr (https://xhr.spec.whatwg.org/) - this.imageRequest * * @param {File} file single input file (jpeg/jpg) * @param {object} params - params of image sent * @param {string} [params.quality_ratio = 100] a value between 0 and 100. 0 indicates 'maximum compression' and the lowest quality, 100 will result in the highest quality image * @param {string} [params.medium_size_ratio = 50] a value between 1 and 100. 1 indicates the new image is 1% of original, 100 - same size as original * @param {string} [params.thumbnail_size_ratio = 30] a value between 1 and 100. 1 indicates the new image is 1% of original, 100 - same size as original * * @returns {Promise} * * @example sending an image * const params = { * quality_ratio : "90", * medium_size_ratio: "40", * thumbnail_size_ratio: "20" * } * conversation.sendImage(fileInput.files[0], params).then((imageRequest) => { * imageRequest.onprogress = (e) => { * console.log("Image request progress: ", e); * console.log("Image progress: " + e.loaded + "/" + e.total); * }; * imageRequest.onabort = (e) => { * console.log("Image request aborted: ", e); * console.log("Image: " + e.type); * }; * imageRequest.onloadend = (e) => { * console.log("Image request successful: ", e); * console.log("Image: " + e.type); * }; * }).catch((error) => { * console.error("error sending the image ", error); * }); * * @deprecated since version 8.3.0 */ sendImage(fileInput: File, params?: { quality_ratio: string; medium_size_ratio: string; thumbnail_size_ratio: string; }): Promise; /** * Cancel uploading or sending an Image message to the conversation. * * @param {XMLHttpRequest} imageRequest * * @returns void * * @example cancel sending an image * conversation.sendImage(fileInput.files[0]).then((imageRequest) => { * conversation.abortSendImage(imageRequest); * }).catch((error) => { * console.error("error sending the image ", error); * }); * * @example cancel uploading an image * conversation.uploadImage(fileInput.files[0]).then((imageRequest) => { * conversation.abortSendImage(imageRequest); * }).catch((error) => { * console.error("error uploading the image ", error); * }); */ abortSendImage(imageRequest: XMLHttpRequest): void | NexmoClientError; /** * Send a message event to the conversation, which will be relayed to every other member of the conversation * * @param {object} params the content of the message you want sent * @param {string} params.message_type the type of the message. It should be one of 'text', 'image', 'audio', 'video', 'file' * @param {string} [params.text] the text content when message type is 'text * @param {object} [params.image] * @param {string} params.image.url the image url when message type is 'image' * @param {object} [params.audio] * @param {string} params.audio.url the audio url when message type is 'audio' * @param {object} [params.video] * @param {string} params.video.url the video url when message type is 'video' * @param {object} [params.file] * @param {string} params.file.url the file url when message type is 'file' * * @returns {Promise} - the message that was sent * * @example sending a message * conversation.sendMessage({ "message_type": "text", "text": "Hi Vonage!" }).then((event) => { * console.log("message was sent", event); * }).catch((error)=>{ * console.error("error sending the message ", error); * }); * */ sendMessage(params: MessageEventParams): Promise; _typing(state: string): Promise; /** * Send start typing indication * * @returns {Promise} - resolves the promise on successful sent * * @example send start typing event when key is pressed * messageTextarea.addEventListener('keypress', (event) => { * conversation.startTyping(); * }); */ startTyping(): Promise; /** * Send stop typing indication * * @returns {Promise} - resolves the promise on successful sent * * @example send stop typing event when a key has not been pressed for half a second * let timeout = null; * messageTextarea.addEventListener('keyup', (event) => { * clearTimeout(timeout); * timeout = setTimeout(() => { * conversation.stopTyping(); * }, 500); * }); */ stopTyping(): Promise; /** * Query the service to get a list of events in this conversation. * * @param {object} params configure s for paginated events query * @param {string} params.order 'asc' or 'desc' ordering of resources based on creation time * @param {number} params.page_size the number of resources returned in a single request list * @param {string} [params.cursor] string to access the starting point of a dataset * @param {string} [params.event_type] the type of event used to filter event requests. Supports wildcard options with :* eg. 'members:*' * * @returns {Promise>>} - Populate Conversations.events. * @example Get Events * conversation.getEvents({ event_type: 'member:*' }).then((events_page) => { * events_page.items.forEach(event => { * render(event) * }) * }).catch((error) => { * console.error("error getting the events ", error); * }); */ getEvents(params?: Object): Promise; /** * Query the service to get a list of members in this conversation. * * @param {object} params configure s for paginated events query * @param {string} params.order 'asc' or 'desc' ordering of resources based on creation time * @param {number} params.page_size the number of resources returned in a single request list * @param {string} [params.cursor] string to access the starting point of a dataset * * @returns {Promise>>} * @example Get Members * const params = { * order: "desc", * page_size: 100 * } * conversation.getMembers(params).then((members_page) => { * members_page.items.forEach(member => { * render(member) * }) * }).catch((error) => { * console.error("error getting the members ", error); * }); */ getMembers(params?: Object): Promise; /** * Query the service to get my member in this conversation. * * @returns {Promise} * @example Get My Member * conversation.getMyMember().then((member) => { * render(member) * }).catch((error) => { * console.error("error getting my member", error); * }); */ getMyMember(): Promise; /** * Query the service to get a member in this conversation. * * @param {string} member_id the id of the member to return * * @returns {Promise} * @example Get Member * conversation.getMember("MEM-id").then((member) => { * render(member) * }).catch((error) => { * console.error("error getting member", error); * }); */ getMember(member_id: string): Promise; /** * Handle and event from the cloud. * using conversationEventHandler * @param {object} event * @private */ _handleEvent(event: CAPIResponse): Promise; } /** * An image event * * @class ImageEvent * @extends NXMEvent */ export class ImageEvent extends NXMEvent { log: Logger; constructor(conversation: Conversation, params?: { body?: { timestamp?: string; representations?: ImageRepresentations; }; }); /** * Set the imageEvent status to 'seen' * @returns {Promise} * @example Set the imageEvent status to 'seen' * imageEvent.seen().then(() => { * console.log("image event status set to seen"); * }).catch((error)=>{ * console.log("error setting image event status to seen ", error); * }); */ seen(): Promise; /** * Set the imageEvent status to 'delivered' * @returns {Promise} * @example Set the imageEvent status to 'delivered' * imageEvent.delivered().then(() => { * console.log("image event status set to delivered"); * }).catch((error)=>{ * console.log("error setting image event status to delivered ", error); * }); */ delivered(): Promise; /** * Delete the image event, all 3 representations of it * passing only the one of the three URLs * @returns {Promise} * @example Delete the imageEvent * imageEvent.del().then(() => { * console.log("image event deleted"); * }).catch((error)=>{ * console.log("error deleting image event ", error); * }); */ del(): Promise; /** * Download an Image from Media service //3 representations * @param {string} [type="thumbnail"] original, medium, or thumbnail * @param {string} [representations=this.body.representations] the ImageEvent.body for the image to download * @returns {string} the dataUrl "data:image/jpeg;base64..." * @example Downloading an image from the imageEvent * imageEvent.fetchImage("medium").then((imageData) => { * const img = new Image(); * img.src = imageData; * document.body.appendChild(img); * }).catch((error)=>{ * console.log("error getting image ", error); * }); */ fetchImage(type?: string, imageRepresentations?: ImageRepresentations): Promise; } /** * A message event * * @class MessageEvent * @extends NXMEvent */ export class MessageEvent extends NXMEvent { log: Logger; constructor(conversation: Conversation, params?: { body?: { timestamp?: string; }; }); /** * Set the messageEvent status to 'seen' * @returns {Promise} * @example Set the messageEvent status to 'seen' * messageEvent.seen().then(() => { * console.log("message event status set to seen"); * }).catch((error)=>{ * console.log("error setting message event status to seen ", error); * }); */ seen(): Promise; /** * Set the messageEvent status to 'delivered'. * handled by the SDK * @returns {Promise} * @example Set the messageEvent status to 'delivered' * messageEvent.delivered().then(() => { * console.log("message event status set to delivered"); * }).catch((error)=>{ * console.log("error setting message event status to delivered ", error); * }); */ delivered(): Promise; /** * Delete the messageEvent * @returns {Promise} * @example Delete the messageEvent * messageEvent.del().then(() => { * console.log("message event deleted"); * }).catch((error)=>{ * console.log("error deleting message event ", error); * }); */ del(): Promise; /** * Download an Image from Media service * @returns {string} the dataUrl "data:image/jpeg;base64..." * @example Downloading an image from the messageEvent * messageEvent.fetchImage().then((imageData) => { * const img = new Image(); * img.src = imageData; * document.body.appendChild(img); * }).catch((error) => { * console.log("error getting image ", error); * }); */ fetchImage(): Promise; } /** * Conversation NXMEvent Object. * The super class that holds the base events that apply to * common event objects. * @class NXMEvent */ export class NXMEvent { conversation: Conversation; type: string; cid: string; from: string; timestamp: Object; id: string; state: { delivered_to?: { [key: string]: string; }; seen_by?: { [key: string]: string; }; submitted_to?: { [key: string]: string; }; rejected_by?: { [key: string]: string; }; undeliverable_to?: { [key: string]: string; }; }; index: number; streamIndex: number; body?: { user?: { user_id?: string; display_name?: string; id?: string; media?: { audio_settings?: { enabled?: boolean; }; }; }; member_id?: string; sdp?: string; digit?: number; digits?: number; representations?: any; timestamp?: Object; text?: string; channel?: Channel; invited_by?: string | null; message_type?: string; image?: { url: string; }; audio?: { url: string; }; video?: { url: string; }; file?: { url: string; }; }; digit: number; application_id: string; constructor(conversation: Conversation, params?: { type?: string; application_id?: string; cid?: string; from?: string; timestamp?: string; id?: string; state?: { delivered_to?: { [key: string]: string; }; seen_by?: { [key: string]: string; }; submitted_to?: { [key: string]: string; }; rejected_by?: { [key: string]: string; }; undeliverable_to?: { [key: string]: string; }; }; index?: number; streamIndex?: number; body?: Object; _embedded?: { from_user?: { display_name?: string; id?: string; name?: string; }; from_member?: { display_name?: string; id?: string; name?: string; }; }; }); /** * Delete the event * @param {number} [event_id=this.event_id] if the event id param is not present, "this" event will be * @returns {Promise} * @private */ del(event_id?: string): Promise; /** * Mark as Delivered the event * @param {number} [event_id=this.event_id] if the event id is not provided, the this event will be used * @returns {Promise} * @private */ delivered(event_id?: string): Promise; /** * Mark as Seen the event * @param {number} [event_id=this.event_id] if the event id is not provided, the this event will be used * @returns {Promise} * @private */ seen(event_id?: string): Promise; } /** * A text event * * @class TextEvent * @extends NXMEvent */ export class TextEvent extends NXMEvent { constructor(conversation: Conversation, params?: { body?: { timestamp?: string; }; }); /** * Set the textEvent status to 'seen' * @returns {Promise} * @example Set the textEvent status to 'seen' * textEvent.seen().then(() => { * console.log("text event status set to seen"); * }).catch((error)=>{ * console.log("error setting text event status to seen ", error); * }); */ seen(): Promise; /** * Set the textEvent status to 'delivered'. * handled by the SDK * @returns {Promise} * @example Set the textEvent status to 'delivered' * textEvent.delivered().then(() => { * console.log("text event status set to delivered"); * }).catch((error)=>{ * console.log("error setting text event status to delivered ", error); * }); */ delivered(): Promise; /** * Delete the textEvent * @returns {Promise} * @example Delete the textEvent * textEvent.del().then(() => { * console.log("text event deleted"); * }).catch((error)=>{ * console.log("error deleting text event ", error); * }); */ del(): Promise; } /** * Handle Application Events * * @class ApplicationEventsHandler * @param {Application} application * @param {Conversation} conversation * @private */ export class ApplicationEventsHandler { log: Logger; application: Application; _handleApplicationEventMap: { [key: string]: Function; }; constructor(application: Application); /** * Handle and event. * * Update the event to map local generated events * in case we need a more specific event to pass in the application listener * or f/w the event as it comes * @param {object} event * @private */ handleEvent(event: CAPIResponse): any; /** * case: call to PSTN, after knocking event we receive joined * @private */ private _processMemberJoined; private _processMemberInvited; } /** * Handle Conversation Events * * @class ConversationEventsHandler * @param {Application} application * @param {Conversation} conversation * @private */ export class ConversationEventHandler { log: Logger; application: Application; conversation: Conversation; constructed_event: NXMEvent; _handleEventMap: { [key: string]: Function; }; constructor(application: Application, conversation: Conversation); /** * Handle and event. * * Identify the type of the event, * create the corresponding Class instance * emit to the corresponding Objects * @param {object} event * @private */ handleEvent(event: CAPIResponse): NXMEvent; /** * Mark the requested event as delivered * use that event as constructed to update the local events' map * @param {object} event * @returns the NXMEvent that is marked as delivered * @private */ private _processDelivered; /** * Delete the requested event * empty the payload of the event (text, image or message) * use that event as constructed to update the local events map * @param {object} event * @returns the deleted events * @private */ private _processDelete; /** * Return an ImageEvent with the corresponding image data * @param {object} event * @returns {ImageEvent} */ private _processImage; /** * Handle events for member state changes (joined, invited, left) * in conversation level. * Other members are going through here too. * For .me member initial event (join, invite) use the application listener * @param {object} event * @returns {NXMEvent} * @private */ private _processMember; /** * Handle events for leg status updates in conversation level. * Other member's legs are going through here too. * @param {object} event * @returns {NXMEvent} * @private */ private _processLegStatus; /** * Handle member:media events * use a call object if and the member object * @param {object} event * @private */ private _processMedia; /** * Handle *:mute:* events * @param {object} event * @private */ private _processMuteForMedia; /** * Mark the requested event as seen * use that event as constructed to update the local Events map * @param {object} event * @private */ private _processSeen; /** * Create the TextEvent object and trigger .delivered() * @param {object} event * @private */ private _processText; /** * Create the MessageEvent object and trigger .delivered() * @param {object} event * @private */ private _processMessage; /** * Mark the requested event as submitted * use that event as constructed to update the local Events map * @param {object} event * @private */ private _processSubmitted; /** * Mark the requested event as rejected * use that event as constructed to update the local Events map * @param {object} event * @private */ private _processRejected; /** * Mark the requested event as undeliverable * use that event as constructed to update the local Events map * @param {object} event * @private */ private _processUndeliverable; } /** * Handle Mapping of Conversation Ids to ConversationEventsProcessor * * @class EventsQueue * @private */ export declare class EventsQueue { callback: any; cidMap: Map; log: Logger; constructor(callback: any); enqueue(event: CAPIResponse, application: Application): Promise; } /** * Handle Ordering of Conversation Events for Processing * * @class ConversationEventsProcessor * @private */ export declare class ConversationEventsProcessor { cid: string; eventsMap: Map; lastEventIdProcessed: number; largestEventIdInQueue: number; callback: any; processing: Boolean; application: Application; eventsFetchRange: number; eventRequestWaitTime: number; log: Logger; constructor(cid: string, lastEventIdProcessed: number, application: Application); enqueue(eventId: number, event: CAPIResponse): CAPIResponse; dequeue(eventId: number): CAPIResponse; processEvents(): Promise; processNextEvent(eventId: number, retry: number): Promise; fetchEventsAndProcess(missingEvent: number): Promise; fetchConversationEvents(start_id: number, range: number): Promise>; } /** * Handle rtc Events * * @class RtcEventHandler * @private */ export class RtcEventHandler { log: Logger; application: Application; _handleRtcEventMap: { [key: string]: Function; }; constructor(application: Application); /** * Entry point for rtc events * @param {object} event * @private */ _handleRtcEvent(event: CAPIResponse): void; /** * on transfer event * update the conversation object in the NXMCall, * update the media object in the new conversation * set `transferred_to` on the member that is transferred * @param {object} event * @private */ private _processRtcTransfer; /** * Handle rtc:answer event * * @param {object} event * @private */ private _processRtcAnswer; /** * Handle rtc:hangup event * * @param {object} event * @private */ private _processRtcHangup; } /** * Handle sip Events * * @class SipEventHandler * @private */ export class SipEventHandler { log: Logger; application: Application; _handleSipCallEventMap: { [key: string]: Function; }; constructor(application: Application); /** * Entry point for sip events * The event belongs to a call Object * @private */ _handleSipCallEvent(event: CAPIResponse): any; /** * Handle sip:hangup event * * @param {object} event_call * @private */ private _processSipHangup; /** * Handle sip:ringing event * * @param {object} event_call * @private */ private _processSipRinging; } /** * An individual user (i.e. conversation member). * @class Member * @param {Conversation} conversation * @param {object} params */ export class Member { conversation: Conversation; callStatus: string | null; id: string; user?: any; channel: any; timestamp: { invited?: string; joined?: string; left?: string; }; state: string; display_name: string; invited_by: string; user_id: string; name: string; media?: Media; stream?: MediaStream; pc?: RTCPeerConnection; emit: any; on: any; off: any; once: any; transferred_to?: Conversation; transferred_from?: Conversation; [key: string]: any; constructor(conversation: Conversation, params?: Object); /** * Update object instance and align attribute names * * Handle params input to keep consistent the member object * @param {object} params member attributes * @private */ _normalise(params?: any): void; /** * Play the given stream only to this member within the conversation * * @param {string} [params] * * @returns {Promise} * @private */ playStream(params: Object): Promise; /** * Speak the given text only to this member within the Conversation. * * @param {string} [params] * * @returns {Promise} * @private */ sayText(params: { text: string; voice_name?: string; level?: number; queue?: boolean; loop?: number; ssml?: boolean; }): Promise; /** * Kick a Member from the Conversation. * * @param {object} [reason] the reason for kicking out a member * @param {string} [reason.reason_code] the code of the reason * @param {string} [reason.reason_text] the description of the reason * @example Remove a member from the Conversation. * // Remove a member * member.kick({reason_code: "Reason Code", reason_text: "Reason Text"}) * .then(() => { * console.log("Successfully removed member."); * }).catch((error) => { * console.error("Error removing member: ", error); * }); * * // Remove yourself * conversation.me.kick({reason_code: "Reason Code", reason_text: "Reason Text"}) * .then(() => { * console.log("Successfully removed yourself."); * }).catch((error) => { * console.error("Error removing yourself: ", error); * }); * * @returns {Promise} */ kick(reason?: { [key: string]: string; }): Promise; /** * Mute your stream. * * @param {boolean} [mute] true for mute, false for unmute * @param {number} [streamIndex] stream index of the stream * @example Mute audio stream of your Member. * // Mute yourself * conversation.me.mute(true); * * // Unmute yourself * conversation.me.mute(false); * * @returns {Promise} */ mute(mute: boolean, streamIndex?: number): Promise; /** * Earmuff yourself in the Conversation. * * @param {boolean} earmuff true or false * @example Disables your Member from hearing other Members in the Conversation. * // Earmuff yourself * conversation.me.earmuff(true); * * // Unearmuff yourself * conversation.me.earmuff(false); * * @returns {Promise} * */ earmuff(earmuff: boolean): Promise; /** * Handle member object events * * Handle events that are modifying this member instance * @param {NXMEvent} event invited, joined, left, media events * @private */ _handleEvent(event: CAPIResponse): void; /** * Set the member.callStatus and emit a member:call:status event * * @param {Member.callStatus} this.callStatus the call status to set * @private */ private _setCallStatusAndEmit; } /** * Class that can emit errors via any emitter passed to it. * @class ErrorsEmitter * @param {Emitter} emitter - Any event emitter that implements "emit" and "releaseGroup". Basically object that is mixed with Wildemitter. * @property {string} LISTENER_GROUP='NXM-errors' - the group this emitter will register * @emits Emitter#NXM-errors * @private */ /** * Application listening for client and expired-token errors events. * * @event Application#NXM-errors * * @property {NexmoClientError} error * * @example listen for client error events on Application level * application.on('*', 'NXM-errors', (error) => { * console.log('Error thrown with type ' + error.type); * }); * @example listen for expired-token error events and then update the token on Application level * application.on('system:error:expired-token', 'NXM-errors', (error) => { * console.log('token expired'); * application.updateToken(token); * }); */ export class ErrorsEmitter { log: Logger; emitter: any; LISTENER_GROUP: string; constructor(emitter: any); /** * Detect if the param.type includes error and emit that payload in the LISTENER_GROUP * @param param - the payload to forward in the LISTENER_GROUP * @param param.type - the type of the event to check if it's an error */ emitResponseIfError(param: { type: string; }): null; /** * Release Group on the registered emitter (using the namespace LISTENER_GROUP that is set) */ cleanup(): any; /** * Returns true if the param includes 'error' * @param {string} type - the error type to check */ _isTypeError(param: { indexOf: (arg0: string) => number; }): boolean; } /** * Member listening for audio stream on. * * @event Member#media:stream:on * * @property {number} payload.streamIndex the index number of this stream * @property {number} [payload.rtc_id] the rtc_id / leg_id * @property {string} [payload.remote_member_id] the id of the Member the stream belongs to * @property {string} [payload.name] the stream's display name * @property {MediaStream} payload.stream the stream that is activated * @property {boolean} [payload.audio_mute] if the audio is muted */ /** * WebRTC Media class * @class Media * @property {Application} application The parent application object * @property {Conversation} parentConversation the conversation object this media instance belongs to * @property {number} parentConversation.streamIndex the latest index of the streams, updated in each new peer offer * @property {object[]} rtcObjects data related to the rtc connection * @property {string} rtcObjects.rtc_id the rtc_id * @property {PeerConnection} rtcObjects.pc the current PeerConnection object * @property {Stream} rtcObjects.stream the stream of the specific rtc_id * @property {string} [rtcObjects.type] audio the type of the stream * @property {number} rtcObjects.streamIndex the index number of the stream (e.g. use to mute) * @property {RTCStatsConfig} rtcstats_conf the config needed to controll rtcstats analytics behavior * @property {RTCStatsAnalytics} rtcstats an instance to collect analytics from a peer connection * @emits Application#rtcstats:report * @emits Application#rtcstats:analytics * @emits Member#media:stream:on */ export class Media { log: Logger; rtcHelper: RtcHelper; application: Application; parentConversation: Conversation; rtcObjects: { [key: string]: { rtc_id: string; pc: RTCPeerConnection; stream: MediaStream; type: string; streamIndex: number; }; }; streamIndex: number; rtcstats_conf: RTCStatsConfig; rtcStats: RTCStatsAnalytics; pc: RTCPeerConnection; listeningToRtcEvent: boolean; me: Member; constructor(); constructor(conversation: Conversation); constructor(application: Application); _attachEndingEventHandlers(): void; /** * Switch on the rtc stats emit events * @private */ _enableStatsEvents(): void; /** * Switch off the rtcStat events * @private */ _disableStatsEvents(): void; /** * Function used to init the media stream * @private */ private _audioInitHandler; /** * Handles the enabling of audio when an offer is available * @private */ private _execAnswer; /** * Handles the enabling of audio only stream with rtc:new * @private */ private _handleAudio; private _findRtcObjectByType; private _cleanConversationProperties; /** * Cleans up the user's media before leaving the conversation * @private */ private _cleanMediaProperties; private _disableLeg; _enableMediaTracks(tracks: MediaStreamTrack[], enabled: boolean): void; /** * Send a mute request with the rtc_id and enable/disable the tracks * If the mute request fails revert the changes in the tracks * @private */ private _setMediaTracksAndMute; /** * Replaces the stream's audio tracks currently being used as the sender's sources with a new one * @param {object} constraints - audio constraints - { deviceId: { exact: selectedAudioDeviceId } } * @param {string} type - rtc object type - audio * @returns {Promise} - Returns the new stream. * @example Update the stream currently being used with a new audio source * conversation.media.updateAudioConstraints({ deviceId: { exact: selectedAudioDeviceId } }, "audio") * .then((response) => { * console.log(response); * }).catch((error) => { * console.error(error); * }); * * */ updateAudioConstraints(constraints?: Object): Promise; /** * Mute your Member * * @param {boolean} [mute=false] true for mute, false for unmute * @param {number} [streamIndex] stream id to set - if it's not set all streams will be muted * @example Mute your audio stream in the Conversation * // Mute your Member * conversation.media.mute(true); * * // Unmute your Member * conversation.media.mute(false); */ mute(mute?: boolean, streamIndex?: number): Promise; /** * Earmuff our member * * @param {boolean} [params] * * @returns {Promise} * @private */ earmuff(earmuff: boolean): Promise; /** * Enable media participation in the conversation for this application (requires WebRTC) * @param {object} [params] - rtc params * @param {string} [params.label] - label is an application defined tag, eg. ‘fullscreen’ * @param {string} [params.reconnectRtcId] - the rtc_id / leg_id of the call to reconnect to * @param {object} [params.audio=true] - audio enablement mode. possible values "both", "send_only", "receive_only", "none", true or false * @param {object} [params.autoPlayAudio=false] - attach the audio stream automatically to start playing after enable media ( false) * @param {object} [params.audioConstraints] - audio constraints to use * @param {boolean} [params.audioConstraints.autoGainControl] - a boolean which specifies whether automatic gain control is preferred and/or required * @param {boolean} [params.audioConstraints.echoCancellation] - a boolean specifying whether or not echo cancellation is preferred and/or required * @param {boolean} [params.audioConstraints.noiseSuppression] - a boolean which specifies whether noise suppression is preferred and/or required * @param {string | Array} [params.audioConstraints.deviceId] - object specifying a device ID or an array of device IDs which are acceptable and/or required * @returns {Promise} * @example Enable media in the Conversation * * conversation.media.enable() * .then((stream) => { * const media = document.createElement("audio"); * const source = document.createElement("source"); * const media_div = document.createElement("div"); * media.appendChild(source); * media_div.appendChild(media); * document.insertBefore(media_div); * // Older browsers may not have srcObject * if ("srcObject" in media) { * media.srcObject = stream; * } else { * // Avoid using this in new browsers, as it is going away. * media.src = window.URL.createObjectURL(stream); * } * media.onloadedmetadata = (e) => { * media.play(); * }; * }).catch((error) => { * console.error(error); * }); * **/ enable(params?: { label?: string; audio?: { muted?: boolean; earmuffed?: boolean; enabled?: boolean; }; offer?: { sdp: string; leg_id: string; }; autoPlayAudio?: boolean; audioConstraints?: { autoGainControl?: boolean; echoCancellation?: boolean; noiseSuppression?: boolean; deviceId?: string | Array; }; reconnectRtcId?: string; }): Promise; /** * Disable media participation in the conversation for this application * if RtcStats MOS is enabled, a final report will be available in * NexmoClient#rtcstats:report * @returns {Promise} * @example Disable media in the Conversation * * conversation.media.disable() * .then((response) => { * console.log(response); * }).catch((error) => { * console.error(error); * }); * **/ disable(): Promise<(string | void)[]>; /** * Play a voice text in the Conversation * @param {object} params * @param {string} params.text - The text to say in the Conversation. * @param {string} [params.voice_name="Amy"] - Name of the voice to use for speech to text. * @param {number} [params.level=1] - Set the audio level of the audio stream: min=-1 max=1 increment=0.1. * @param {boolean} [params.queue=true] - ? * @param {boolean} [params.loop=1] - The number of times to repeat audio. Set to 0 to loop infinitely. * @param {boolean} [params.ssml=false] - Customize the spoken text with Speech Synthesis Markup Language (SSML) specification * * @returns {Promise} * @example Play speech to text in the Conversation * conversation.media.sayText({text:"hi"}) * .then((response) => { * console.log(response); * }) * .catch((error) => { * console.error(error); * }); * **/ sayText(params: { text: string; voice_name?: string; level?: number; queue?: boolean; loop?: number; ssml?: boolean; }): Promise; /** * Send DTMF in the Conversation * @param {string} digit - the DTMF digit(s) to send * * @returns {Promise} * @example Send DTMF in the Conversation * conversation.media.sendDTMF("digit"); * .then((response) => { * console.log(response); * }) * .catch((error) => { * console.error(error); * }); **/ sendDTMF(digit: string): Promise; /** * Play an audio stream in the Conversation * @param {object} params * @param {number} params.level - Set the audio level of the audio stream: min=-1 max=1 increment=0.1. * @param {array} params.stream_url - Link to the audio file. * @param {number} params.loop - The number of times to repeat audio. Set to 0 to loop infinitely. * * @returns {Promise} * @example Play an audio stream in the Conversation * conversation.media.playStream({ level: 0.5, stream_url: ["https://nexmo-community.github.io/ncco-examples/assets/voice_api_audio_streaming.mp3"], loop: 1 }) * .then((response) => { * console.log("response: ", response); * }) * .catch((error) => { * console.error("error: ", error); * }); * */ playStream(params: Object): Promise; /** * Send start ringing event * @returns {Promise} * @example Send start ringing event in the Conversation * * conversation.media.startRinging() * .then((response) => { * console.log(response); * }).catch((error) => { * console.error(error); * }); * * // Listen for start ringing event * conversation.on('audio:ringing:start', (data) => { * console.log("ringing started: ", data); * }); * */ startRinging(): Promise; /** * Send stop ringing event * @returns {Promise} * @example Send stop ringing event in the Conversation * * conversation.media.stopRinging() * .then((response) => { * console.log(response); * }).catch((error) => { * console.error(error); * }); * * // Listen for stop ringing event * conversation.on('audio:ringing:stop', (data) => { * console.log("ringing stopped: ", data); * }); * */ stopRinging(): Promise; } /** * Conversation NXMCall Object. * @class NXMCall * @param {Application} application - The Application object. * @param {Conversation} conversation - The Conversation object that belongs to this nxmCall. * @param {Member} from - The member that initiated the nxmCall. * @property {Application} application - The Application object that the nxmCall belongs to. * @property {Conversation} conversation - The Conversation object that belongs to this nxmCall. * @property {Member} from - The caller. The member object of the caller (not a reference to the one in conversation.members) * @property {Map} to - The callees keyed by a member's id. The members that receive the nxmCall (not a reference to conversation.members) * @property {String} id - The nxmCall id (our member's leg_id, comes from rtc:answer event, or member:media) * @property {NXMCall.CALL_STATUS} CALL_STATUS="started" - the available nxmCall statuses * @property {NXMCall.CALL_DIRECTION} direction - the Direction of the nxmCall, Outbound, Inbound * @property {NXMCall.STATUS_PERMITTED_FLOW} STATUS_PERMITTED_FLOW - the permitted nxmCall status transition map, describes the "from" and allowed "to" transitions * @property {object[]} rtcObjects data related to the rtc connection * @property {string} rtcObjects.rtc_id the rtc_id * @property {PeerConnection} rtcObjects.pc the current PeerConnection object * @property {Stream} rtcObjects.stream the stream of the specific rtc_id * @property {string} [rtcObjects.type] audio the type of the stream * @property {number} rtcObjects.streamIndex the index number of the stream (e.g. use to mute) * @property {Stream} stream the remote stream * @emits Application#member:call * @emits Application#call:status:changed */ /** * Application listening for member call events. * * @event Application#member:call * * @property {Member} member - the member that initiated the nxmCall * @property {NXMCall} nxmCall - resolves the nxmCall object * * @example listen for member call events on Application level * application.on("member:call", (member, nxmCall) => { * console.log("NXMCall ", nxmCall); * }); */ /** * Application listening for nxmCall status changed events. * * @event Application#call:status:changed * @property {NXMCall} nxmCall - the actual event * @example listen for nxmCall status changed events on Application level * application.on("call:status:changed",(nxmCall) => { * console.log("call: " + nxmCall.status); * }); */ export class NXMCall { application: Application; log: Logger; from: Member | any; conversation: Conversation; status: string; direction: string; to: Map; id: string; successful_invited_members: Map; client_ref: string; knocking_id: string; CALL_STATUS: { [key: string]: string; }; CALL_DIRECTION: { [key: string]: string; }; STATUS_PERMITTED_FLOW: Map>; _handleStatusChangeMap: Map; transferred?: boolean; stream: MediaStream; rtcStats: RTCStatsAnalytics; rtcObjects?: { [key: string]: { rtc_id: string; pc: RTCPeerConnection; stream: MediaStream; type: string; streamIndex: number; }; }; private offer; call_disconnect_timeout: any; constructor(application: Application, conversation?: Conversation, from?: string | Member); /** * Enable NXMCall stats to be emitted in * - application.inAppCall.on('rtcstats:report') * - application.inAppCall.on('rtcstats:analytics') * @private */ _enableStatsEvents(): void; /** * Attach member event listeners from the conversation * @private */ private _attachCallListeners; /** * Validate the current nxmCall status transition * If a transition is not defined, return false * @param {string} status the status to validate * @returns {boolean} false if the transition is not permitted * @private */ private _isValidStatusTransition; /** * Go through the members of the conversation and if .me is the only one (JOINED or INVITED) * nxmCall nxmCall.hangUp(). * @returns {Promise} - empty promise or the nxmCall.hangUp promise chain */ hangUpIfAllLeft(): Promise; /** * Set the conversation object of the NXMCall * update nxmCall.from, and nxmCall.to attributes based on the conversation members * @private */ _setupConversationObject(conversation: Conversation, rtc_id?: string): void; /** * Set the from object of the NXMCall * @private */ _setFrom(from: Member): void; /** * Set the from object of the NXMCall * @private */ _setOffer(offer: { sdp: string; leg_id: string; }): void; /** * Process raw events to figure out the nxmCall status * @private */ _handleStatusChange(event: NXMEvent | CAPIResponse): any; /** * Set the nxmCall.status and emit a call:status:changed event * * @param {NXMCall.CALL_STATUS} this.CALL_STATUS the canxmCallll status to set * @emits Application#call:status:changed * @private */ private _setStatusAndEmit; /** * Answers an incoming nxmCall * Join the conversation that you are invited * Create autoplay Audio object * * @param {boolean} [autoPlayAudio=true] attach the audio stream automatically to start playing ( true) * @returns {Promise