/**
* 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}
*/
answer(autoPlayAudio?: boolean): Promise;
/**
* Trigger the nxmCall flow for the input users.
* Create a conversation with prefix name "CALL_"
* and invite all the users.
* If at least one user is successfully invited, enable the audio.
*
* @param {string[]} usernames the usernames of the users to call
* @param {boolean} [autoPlayAudio=true] attach the audio stream automatically to start playing ( true)
* @returns {Promise[]} an array of the invite promises for the provided usernames
* @private
*/
createCall(usernames: string[], autoPlayAudio?: boolean): Promise[]>;
/**
* Trigger the nxmCall flow for the phone call.
* Create a knocking event
*
* @param {string} user the phone number or the username to call
* @param {string} type the type of the call you want to have. possible values "phone" or "app" ( is "phone")
* @returns {Promise}
* @private
*/
createServerCall(user: string, type?: string, custom_data?: Object): Promise;
/**
* Hangs up the nxmCall
*
* If there is a knocking active, do a knocking:delete
* otherwise
* Leave from the conversation
* Disable the audio
*
* @param {object} [reason] the reason for hanging up the nxmCall
* @param {string} [reason.reason_code] the code of the reason
* @param {string} [reason.reason_text] the description of the reason
* @returns {Promise}
*/
hangUp(reason?: {
[key: string]: string;
}): Promise;
/**
* Rejects an incoming nxmCall
* Leave from the conversation that you are invited
*
* @param {object} [reason] the reason for rejecting the nxmCall
* @param {string} [reason.reason_code] the code of the reason
* @param {string} [reason.reason_text] the description of the reason
* @returns {Promise}
*/
reject(reason?: {
[key: string]: string;
}): Promise;
}
export class PublicIp {
static v4: (options?: PublicIpOptions) => Promise;
static v6: (options?: PublicIpOptions) => Promise;
}
/**
* RTC helper object for accessing webRTC API.
* @class RtcHelper
* @private
*/
export class RtcHelper {
log: Logger;
constructor();
static getUserAudio(audioConstraints?: Object | boolean): Promise;
createRTCPeerConnection(config: Object): RTCPeerConnection;
_getWindowLocationProtocol(): string;
static _getBrowserName(): string;
static isNode(): boolean;
/**
* Check if the keys in an object are found in another object
*/
checkValidKeys(object: Object, Object: Object): boolean;
static cleanCallMediaIfFailed(call: NXMCall): void;
static callDisconnectHandler(call: NXMCall, pc: RTCPeerConnection): ReturnType;
static cleanMediaProperties(call: NXMCall): void;
static cleanConversationMediaProperties(pc: RTCPeerConnection, localStream: MediaStream): void;
static playAudioStream(stream: MediaStream): HTMLAudioElement;
static createDummyCandidateSDP(pc: RTCPeerConnection): string;
static createRTCPeerConnectionConfig(application: any): Object;
static setupPeerConnectionApplicationListeners(application: Application, pc: RTCPeerConnection): void;
static createPeerConnection(application: Application): RTCPeerConnection;
static sendOffer(application: Application, pc: RTCPeerConnection, conversation: Conversation, reconnectRtcId?: String): Promise<{
rtc_id: string;
}>;
static sendAnswer(application: Application, pc: RTCPeerConnection, conversation: Conversation, leg_id: String): Promise<{
rtc_id: string;
}>;
static createLeg(application: Application, pc: RTCPeerConnection): PostLegResponse;
static closeStream(stream: MediaStream): void;
static emitMediaStream(member: Member, pc: RTCPeerConnection, stream: MediaStream): void;
static _initStatsEvents(context: {
application: Application;
conversation?: Conversation;
pc: RTCPeerConnection;
rtc_id: string;
}): RTCStatsAnalytics;
static attachConversationEventHandlers(context: MediaHandlerContext): void;
static onconnectionstatechangeHandler: (pc: RTCPeerConnection, log: Logger, nxmCall: NXMCall, resolveCallback: any, rejectCallback: any) => void;
static oniceconnectionstatechange: (connection_event: RTCPeerConnectionIceEvent, pc: RTCPeerConnection, log: Logger, rejectCallback: any) => void;
static onnegotiationneededHandler: (pc: RTCPeerConnection, rejectCallback: any) => Promise;
static doAnswer(context: MediaHandlerContext, offer: string, leg_id: string): void;
static attachPeerConnectionEventHandlers(context: MediaHandlerContext): void;
private static addPeerConnectionListeners;
static prewarmLeg(nxmCall: NXMCall): Promise;
}
/**
* Collect WebRTC Report data
* Removes credential information from the STUN.TURN server configuration.
* performs Delta compression
*
* if isCallback is true the report includes a MOS score : trace('mos', mos, report);
*
* @param {object} context
* @param {Application} context.application
* @param {Conversation} context.conversation
* @param {RTCPeerConnection} context.pc peer connection object
* @param {string} context.rtc_id id of a leg
* @param {RTCStatsConfig} context.config config settings for ananlytics
* @property {MosReport} mos_report the final mos report to be sent when the stream is closed
* @property {number} _reportsCount the number of reports taken for mos average
* @property {number} _mosSum the summary of mos scores
* @private
*/
export class RTCStatsAnalytics {
mos_report: any;
_reportsCount: number;
_mosSum: number;
intervals: ReturnType[];
_deprecationWarningSent: Boolean;
conversation: Conversation;
application_id: string;
constructor(context: RTCStatsAnalyticsParams);
attachHandlers(context: RTCStatsAnalyticsParams): void;
emitLastReport(context: RTCStatsAnalyticsParams): void;
startSendingStats(context: RTCStatsAnalyticsParams): void;
startEmittingStats(context: RTCStatsAnalyticsParams): void;
removeIntervals(): void;
getMos(stats: RTCStatsReport): string;
/**
* Update the mos_report object
* @param {number} mos the MOS score
* @returns {object} the report object
*/
updateMOSReport(mos: number): void;
/**
* Update the MOS report object
* mos_report.min - the minimum MOS value during the stream
* mos_report.max - the maximum MOS value during the stream
* mos_report.last - the last MOS value during the stream
* mos_report.average - the average MOS value during the stream
* @returns {MosReport} mos_report - a report for the MOS values
*
*/
getMOSReport(): MosReport;
static normaliseFloat(value: any): string;
}
/**
* Error constructor of an NexmoClient-error
* @param {string} errorInput String client error
*/
export declare class NexmoClientError {
message: string;
stack: any;
name: string;
log: Logger;
constructor(errorInput: any);
}
/**
* Error constructor of an API-error
* @param {object} error API error, always containing {type: }
*/
export declare class NexmoApiError {
message: string;
stack: any;
name: string;
log: Logger;
constructor(errorInput: any);
}
/**
* A Conversations Page
*
* @class ConversationsPage
* @param {Map} items map of conversations fetched in the paginated query
* @extends Page
*/
export class ConversationsPage extends Page {
items: Map;
constructor(params: {
items: Object[];
});
/**
* Fetch the previous page if exists
* @returns {Promise}
* @example Fetch the previous page if exists
* currentConvPage.getPrev().then((prevConvPage) => {
* console.log("previous conversation page ", prevConvPage);
* }).catch((error) => {
* console.error("error getting previous conversation page ", error);
* });
*/
getPrev(): Promise | Promise;
/**
* Fetch the next page if exists
* @returns {Promise}
* @example Fetch the next page if exists
* currentConvPage.getNext().then((nextConvPage) => {
* console.log("next conversation page ", nextConvPage);
* }).catch((error) => {
* console.error("error getting next conversation page ", error);
* });
*/
getNext(): Promise | Promise;
}
/**
* A Events Page
*
* @class EventsPage
* @param {Map} items map of events fetched in the paginated query
* @extends Page
*/
export class EventsPage extends Page {
items: Map;
conversation: Conversation;
constructor(params: {
items: Object[];
conversation: Conversation;
});
/**
* Fetch the previous page if exists
* @returns {Promise}
* @example Fetch the previous page if exists
* currentEventsPage.getPrev().then((prevEventsPage) => {
* console.log("previous events page ", prevEventsPage);
* }).catch((error) => {
* console.error("error getting previous events page ", error);
* });
*/
getPrev(): Promise | Promise;
/**
* Fetch the next page if exists
* @returns {Promise}
* @example Fetch the next page if exists
* currentEventsPage.getNext().then((nextEventsPage) => {
* console.log("next events page ", nextEventsPage);
* }).catch((error) => {
* console.error("error getting next events page ", error);
* });
*/
getNext(): Promise | Promise;
}
/**
* A Members Page
*
* @class MembersPage
* @param {Map} items map of members fetched in the paginated query
* @extends Page
*/
export class MembersPage extends Page {
items: Map;
conversation: Conversation;
constructor(params: {
items: Object[];
conversation: Conversation;
});
/**
* Fetch the previous page if exists
* @returns {Promise}
* @example Fetch the previous page if exists
* currentMembersPage.getPrev().then((prevMembersPage) => {
* console.log("previous members page ", prevMembersPage);
* }).catch((error) => {
* console.error("error getting previous members page ", error);
* });
*/
getPrev(): Promise | Promise;
/**
* Fetch the next page if exists
* @returns {Promise}
* @example Fetch the next page if exists
* currentMembersPage.getNext().then((nextMembersPage) => {
* console.log("next members page ", nextMembersPage);
* }).catch((error) => {
* console.error("error getting next members page ", error);
* });
*/
getNext(): Promise | Promise;
}
/** Config Class for Paginated Requests
*
* @class PageConfig
* @param {number} page_size=10 the number of resources returned in a single request list
* @param {string} order=asc the asc' or 'desc' ordering of resources (usually based on creation time)
* @param {string} cursor='' cursor parameter to access the next or previous page of a data set
* @param {string} [event_type] the type of event used to filter event requests
* @param {string} state='' the INVITED, JOINED, or LEFT state of your membership in the conversation
* @private
*/
export class PageConfig {
page_size: number;
order: string;
cursor: Object;
event_type: string;
state: string;
constructor(params?: {
page_size?: number;
order?: 'string';
cursor?: Object;
event_type?: string;
state?: string;
});
}
/** Page Class for Paginated Results
*
* @class Page
* @param {number} page_size the number of resources returned in a single request list
* @param {string} order 'asc' or 'desc' ordering of resources (usually based on creation time)
* @param {string} cursor cursor parameter to access the next or previous page of a data set
* @param {Application} application - the parent Application
* @param {string} [event_type] the type of event used to filter event requests
*
* @private
*/
export class Page {
page_size: number;
order: string;
cursor: {
prev: string;
next: string;
};
application: Application;
event_type: string;
constructor(params?: {
page_size?: number;
order?: string;
cursor?: {
prev: string;
next: string;
};
event_type?: string;
application?: Application;
conversation?: Conversation;
items?: Object[];
});
/**
* Check if previous page exists
* @returns {Boolean}
* @example Check if previous page exists
* // currentPage is the current Conversations or Events Page
* currentPage.hasPrev() // true or false
*/
hasPrev(): boolean;
/**
* Check if next page exists
* @returns {Boolean}
* @example Check if next page exists
* // currentPage is the current Conversations or Events Page
* currentPage.hasNext() // true or false
*/
hasNext(): boolean;
/**
* Create config params for paginationRequest
* @param {string} cursor cursor parameter to access the next or previous page of a data set
* @returns {Object}
* @private
*/
_getConfig(cursor: string): Object;
/**
* Create a nexmoClientError when page does not exist
* @private
*/
_getError(): Promise;
}
/**
* A UserSessions Page
*
* @class UserSessionsPage
* @param {Map} items map of UserSessions fetched in the paginated query
* @extends Page
*/
export class UserSessionsPage extends Page {
items: Map;
constructor(params: {
items: Object[];
application: Application;
});
/**
* Fetch the previous page if exists
* @returns {Promise}
* @example Fetch the previous page if exists
* currentUserSessionsPage.getPrev().then((prevUserSessionsPage) => {
* console.log("previous user sessions page ", prevUserSessionsPage);
* }).catch((error) => {
* console.error("error getting previous user sessions page ", error);
* });
*/
getPrev(): Promise | Promise;
/**
* Fetch the next page if exists
* @returns {Promise}
* @example Fetch the next page if exists
* currentUserSessionsPage.getNext().then((nextUserSessionsPage) => {
* console.log("next user sessions page ", nextUserSessionsPage);
* }).catch((error) => {
* console.error("error getting next user sessions page ", error);
* });
*/
getNext(): Promise | Promise;
}
///
/**
* The parent NexmoClient class.
*
* @class NexmoClient
*
* @param {object} params the settings to initialise the SDK
* @param {string} params.debug='silent' set mode to 'debug', 'info', 'warn', or 'error' for customized logging levels in the console
* @param {string} params.url='nexmo_ws_url' Nexmo Conversation Websocket url, default is wss://ws.nexmo.com (wss://ws-us-1.nexmo.com for WDC, wss://ws-us-2.nexmo.com for DAL, wss://ws-eu-1.nexmo.com for LON, wss://ws-sg-1.nexmo.com for SNG)
* @param {string} params.nexmo_api_url=Nexmo Conversation Api url, default is https://api.nexmo.com (https://api-us-1.nexmo.com for WDC, https://api-us-2.nexmo.com for DAL, https://api-eu-1.nexmo.com for LON, https://api-sg-1.nexmo.com for SNG)
* @param {string} params.ips_url='ips_url' Nexmo IPS url for image upload, default is https://api.nexmo.com/v1/image (https://api-us-1.nexmo.com/v1/image for WDC, https://api-us-2.nexmo.com/v1/image for DAL, https://api-eu-1.nexmo.com/v1/image for LON, https://api-sg-1.nexmo.com/v1/image for SNG)
* @param {string} params.path='/v2/rtc' Nexmo Conversation Websocket url path suffix
* @param {RTCStatsConfig} params.rtcstats set reporting for stream statistics (Internal event emit)
* @param {Boolean} params.rtcstats.emit_events=false receive rtcstats:report event (deprecated)
* @param {Boolean} params.rtcstats.emit_rtc_analytics=false receive rtcstats:analytics event
* @param {number} params.rtcstats.emit_interval=1000 interval in ms for rtcstats:report and rtcstats:analytics
* @param {Boolean} params.rtcstats.remote_collection=true collect client logs internally
* @param {Boolean} params.rtcstats.remote_collection_url='gollum_url' url for collecting client logs internally
* @param {number} params.rtcstats.remote_collection_interval=5000 interval in ms to collect client logs internally
* @param {object} params.socket_io configure socket.io
* @param {Boolean} params.socket_io.forceNew=true configure socket.io forceNew attribute
* @param {Boolean} params.socket_io.autoConnect=true socket.io autoConnect attribute
* @param {Boolean} params.socket_io.reconnection=true socket.io reconnection attribute
* @param {number} params.socket_io.reconnectionAttempts=5 socket.io reconnectionAttempts attribute
* @param {string[]} params.socket_io.transports='websocket' socket.io transports protocols
* @param {string} params.sync='none' {'none' || 'lite' || 'full'} after a successful session creation, synchronise conversations, include events or nothing
* @param {string} params.environment='production' development / production environment
* @param {object[]} [params.iceServers=[]] configure iceServers for RTCPeerConnection
* @param {object} params.log_reporter configure log reports for bugsnag tool
* @param {Boolean} params.log_reporter.enabled=true
* @param {string} params.log_reporter.bugsnag_key your bugsnag api key / defaults to Nexmo api key
* @param {object} params.conversations_page_config configure paginated requests for conversations
* @param {number} params.conversations_page_config.page_size=10 the number of resources returned in a single request list
* @param {string} params.conversations_page_config.order=asc 'asc' or 'desc' ordering of resources (usually based on creation time)
* @param {string} params.conversations_page_config.cursor cursor parameter to access the next or previous page of a data set
* @param {object} params.events_page_config configure paginated requests for events
* @param {number} params.events_page_config.page_size=10 the number of resources returned in a single request list
* @param {string} params.events_page_config.order=asc 'asc' or 'desc' ordering of resources (usually based on creation time)
* @param {string} params.events_page_config.event_type the type of event used to filter event requests. Supports wildcard options with :* eg. 'members:*'
* @param {Boolean} params.enableEventsQueue=true mechanism to guarantee order of events received during a session
* @param {Boolean} params.enableInboundOffer=false configure receiving offer for faster inbound call setup
* @param {Boolean} params.acknowledgeEvents=true send acknowledgment over websocket to server for received events
* @param {string} params.token the jwt token for network requests
*
* @emits NexmoClient#disconnect
* @emits NexmoClient#error
* @emits NexmoClient#ready
* @emits NexmoClient#reconnect
* @emits NexmoClient#reconnecting
*/
export default class NexmoClient {
sessionReady: boolean;
session_id: string | null;
apiKey: string | null;
requests: {
[key: string]: {
type: string;
request?: CAPIRequest;
callback: Function;
};
};
disconnectTimestamp?: number;
application: Application;
log: Logger;
config: Configuration;
connection: SocketIOClient.Socket;
errorsEmitter: ErrorsEmitter;
emit: any;
/**
* Enum for NexmoClient disconnection reason.
* @readonly
* @enum {string}
* @alias NexmoClient.DISCONNECT_REASON
*/
static DISCONNECT_REASON: {
ClientDisconnected: string;
TokenExpired: string;
ConnectionError: string;
};
constructor(params?: Configuration);
/**
* Creates and sets the socket_io connection
*
* @private
*/
_createAndSetConnection(): SocketIOClient.Socket;
/**
* Revert any invalid params to our default
*
* @param {object} config the object to sanitize
* @private
*/
_sanitizeConfig(incomingConfig: Configuration): Configuration;
/**
* Conversation listening for text events.
*
* @event Conversation#text
*
* @property {Member} sender - The sender of the text
* @property {TextEvent} text - The text message received
* @example listen for text events
* conversation.on("text",(sender, message) => {
* console.log(sender, message);
* // Identify your own message.
* if (message.from === conversation.me.id){
* renderMyMessages(message)
* } else {
* renderOtherMessages(message)
* }
* });
*/
/**
*
* Conversation listening for image events.
*
* @event Conversation#image
*
* @property {Member} sender - The sender of the image
* @property {ImageEvent} image - The image message received
* @example listen for image events
* conversation.on("image", (sender, image) => {
* console.log(sender,image);
* // Identify if your own imageEvent or someone else's.
* if (image.from !== conversation.me.id){
* displayImages(image);
* }
* });
*/
/**
* Conversation listening for deleted events.
*
* @event Conversation#event:delete
*
* @property {Member} member - the Member who deleted an event
* @property {NXMEvent} event - deleted event: event.id
* @example get details about the deleted event
* conversation.on("event:delete", (member, event) => {
* console.log(event.id);
* console.log(event.body.timestamp.deleted);
* });
*/
/**
* Conversation listening for ephemeral events.
* @param {object} body customizable key value pairs
*
* @returns {Promise} - the ephemeral event that was sent
*
* @example get ephemeral event
* conversation.on("ephemeral", (member, event) => {
* console.log(event);
* });
*
*/
/**
* Conversation listening for new Members.
*
* @event Conversation#member:joined
*
* @property {Member} member - the Member that joined
* @property {NXMEvent} event - the join event
* @example get the name of the new Member
* conversation.on("member:joined", (member, event) => {
* console.log(event.id)
* console.log(member.userName+ " joined the conversation");
* });
*/
/**
* Conversation listening for Members being invited.
*
* @event Conversation#member:invited
*
* @property {Member} member - the Member that is invited
* @property {NXMEvent} event - data regarding the receiver of the invitation
* @example get the name of the invited Member
* conversation.on("member:invited", (member, event) => {
* console.log(member.userName + " invited to the conversation");
* });
*/
/**
* Conversation listening for Members callStatus changes.
*
* @event Conversation#member:call:status
*
* @property {Member} member - the Member that has left
* @example get the callStatus of the member that changed call status
* conversation.on("member:call:status", (member) => {
* console.log(member.callStatus);
* });
*/
/**
* Conversation listening for Members leaving (kicked or left).
*
* @event Conversation#member:left
*
* @property {Member} member - the Member that has left
* @property {NXMEvent} event - data regarding the receiver of the invitation
* @example get the username of the Member that left
* conversation.on("member:left", (member , event) => {
* console.log(member.userName + " left");
* console.log(event.body.reason);
* });
*/
/**
* Conversation listening for Members typing.
*
* @event Conversation#text:typing:on
*
* @property {Member} member - the member that started typing
* @property {NXMEvent} event - the start typing event
* @example get the display name of the Member that is typing
* conversation.on("text:typing:on", (member, event) => {
* console.log(member.displayName + " is typing...");
* });
*/
/**
* Conversation listening for Members stopped typing.
*
* @event Conversation#text:typing:off
*
* @property {Member} member - the member that stopped typing
* @property {NXMEvent} event - the stop typing event
* @example get the display name of the Member that stopped typing
* conversation.on("text:typing:off", (member, event) => {
* console.log(member.displayName + " stopped typing...");
* });
*/
/**
* Conversation listening for Members' seen texts.
*
* @event Conversation#text:seen
*
* @property {Member} member - the Member that saw the text
* @property {TextEvent} text - the text that was seen
* @example listen for seen text events
* conversation.on("text:seen", (member, text) => {
* console.log(text);
* if (conversation.me.id !== member.memberId) {
* console.log(member);
* }
* });
*/
/**
* Conversation listening for Members' seen images.
* @event Conversation#image:seen
*
* @property {Member} member - the member that saw the image
* @property {ImageEvent} image - the image that was seen
* @example listen for seen image events
* conversation.on("image:seen", (member, image) => {
* console.log(image);
* if (conversation.me.id !== member.memberId) {
* console.log(member);
* };
* });
*/
/**
* Conversation listening for Members submitted messages.
* @event Conversation#message:submitted
*
* @property {Member} member - the member that message was submitted to
* @property {MessageEvent} message - the message that was submitted
* @example listen for submitted message events
* conversation.on("message:submitted", (member, message) => {
* console.log(message);
* if (conversation.me.id !== member.memberId) {
* console.log(member);
* };
* });
*/
/**
* Conversation listening for Members rejected messages.
* @event Conversation#message:rejected
*
* @property {Member} member - the member that message was rejected by
* @property {MessageEvent} message - the message that was rejected
* @example listen for rejected message events
* conversation.on("message:rejected", (member, message) => {
* console.log(message);
* if (conversation.me.id !== member.memberId) {
* console.log(member);
* };
* });
*/
/**
* Conversation listening for Members undeliverable messages.
* @event Conversation#message:undeliverable
*
* @property {Member} member - the member that message was undeliverable to
* @property {MessageEvent} message - the message that was undeliverable
* @example listen for undeliverable message events
* conversation.on("message:undeliverable", (member, message) => {
* console.log(message);
* if (conversation.me.id !== member.memberId) {
* console.log(member);
* };
* });
*/
/**
* Conversation listening for Members delivered messages.
* @event Conversation#message:delivered
*
* @property {Member} member - the member that message was delivered to
* @property {MessageEvent} message - the message that was delivered
* @example listen for delivered message events
* conversation.on("message:delivered", (member, message) => {
* console.log(message);
* if (conversation.me.id !== member.memberId) {
* console.log(member);
* };
* });
*/
/**
* Conversation listening for Members seen messages.
* @event Conversation#message:seen
*
* @property {Member} member - the member that message was seen by
* @property {MessageEvent} message - the message that was seen
* @example listen for seen message events
* conversation.on("message:seen", (member, message) => {
* console.log(message);
* if (conversation.me.id !== member.memberId) {
* console.log(member);
* };
* });
*/
/**
* Conversation listening for Members media changes (audio,text)
*
* Change in media presence state. They are in the Conversation with text or audio.
*
* @event Conversation#member:media
*
* @property {Member} member - the Member object linked to this event
* @property {NXMEvent} event - information about media presence state
* @property {boolean} event.body.audio - is audio enabled
* @example get every Member's media change events
* conversation.on("member:media", (member, event) => {
* console.log(event.body.media); //{"audio": true, "audio_settings": {"enabled": true, "muted": false, "earmuffed": false}}
* });
*/
/**
* Conversation listening for mute on events
* A Member has muted their audio
*
* @event Conversation#audio:mute:on
*
* @property {Member} member - the Member object linked to this event
* @property {NXMEvent} event - information about the mute event
* @example listen for audio mute on events
* conversation.on("audio:mute:on", (member, event) => {
* console.log("member that is muted ", member);
* console.log(event);
* });
*/
/**
* Conversation listening for mute off events
* A member has unmuted their audio
*
* @event Conversation#audio:mute:off
*
* @property {Member} member - the member object linked to this event
* @property {NXMEvent} event - information about the mute event
* @example listen for audio mute off events
* conversation.on("audio:mute:off", (member, event) => {
* console.log("member that is unmuted ", member);
* console.log(event);
* });
*/
sendRequest(request: CAPIRequest, callback: Function): void;
sendNetworkRequest(params: NetworkRequestParams): Promise;
/**
* Create a new Session.
* @param {string} token - the user JSON Web Token (JWT)
* @returns {Promise} - the application logged in to
* @example Create a session and return the Application
* rtc.createSession(token).then((application) => {
* console.log(application);
* }).catch((error) => {
* console.log(error);
* });
*/
createSession(token: string): Promise;
/**
* Delete existing Session.
* @returns {Promise} - response with rid and type
* @example Delete existing session
* rtc.deleteSession().then((response) => {
* console.log(response);
* }).catch((error) => {
* console.log(error);
* });
*/
deleteSession(): Promise;
updateSession(event: CAPIResponse): any;
/**
* Disconnect from the cloud.
*
*/
disconnect(): SocketIOClient.Socket;
/**
* Connect to the cloud.
*
*/
connect(): SocketIOClient.Socket;
/**
* Get a connectivity report for all Vonage DCs and Media Servers.
* @param {string} token - the JSON Web Token (JWT)
* @param {object} options - configure the connectivityReport
* @param {Function} options.dcListCallback - a callback function to edit the list of datacenters before connectivity checks
* @returns {Promise}
* @example Get a connectivity report
*
* rtc.connectivityReport(token, {
* dcListCallback: (dcList) => {...dcList, additionalDc}
* }).then((report) => {
* console.log(report);
* }).catch((error) => {
* console.log(error);
* });
*/
connectivityReport(token: string, options?: {
dcListCallback?: Function;
}): Promise;
/**
* Return a list with the connection health of the media servers for a specific datacenter.
* @returns {Promise}
* @param {string} token - the JSON Web Token (JWT)
* @param {string} nexmo_api_url - url of the nexmo api to be called
* @param {string} datacenter - datacenter of interest
* @example Return a list with the connection health of the media servers
*
* rtc.checkMediaServers('nexmo-api-url','dc').then((responseArray) => {
* console.log(responseArray);
* }).catch((error) => {
* console.log(error);
* });
*/
checkMediaServers(token: string, nexmo_api_url: string, datacenter: string): Promise;
/**
* Return the connection health of a single media server including possible connectionTime in ms.
* @returns {Promise}
* @param {string} ip - ip address of the Media Server
* @param {string} port - port number of the Media Server
* @example Return the connection health of a single media server
*
* rtc.checkMediaConnectivity('ip-address','1').then((response) => {
* console.log(`IP Address of media server: ${response.ip}`);
* console.log(`Able to connect: ${response.canConnect}`);
* console.log(`ConnectionTime in ms: ${resonse.connectionTime}`);
* }).catch((error) => {
* console.log(error);
* });
*/
checkMediaConnectivity(ip: string, port: number): Promise;
}
export class UserSession {
application: Application;
id: string;
_embedded: {
user: User;
};
constructor(application: Application, params?: any);
}
export class User {
application: Application;
id: string;
name: string;
constructor(application: Application, params?: Object);
}
/**
* Utilities class for the SDK.
*
* @class Utils
* @private
*/
export class Utils {
/**
* Get the Member from the username of a conversation
*
* @param {string} username the username of the member to get
* @param {Conversation} conversation the Conversation to search in
* @returns {Member} the requested Member
* @static
*/
static getMemberFromNameOrNull(conversation: Conversation, username: string): Member | null;
/**
* Get the Member's number or uri from the event's channel field
*
* @param {object} channel the event's channel field
* @returns {string} the requested Member number or uri
* @static
*/
static getMemberNumberFromEventOrNull(channel: Channel): string | null;
/**
* Check if the input is sanitized
* @param input Text to be checked for sanitization
* @returns {boolean} true if the input is sanitized, false otherwise
*/
static isSanitizedInput(input: string): boolean;
/**
* Check if the input is a sanitized URL
* @param input URL to be checked for sanitization
* @returns {boolean} true if the input is a sanitized URL, false otherwise
*/
static isSanitizedUrlInput(input: string): boolean;
static checkIsSanitized([key, value]: [string, any]): boolean;
/**
* Perform a network request to the given url
*
* @param {object} reqObject the object that has all the information for the request
* @param {string} url the request url
* @param {string} type=GET|POST|PUT|DELETE the types of the network request
* @param {object} [data] the data that are going to be sent
* @param {string} [responseType] the response type of the request
* @param {string} token the jwt token for the network request
* @returns {Promise} the NetworkRequestResponse
* @static
*/
static networkRequest(reqObject: ReqObject): Promise;
/**
* Perform a GET network request for fetching paginated conversations and events
*
* @param {string} url the request url
* @param {object} [params] network request params
* @param {string} [params.cursor] cursor parameter to access the next or previous page of a data set
* @param {number} [params.page_size] the number of resources returned in a single request list
* @param {string} [params.order] 'asc' or 'desc' ordering of resources (usually based on creation time)
* @param {string} [params.event_type] the type of event used to filter event requests ('member:joined', 'audio:dtmf', etc)
* @param {string} token the jwt token for the network request
* @param {string} [version=Application.CONVERSATION_API_VERSION.v1] version of conversation service that is used for the request (one of v1 and v3)
*
* @returns {Promise} the XMLHttpRequest
* @static
* @example Sending a nexmo GET request
* paginationRequest(url, params).then((response) => {
* response.items: {},
* response.cursor: {
* prev: '',
* next: '',
* self: ''
* },
* response.page_size: 10,
* response.order: 'asc',
* });
*/
static paginationRequest(url: string, params: any, token: string, version?: string): Promise;
/**
* Update the Search Params of a url
* @returns {string} the appended url
* @static
*/
static addUrlSearchParams(url: string, params?: {
[key: string]: string;
}): string;
/**
* Deep merges two objects
* @returns {Object} the new merged object
* @static
*/
static deepMergeObj(obj1: Configuration, obj2: Configuration): Configuration;
/**
* Inject a script into the document
*
* @param {string} s script being executed
* @param {requestCallback} c the callback fired after script executed
* @static
*/
static injectScript(u: any, c: any): void;
static allocateUUID(): string;
/**
* Validate dtmf digit
* @static
*/
static validateDTMF(digit: string): boolean;
/**
* Get the nexmo bugsnag api key
* @private
*/
static _getBugsnagKey(): string;
/**
* Update the member legs array with the new one received in the event
*
* @param {Array} legs the member legs array
* @param {NXMEvent} event the member event holding the new legs array
* @static
*/
static updateMemberLegs(legs: Leg[], event: CAPIResponse): Leg[];
/**
* Check if the event is referenced to a call or simple conversation
* @private
*/
static _isCallEvent(event: CAPIResponse): boolean;
/**
* Fetch an image from Media Service
* @private
*/
static _fetchImage(url: string, token: string): Promise;
/**
* Check if HTTP URL is reachable
* @private
*/
static _checkHttpConnectivity(url: string): Promise;
/**
* Check if websocket URL is reachable
* @private
*/
static _checkWsConnectivity(ws_url: string, path: string, config: Object): Promise;
/**
* Return a list with the connection health of the Media Servers
* @private
*/
static _checkMediaServers(token: string, nexmo_api_url: string, datacenter: string): Promise;
/**
* Check if we can establish a peer connection with a specific Media Server
* @private
*/
static _checkMediaConnectivity(ip: string, port: number): Promise;
/**
* Check if the user is re invited to an existing conversation
* @private
*/
static _checkIfUserIsReInvited(conversations: Map, event: CAPIResponse): boolean;
}
///
///
export interface CAPIRequest {
type: string;
body: any;
tid?: string
}
export interface CAPIResponse {
type: string;
body: any;
rid: string;
delay?: string;
from?: string;
cid?: string;
client_ref?: string;
timestamp?: string;
streamIndex?: number;
id?: string;
conversation? : any;
_embedded?: EventEmbeddedInfo;
}
export interface NetworkRequestParams {
version?: string;
type: string;
path: string;
data?: any
}
export interface User {
name: string;
display_name: string;
}
export interface From {
type: string;
user: string;
uri: string;
number: string;
}
export interface To {
number: string;
type: string;
}
export interface Channel {
id?: string;
type: string;
leg_ids: Array;
leg_settings: Array;
legs: Array;
from: From;
to: To;
}
export interface ReqObject {
url: string;
type: string;
data?: any;
responseType?: '' | 'json' | 'arraybuffer' | 'blob' | 'document' | 'text';
token?: string;
}
export interface Response {
event_type?: string;
page_size: number;
_embedded: any;
_links: any;
}
export interface Leg {
leg_id: string;
status: string;
}
export interface ImageRepresentations {
id: string;
medium: {
id: string;
size: number;
type: string;
url: string;
};
original: {
id: string;
size: number;
type: string;
url: string;
};
thumbnail: {
id: string;
size: number;
type: string;
url: string;
};
[key: string]: any;
}
export interface Configuration {
debug?: any;
log_reporter?: {
enabled?: boolean;
bugsnag_key?: string | null;
};
environment?: string;
ips_url?: string;
nexmo_api_url?: string;
path?: string;
repository?: string;
socket_io?: {
reconnection?: boolean;
reconnectionAttempts?: number;
reconnectionDelay?: number;
reconnectionDelayMax?: number;
randomizationFactor?: number;
forceNew?: boolean;
autoConnect?: boolean;
transports?: string[];
query?: {
token: string,
SDK_version: string,
session_version:string,
acknowledge_events: boolean,
OS_family: string,
OS_revision: string
}
};
SDK_version?: string,
sync?: string;
url?: string;
iceServers?: [];
rtcstats?: RTCStatsConfig;
conversations_page_config?: {
page_size: number;
order: string;
cursor: string;
};
events_page_config?: {
page_size: number;
order: string;
event_type: string;
};
enableEventsQueue?: boolean;
enableInboundOffer?: boolean;
acknowledgeEvents?: boolean;
token?: string | null;
[key: string]: any;
}
export interface RTCStatsConfig {
remote_collection_url?: string;
remote_collection?: boolean;
remote_collection_interval?: number;
emit_events?: boolean;
emit_rtc_analytics?: boolean;
emit_interval?: number;
}
export interface InviteParams {
id?: string;
user_name?: string;
media?: {
audio_settings: {
enabled?: boolean;
earmuffed?: boolean;
muted?: boolean;
};
};
}
export interface PrewarmResponse {
stream: MediaStream;
legId: string;
rtcObjects: RtcObjects;
}
export interface PostLegResponse {
rtc_id: string;
sdp: string;
}
export interface RtcObjects {
[key: string]: {
rtc_id: string;
pc: RTCPeerConnection;
stream: MediaStream;
type: string;
streamIndex: number;
}
}
export interface MosReport {
min: string;
max: string;
last?: string;
average?: string;
}
export interface RTCStatsAnalyticsParams {
application: Application;
conversation?: Conversation;
pc: RTCPeerConnection;
rtc_id: string;
config: RTCStatsConfig;
}
export interface MediaHandlerContext {
application: Application;
pc: any;
conversation?: Conversation;
streamIndex?: number;
log?: Logger;
localStream?: MediaStream;
rtcObjects?: RtcObjects;
reconnectRtcId?: string;
resolve?: (value?: PromiseLike | MediaStream) => void;
reject?: (reason?: any) => void;
}
export interface LogLevel {
TRACE: 0;
DEBUG: 1;
INFO: 2;
WARN: 3;
ERROR: 4;
SILENT: 5;
}
export type MethodFactory = (methodName: string, level: LogLevelNumbers, loggerName: string) => LoggingMethod;
export type LogLevelNumbers = LogLevel[keyof LogLevel];
export type LoggingMethod = (...message: any[]) => void;
export type LogLevelDesc = LogLevelNumbers
| 'trace'
| 'debug'
| 'info'
| 'warn'
| 'error'
| 'silent'
| keyof LogLevel;
export interface Logger {
readonly levels: LogLevel;
methodFactory: MethodFactory;
trace(...msg: any[]): void;
debug(...msg: any[]): void;
info(...msg: any[]): void;
warn(...msg: any[]): void;
error(...msg: any[]): void;
setLevel(level: LogLevelDesc, persist?: boolean): void;
getLevel(): LogLevel[keyof LogLevel];
setDefaultLevel(level: LogLevelDesc): void;
enableAll(persist?: boolean): void;
disableAll(persist?: boolean): void;
}
export interface EventEmbeddedInfo {
from_user?: {
id?: string;
name?: string;
display_name?: string;
image_url?: string;
custom_data?: Object;
},
from_member: {
id?: string;
name?: string;
display_name?: string;
image_url?: string;
custom_data?: Object;
}
}
export interface ConversationMemberInfo {
memberId: string;
userId?: string;
userName?: string;
displayName?: string;
imageUrl?: string;
customData?: Object;
}
export interface MessageEventParams {
message_type: string;
text?: string;
image?: {
url: string;
};
audio?: {
url: string;
};
video?: {
url: string;
};
file?: {
url: string;
};
}
export type NetworkRequestResponse =
| XMLHttpRequest
| NexmoServers
| MediaServerInfo[];
export interface NexmoServers {
[key: string]: {
endpoint: string;
https: string;
ws: string;
};
}
export interface Report {
machineInfo: {
ip: string;
};
connectivityReport: ConnectivityReport[];
}
export interface ConnectivityReport {
name: string;
signalConnectionReport: SignalConnectionReport;
mediaConnectionReport: MediaConnectionReport[];
}
export interface SignalConnectionReport {
https: HttpsSignalConnectionReport;
ws: WsSignalConnectionReport;
}
export interface HttpsSignalConnectionReport {
url: string;
canConnect: boolean;
connectionTime?: number;
error?: string;
}
export interface WsSignalConnectionReport {
url: string;
canConnect: boolean;
connectionTime?: number;
error?: object;
}
export interface MediaConnectionReport {
ip: string;
canConnect: boolean;
connectionTime?: number;
error?: object;
}
export interface MediaServerInfo {
ip: string;
port: number;
}
export interface PublicIpOptions {
onlyHttps?: boolean;
timeout?: number;
fallbackUrls?: string[];
}
export type PublicIpFunction = (options?: any) => Promise