Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

nexmo-client

Nexmo24kApache 2.09.6.1TypeScript support: included

Nexmo Client SDK for JavaScript

nexmo, webrtc, conversation, sdk, ip-messaging, rtc, communication, audio

readme

Vonage Client SDK for JavaScript

Twitter

The Client SDK is intended to provide a ready solution for developers to build Programmable Conversation applications across multiple Channels including: Messages, Voice, SIP, websockets, and App.

The following media types are supported:

In-App Messaging

  • Offline Sync – With built-in caching, messages are saved and sent or received once their device is back online.
  • Push Notifications – Keep users aware of important alerts by sending notifications to their device.
  • Text and Image Support – Users can quickly send and receive texts and images from your application.

    Read more about In-App Messaging.

In-App Voice

  • User Control – Users can control whether their audio stream is muted or unmuted.
  • Notifications – Users can be notified when they receive a call or when participants are muted.
  • Group Calls – Configure call settings so users can start a group call by adding participants in real time.

    Read more about In-App Voice.

Tutorials

See how the Client SDK is used in the following tutorials:

Installation

NPM

A dependency manager for Node packages. You can install the Client SDK with the following command:

npm install nexmo-client

SDK Setup

Include the nexmoClient.js script in your web page

<script src="node_modules/nexmo-client/dist/nexmoClient.js"></script>

Or the minified version

<script src="node_modules/nexmo-client/dist/nexmoClient.min.js"></script>

Testing

We use third party tools for testing the framework:

  • Karma: Karma is our test runner
  • Mocha: Mocha is a feature-rich JavaScript test framework running on Node.js and in the browser, making asynchronous testing simple and fun.
  • Chai: Chai is a BDD / TDD assertion library for node and the browser that can be delightfully paired with any javascript testing framework.

Code style & Conventions

License

Copyright (c) 2020 Vonage, Inc. All rights reserved. Licensed only under the Vonage Client SDK License Agreement (the "License") located at LICENCE.

By downloading or otherwise using our software or services, you acknowledge that you have read, understand and agree to be bound by the Vonage Client SDK License Agreement and Privacy Policy.

You may not use, exercise any rights with respect to or exploit this SDK, or any modifications or derivative works thereof, except in accordance with the License.

changelog

Changelog

9.6.1

Changes

  • We now throw an error on unsanitized inputs

9.6.0

New

  • Dispatch rtc:iceconnectionstatechange event at application level when a ice connection state
  application.on('rtc:iceconnectionstatechange', (state) => {
    console.log(state);
  });
  • Dispatch rtc:peerconnectionstatechange event at application level when a peer connection for a call has a state change
  application.on('rtc:peerconnectionstatechange', (state) => {
    console.log(state);
  });
  • Dispatch rtc:peerconnectioncreated event at application level when a peer connection is created
  application.on('rtc:peerconnectioncreated', (peerconnection) => {
    console.log(peerconnection);
  });
  • Dispatch rtc:icecandidateerror event at application level when there is an error with the ice candidate
  application.on('rtc:icecandidateerror', (error) => {
    console.log(error);
  });
  • Dispatch rtc:icegatheringstatechange event at application level when a ice state changes during ice gathering process
  application.on('rtc:icegatheringstatechange', (state) => {
    console.log(state);
  });
  • Dispatch rtc:signalingstatechange event at application level when a peer connection signaling state change
  application.on('rtc:signalingstatechange', (state) => {
    console.log(state);
  });

Changes

  • Update webrtc-adapter shim to 9.0.1

9.5.3

Fixes

  • Fix bug on keeping active local streams open if RTCPeerConnection establishment fails

9.5.2

Changes

  • Improve Event Sync request efficiency

9.5.1

Fixes

  • Fix bug on networkRequest data stringification

9.5.0

New

  • Support pending events (missed member:invited)

9.4.0

New

  • Support ephemeral event
// send ephemeral event
conversation
  .sendEphemeralEvent({ state: "INVITED" })
  .then((event) => {
    console.log(event)
  });

9.3.1

Fixes

  • Fix NexmoAPI error wrapping for v0.3 Conversation API endpoints

9.3.0

New

  • Add state to query param for application.getConversations() for the ConversationsPage object
// iterate through conversations
application
  .getConversations({ state: "INVITED" })
  .then((conversations_page) => {
    conversations_page.items.forEach(conversation => {
      render(conversation);
    })
  });

Fixes

  • Fix type definition for Conversation timestamp to object
  • Default socket.io query session_version to 0.0.1 unless enableInboundOffer flag set to true, then default to 0.0.2

9.2.6

Changes

  • Add WS reconnection metrics

9.2.5

Fixes

  • Fix type definition for enableEventsQueue and enableInboundOffer
  • Add acknowledgeEvents flag in the configuration to allow tracking of websocket event acknowledgement

9.2.4

Fixes

  • Emitting reconnecting socket event on reconnection attempt

9.2.3

Changes

  • Upgrade socket.io-client version to 4.6.1

9.2.2

Fixes

  • Fix ConversationEventsProcessor being initiated multiple times for the same conversation

9.2.1

Fixes

  • Fix EmitMediaStream listener for failed call

9.2.0

Changes

  • Add enableInboundOffer flag to config for inbound call setup
  • Remove Ice Servers default from webrtc STUN server setup
  • Replace api.nexmo URLs to api.vonage URLs

9.1.5

Fixes

  • Fix bug on user re invited/joined to a conversation

9.1.4

Changes

  • Use v2 of Nexmo Conversation Websocket

9.1.3

Fix

  • Fix typescript module definition

9.1.2

Fix

  • Refactor preload media function

9.1.1

Fix

  • Fix events ordering for rtc:transfer on named conversations

9.1.0

New

  • Use pre-loaded media on inbound calls (start WebRTC ice gathering process as soon as member is invited to a call)

Fix

  • Remove public-ip library because of a security vulnerability (updated with is-ip)

9.0.0

Breaking changes

  • Rename login() function to createSession()
rtc.createSession(token).then((application) => {
  console.log(application);
}).catch((error) => {
  console.log(error);
});
  • Rename logout() function to deleteSession()
rtc.deleteSession().then((response) => {
  console.log(response);
}).catch((error) => {
  console.log(error);
});

Changes

  • Move websocket connection creation to the createSession() function

8.7.3

Changes

  • Added token authentication to connectivityReport()
rtc.connectivityReport(token, {
  dcListCallback: (dcList) => {...dcList, additionalDc}
}).then((report) => {
  console.log(report);
}).catch((error) => {
  console.log(error);
});
  • Added token authentication to checkMediaServers()
rtc.checkMediaServers('token', 'nexmo-api-url','dc').then((responseArray) => {
 console.log(responseArray);
}).catch((error) => {
  console.log(error);
});

8.7.2

Fix

  • Removed unused npm dependencies.

8.7.1

New

  • Added new checkMediaServers() method to return a list with the connection health of the media servers for a specific datacenter.
rtc.checkMediaServers('nexmo-api-url','dc').then((responseArray) => {
    console.log(responseArray);
}).catch((error) => {
  console.log(error);
});
  • Added new checkMediaConnectivity() method to return the connection health of a single media server.
rtc.checkMediaConnectivity('ip-address','1').then((response) => {
  console.log(response);
}).catch((error) => {
    console.log(error);
});

Changes

  • Update connectivityReport() to return connection time in ms for connection to https, wss, and media servers

8.6.0

New

  • Added an optional object argument to the connectivityReport(), with optional field dcListCallback which accepts a callback function to update data center list
rtc.connectivityReport({
  dcListCallback: (dcList) => {...dcList, additionalDc}
}).then((report) => {
  console.log(report);
}).catch((error) => {
  console.log(error);
});

8.5.0

New

  • Expose seen() and delivered() functions for message events
messageEvent.seen().then(() => {
  console.log(`Seen message with id ${messageEvent.id}`);
}).catch((error) => {
  console.log(error);
});
  • Support new message status events
    • message:seen
    • message:delivered
    • message:submitted
    • message:rejected
    • message:undeliverable
conversation.on("message:delivered", (member, event) => {
  console.log(`Message with id ${event.id} delivered to ${member.name}`);
});
  • Added new state objects for message events supporting the new statuses
    • seen_by
    • delivered_to
    • submitted_to
    • rejected_by
    • undeliverable_to

Changes

  • Update connectivityReport() to use proper endpoints per region

8.4.1

Fix

  • Fix events ordering when gap in inbound events

8.4.0

New

  • Added new connectivityReport() function to get a connectivity report for all Vonage data centers and media servers
rtc.connectivityReport().then((report) => {
  console.log(report);
}).catch((error) => {
  console.log(error);
});

8.3.1

New

  • Set the default sync level for the login process from lite to none

8.3.0

New

  • Added new uploadImage() function to upload an image to the Vonage Media Service
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);
});
  • Added new sendMessage() function to send a new message to the conversation (supported types are text, image, audio, video and file)
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);
});
conversation.sendMessage({
  "message_type": "image",
  "image": {
    "url": "https://example.com/image.jpg"
  }
})
.then((event) => {
  console.log("message was sent", event);
}).catch((error)=>{
  console.error("error sending the message ", error);
});
  • Added new MessageEvent type of event
conversation.on("message", (member, messageEvent) => {
  console.log(messageEvent);
});

Changes

  • Deprecate sendText() function (use sendMessage() with a type of text instead)
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);
});
  • Deprecate sendImage() function (use uploadImage() and sendMessage() with a type of image instead)
conversation.uploadImage(imageFile).then((imageRequest) => {
  imageRequest.onreadystatechange = () => {
    if (imageRequest.readyState === 4 && imageRequest.status === 200) {
      try {
        const { original, medium, thumbnail } = JSON.parse(imageRequest.responseText);
        const message = {
          message_type: 'image',
          image: {
            url: original.url ?? medium.url ?? thumbnail.url
          }
        }
        return conversation.sendMessage(message);
      } catch (error) {
        console.error("error sending the message ", error);
      }
    }
    if (imageRequest.status !== 200) {
      console.error("error uploading the image");
    }
  };
  return imageRequest;
})
.catch((error) => {
  console.error("error uploading the image ", error);
});

8.2.5

Fix

  • Fix error handling for audio permissions

8.2.2

Fix

  • Enhance debug logs

8.2.0

New

  • Add new getUserSessions() function to fetch the sessions of the logged in user
application.getUserSessions({ user_id: "USR-id", page_size: 20 }).then((user_sessions_page) => {
  user_sessions_page.items.forEach(user_session => {
    render(user_session)
  })
}).catch((error) => {
  console.error(error);
});

8.1.1

New

  • Add new optional mediaParams parameter in reconnectCall function, in order to modify the MediaStream object
application.reconnectCall(
  "conversation_id",
  "rtc_id",
  { audioConstraints: { deviceId: "device_id" } }
).then((nxmCall) => {
  console.log(nxmCall);
}).catch((error) => {
  console.error(error);
});
  • Update media.enable() docs to include audio constraints

Fixes

  • Assign the correct NXMCall status when reconnecting to a call (STARTED, RINGING or ANSWERED)

Changes

  • Update npm dependencies

8.1.0

New

  • Add reconnectCall function allowing users to reconnect to a call within 20 seconds if browser tab closed
application.reconnectCall("conversation_id", "rtc_id").then((nxmCall) => {
  console.log(nxmCall);
}).catch((error) => {
  console.error(error);
});
  • Add optional parameter reconnectRtcId to media enable() function to reconnect media to call
conversation.media.enable({ reconnectRtcId: "UUID" }).then((stream) => {
  console.log(stream)
}).catch((error) => {
  console.error("error renabling media", error);
});
  • Add custom_data object in callServer function
application.callServer("<phone_number>", "phone", { field1: "test" }).then((nxmCall) => {
  console.log(nxmCall);
}).catch((error) => {
  console.error(error);
});
  • Add apiKey, applicationId, conversationId and conversationName when available in rtcstats analytics reports

Fixes

  • Fix bug in call transfer where transferred_from was undefined

8.0.5

Fixes

  • Fix the from for member events
  • Update npm dependencies including socket-io

8.0.4

Fixes

  • Fix bug on DTMF dispatch of callback to event_url

8.0.3

Fixes

  • Fix out of order internal events processing in the events queue
  • Fix deprecation warning message for rtcstats:report

8.0.1

Fixes

  • Update Typescript definitions
  • Fix bug on IP-IP call scenario involving Native SDKs (not populating properly the Conversation.members Map)

8.0.0

Breaking changes

  • Deprecate Conversation.members Map (it will be populated only on a call scenario)
  • Conversation events will be emitted with a subset information of the Member
conversation.on("any:event", ({memberId, userId, userName, displayName, imageUrl, customData}, event) => {});

Changes

  • Add paginated getMembers() function to retrieve the members of a conversation
conversation.getMembers().then((members_page) => {
  members_page.items.forEach(member => {
    render(member);
  })
}).catch((error) => {
  console.error("error getting the members ", error);
});
  • Add getMyMember() function to retrieve our own member in a conversation
conversation.getMyMember().then((member) => {
  render(member);
}).catch((error) => {
  console.error("error getting my member", error);
});
  • Add getMember() function to fetch a conversation member by member_id
conversation.getMember("MEM-id").then((member) => {
  render(member);
}).catch((error) => {
  console.error("error getting member", error);
});

Fixes

  • Update Typescript definitions

7.1.0

Changes

  • rtcstats:report is deprecated. Please use rtcstats:analyticsinstead
application.on('rtcstats:analytics', ({
  type: 'mos' || 'mos_report',
  mos: string,
  rtc_id: string,
  mos_report?: {
    average: string,
    last: string,
    max: string,
    min: string
  },
  report?: RTCStatsReport
}) => {}
  • Add logs reporter for remote logging
  • Add custom getStats parser
  • Remove callstats library and implementation

7.0.2

Fixes

  • Emit 'call:status:update' event when application offline and call disconnected

7.0.1

Fixes

  • Remove unnecessary warning message for call status transitions

7.0.0

Breaking changes

  • legs endpoint should be included in acl paths on JWT token creation
"acl": {
  "paths": {
    ...,
    "/*/legs/**": {}
  }
}

Changes

  • Improve callServer setup time by prewarming leg
  • Add the rtcObject and remote stream to the NxmCall object

Fixes

  • Return ClientDisconnected reason when client logouts from SDK

6.2.1

Fixes

  • Revert back to 6.1.1 from 6.2.0-alpha

6.1.2

Fixes

  • Update Typescript definitions

6.1.1

Fixes

  • Update Typescript definitions

6.1.0

Changes

  • Add enableEventsQueue flag to client configuration (default to true)
  • Add internal eventsQueue mechanism to guarantee order of events received during a session

6.0.19

Changes

  • Update reconnectionDelay to 2000 in socket.io
  • Add randomizationFactor to 0.55 in socket.io

6.0.18

Changes

  • Update documentation

Fixes

  • Add reconnectionDelay to 3000 and reconnectionDelayMax to 15000 in socket.io

6.0.17

Fixes

  • Update Session id after reconnection

6.0.16

Fixes

  • Dispatch system:error:expired-token event in application level
  application.on('system:error:expired-token', 'NXM-errors', () => {
    console.log('Token Expired');
  });
  • Handle uncaught exception of conversation:error:invalid-member-state event

6.0.15

Fixes

  • Set SDK default to single preset ICE candidate
  • Remove iceGatherOnlyOneCandidate flag from client configuration

6.0.13

Fixes

  • Update websocket reconnection logic for token expiry

6.0.12

Fixes

  • Update resolved stream on media enabling

6.0.11

Changes

  • Update websocket reconnection logic
  • Fix delay in establishing media connection with one ice candidate sent

6.0.10

Fixes

  • Filter IPv6 Candidates from iceGatherOnlyOneCandidate SDP offer

6.0.9

Fixes

  • Fix handler of rtc:transfer event to refresh conversation

6.0.8

Fixes

  • Fix duplicated webrtc offer sent during IP calling
  • Fix Safari WebRTC dependency

6.0.7

Fixes

  • Fix ANSWERED call status in IP - IP calling
  • Fix docs issues

Changes

  • Improve TypeScript definitions

6.0.6

Fixes

  • Add iceGatherOnlyOneCandidate configuration option and use to define path in ICE gathering process

6.0.5

Fixes

  • Update styling of JSDocs to Docstrap template
  • Change RTCPeerConnection ICE candidates gathering process to send the Session Description Protocol (SDP) offer on first ICE candidate gathered

6.0.4

Fixes

  • Remove remaining audio elements after transferring a call to a new conversation
  • Update conversation.invite() to not include empty user_id or user_name fields within the requests

6.0.3

New

  • Added TypeScript definition files

Changes

  • Added options for customized logging levels in the console of debug, info, warn, or error.
new NexmoClient({
  debug: 'info'
})
  • Moved storage of JWT token from localStorage to NexmoClient configuration object
  • Removed unnecessary files from the NPM release package

Fixes

  • Fixed call statuses order in case of a transfer

6.0.1

Changes

  • Removed media.record() and media.fetchRecording() functions
  • Removed cache option from SDK, used for storing conversations and events
  • Removed automatic syncing of all individual conversations in login, when sync is lite or full

6.0.0

Breaking Changes

  • Change return value of application.getConversations() to new ConversationsPage object
// iterate through conversations
application
  .getConversations({ page_size: 20 })
  .then((conversations_page) => {
    conversations_page.items.forEach(conversation => {
      render(conversation);
    })
  });
  • Change return value of conversation.getEvents() to new EventsPage object
// iterate through events
conversation
  .getEvents({ event_type: `member:*` })
  .then((events_page) => {
    events_page.items.forEach(event => {
      render(event);
    })
  });
  • Rename method application.callPhone to application.callServer
  • Rename method application.call to application.inAppCall
  • Rename method call.createPhoneCall to call.createServerCall
  • Rename class Call to NXMCall
  • Rename class ConversationClient to NexmoClient
  • Rename class ConversationClientError to NexmoClientError
  • Rename files conversationClient.js and conversationClient.min.js to nexmoClient.js and nexmoClient.min.js
  • Deprecate member:call:state event (use instead member:call:status)
  • Remove automatic login in case of a websocket reconnection and emit the event

New

  • Send and listen for custom event types in a conversation.
//sending a custom event type to a conversation
conversation
  .sendCustomEvent({type: `my_custom_event`, body: { enabled: true }})
  .then((custom_event) => {
    console.log(event.body);
  });
//listening for a custom event type
conversation.on(`my_custom_event`, (from, event) => {
  console.log(event.body);
});
  • Add new PageConfig class for configuring settings for paginated requests
  • Add new Page class to wrap results of paginated requests
  • Add setup of default pagination configuration for conversations and events in ConversationClient initialization
  • Add wild card supported for filtering by event types using :* (for example event_type: member:*)
new NexmoClient({
  conversations_page_config: {
    page_size: 25,
    order: 'asc'
    cursor: 'abc'
  },
  events_page_config: {
    page_size: 50,
    event_type: `member:*`
  }
})
  • Add new ConversationsPage and EventsPage which extend Page class to wrap results of paginated requests for conversations and events
  • Add getNext() and getPrev() methods to ConversationsPage and EventsPage objects to fetch previous and next pages of conversations and events
  • Add conversations_page_last parameter to application object and events_page_last parameter to conversation object for reference to last page retrieved
application.conversations_page_last
  .getNext((conversations_page) => {
    conversations_page.items.forEach(conversation => {
      render(conversation)
    })
  })
conversation.events_page_last
  .getPrev((events_page) => {
    events_page.items.forEach(event => {
      render(event)
    })
  })
  • Add the ability to make an IP-IP call through callServer function
// IP-IP call scenario
application
  .callServer('username', 'app')
  .then((nxmCall) => {
    // console.log(nxmCall);
  });

// IP-PSTN call scenario
application
  .callServer('07400000000')
  .then((nxmCall) => {
    // console.log(nxmCall);
  });

Changes

  • Update reason object to receive reason.reason_text and reason.reason_code fields

Internal changes

  • Rename Event class to NXMEvent
  • Update CAPI requests to REST calls for these events
    • event:delivered
    • text:delivered
    • image:delivered
    • event:seen
    • text:seen
    • image:seen
    • conversation:events
    • audio:play
    • conversation:delete
    • conversation:invite
    • text
    • text:typing:on
    • text:typing:off
    • new:conversation
    • conversation:get
    • user:conversations
    • user:get
    • conversation:join
    • audio:say
    • audio:earmuff:on
    • audio:earmuff:off
    • audio:dtmf
    • audio:record
    • audio:play
    • conversation:member:delete
    • event:delete
    • audio:ringing:start
    • audio:ringing:stop
    • audio:mute:on
    • audio:mute:off
    • image
    • rtc:new
    • rtc:answer
    • rtc:terminate
    • knocking:new
    • knocking:delete

5.3.4

Fixes

  • Custom SDK config object does a deep merge with default config object

5.3.3

Fixes

  • Change digits to digit in the sendDTMF() request method payload
  • Stream is not being terminated on a call transfer
  • member:call is not being emitted if media.audio_settings.enabled is false or doesn't exist

New

  • Set member.callStatus started when initialising an IP - IP call
  • Set member.callStatus ringing when enabling the ringing with media.startRinging()

Internal changes

  • Move stream clean up from member:left to rtc:hangup in Media module

5.3.2

Breaking changes

  • Revert 5.3.1 pagination back to 5.2.1

5.3.1

Patch

  • Update expected payload for pagination

5.3.0

New

  • Migrated from websocket to network requests for conversation.getEvents() & application.getConversations() in preparation for new paginated endpoints

5.2.1

New

  • Support reason for member:delete conversation.leave, member.kick, call.hangup and call.reject
  • Listen for the member:left event with reason
//listening for member:left with reason
conversation.on('member:left', (member, event) => {
  console.log(event.body.reason);
});
/**
* Reason object format
*
* @param {object} [reason] the reason for kicking out a member
* @param {string} [reason.code] the code of the reason
* @param {string} [reason.text] the description of the reason
*/
  • Add callStatus field in the Member object, defining the status of a call
  • Emit member:call:status event each time the member.callStatus changes
conversation.on("member:call:status", (member) => {
   console.log(member.callStatus);
});

5.2.0

New

  • Add the call instance in application.calls map in createCall() function (IP -IP call)

  • Update caller parameter in call object in a PSTN - IP call from unknown to channel.from.number or channel.from.uri if exists

  • Emit the new leg:status:update event each time a member leg status change

/**
  * Conversation listening for leg:status:update events.
  *
  * @event Conversation#leg:status:update
  *
  * @property {Member} member - the member whose leg status changed
  * @property {Event} event - leg:status:update event
  * @param {string} event.cid - the conversation id
  * @param {string} event.body.leg_id - the conversation leg id
  * @param {string} event.body.type - the conversation leg type (phone or app)
  * @param {string} event.body.status - the conversation member leg status
  * @param {Array} event.body.statusHistory - array of previous leg statuses
*/
conversation.on("leg:status:update", (member, event) {
  console.log(member, event);
});
  • Add the the channel.legs field in member events offered by CS
conversation.on(<member_event>, (member, event) {
  console.log(event);
  // member_id: <member_id>,
  // conversation_id: <conversation_id>,
  // ...
  // channel: {
  //  to: {
  //    type: app
  //  },
  //  type: app,
  //  leg_ids: [<leg_id>]
  //  legs : [{ leg_id: <leg_id>, status: <leg_status>}],
  //  leg_settings: {},
  // },
  // state: <state>,
  // leg_ids: []
});

5.1.0

New

  • Send DTMF event to a conversation

    * Send DTMF in a conversation
    *
    * @param {string} digits - the DTMF digit(s) to send
    * @returns {Promise<Event>}
 conversation.media.sendDTMF('digits')
  • Emit new event audio:dtmf
conversation.on("audio:dtmf",(from, event)=>{
  event.digit // the dtmf digit(s) received
  event.from //id of the user who sent the dtmf
  event.timestamp //timestamp of the event
  event.cid // conversation id the event was sent to
  event.body // additional context about the dtmf
});
  • Set customized audio constraints for IP calls when enabling audio
 conversation.media.enable({
    'audioConstraints': audioConstraints
 })
  * Replaces the stream's audio tracks currently being used as the sender's sources with a new one with new audio constraints
  * @param {object} constraints - audio constraints
  * @returns {Promise<MediaStream>} - Returns the new stream with the updated audio constraints.
  * @example
  * conversation.media.updateAudioConstraints({'autoGainControl': true})
  **/
  • Update audio constraints for existing audio tracks
  conversation.media.updateAudioConstraints(audioConstraints)
 })

Fixes

  • Remove 'this' passed to cache worker event handler

Internal breaking changes

  • Change the media audio parameter from media.audio to media.audio_settings in inviteWithAudio function

5.0.3

Changes

  • Change default behaviour of autoPlayAudio in media.enable() from false to true
  • Pass an autoPlayAudio parameter to call.createCall() and call.answer() functions (default is true)

5.0.2

New

  • Delete the image files before sending the image:delete request
  • Attach of audio stream can now be chosen if it will be automatically on or off through media.enable()
media.enable({
  autoPlayAudio: true | false
})

Changes (internally)

  • Combine the network GET, POST and DELETE requests in one generic function

5.0.1

Fixes

  • Clean up user's media before leaving from an ongoing conversation

Breaking changes

  • Change application.conversations type from Object to Map

4.1.0

Fixes

  • Fixed the bug where the audio stream resolved in media.enable() is causing echo and was not the remote stream
  • Resolve the remote stream pc.ontrack() and not the localStream from getUserMedia

Changes

  • Rename localStream to stream in media.rtcObjects object.

4.0.2

Changes

  • Removed media.rtcNewPromises

New

  • Internal lib dependencies update
  • Added suport for Bugsnag error monitoring and reporting tool
 * @class ConversationClient
 *
 * @param {object} param.log_reporter configure log reports for bugsnag tool
 * @param {Boolean} param.log_reporter.enabled=false
 * @param {string} param.log_reporter.bugsnag_key your bugsnag api key / defaults to Nexmo api key
  • Updated vscode settings to add empty line (if none) at end of every file upon save
  • Disable the ice candidates trickling in ice connection
  • Wait until most of the candidates to be gathered both for the local and remote side
  • Added new private function editSDPOrder(offer, answer) in rtc_helper.js to reorder the answer SDP when it's needed
  • For rtc connection fail state
    • Disable leg
    • emit new event media:connection:fail
member.on("media:connection:fail",(connection_details)=>{
  connection_details.rtc_id // my member's call id / leg id
  connection_details.remote_member_id // the id of the Member the stream belongs to
  connection_details.connection_event: // the connection fail event
  connection_details.type // the type of the connection (video or screenshare)
  connection_details.streamIndex // the streamIndex of the specific stream
});
* @event Member#media:connection:fail
*
* @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 {event} payload.connection_event the connection fail event
  • Add new LICENCE file

Breaking changes (internally)

  • Deprecating ice trickling logic with onicecandidate event handler
  • Change the format of member:media event to the new one offered by CS
type: 'member:media',
  from: member.member_id,
  conversation_id: member.conversation_id,
  body: {
    media: member.media,
    channel: member.channel
  }
  • Change the format of member:invited event to the new offered by CS
type: 'member:invited',
  body: {
    media: {
      audio_settings: {
        enabled: false,
        earmuffed: false,
        muted: false
      }
    }
  }

4.0.1

New

  • Select the sync level for the login process

    • full: trigger full sync to include conversations and events
    • lite: trigger partial sync, only conversation objects (empty of events)
    • none: don't sync anything

    if the Cache module is enabled the manual fetch of a conversation will store them in internal storage

    usage:

    new ConverationClient({'sync':'full'});

Fixes

  • rtcstats:report was duplicating instances in each call
  • remove screenshare https restriction

Breaking changes (internally)

  • Deprecating application.activeStream, now it's part of application.activeStreams
  • Removed the restriction to allow calling media.enable() while a stream is active

4.0.0

Breaking Changes

  • rename SDK stitch to client
  • listening for media:stream:* now gives streamIndex instead of index for consistency with the internal rtcObjects
 * @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.video_mute] if the video is hidden
 * @property {boolean} [payload.audio_mute] if the audio is muted

Internal Breaking Changes

New

  • Screen Share Source ID can now be specified when invoking media.enable()

3.0.2

New

  • Get local stream details under member object on media:stream:on for audio

call.conversation.me.on("media:stream:on",(stream_details)=>{
  // stream_details.rtc_id // my member's call id / leg id
  // stream_details.pc // the PeerConnection object of the instance
  // stream_details.stream: // the local stream object,
  // stream_details.type: 'audio', // the stream type
  // stream_details.index: streamIndex // the stream index
});
 * @event Member#media:stream:on
 *
 * @property {number} payload.index 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.video_mute] if the video is hidden
 * @property {boolean} [payload.audio_mute] if the audio is muted

Fix

  • Resubscribe to events after disabling and re-enabling media (video flow)

Changes

  • update default socket.io reconnectionAttempts from infinity to 5

Breaking changes

  • group socket.io configuration params

    e.g. to disable auto-reconnect: new ConversationClient({socket_io:{

    reconnection:false

    }})

  • rename Stitch-client errors to NXM-errors errors

Example: Listen to general errors

            application.on('*', 'NXM-errors', (error) => {
              console.log('An error has been thrown with the type' + error.type);
            });

Example: Listen to expired token and update it

            application.on('system:error:expired-token', 'NXM-errors', () => {
              application.updateToken(<token>)
                .then(() => {
                  console.log('Token Expired');
                });
            });

3.0.1

New

  • handle call transfer events rtc:transfer

    • attach member.transferred_from = old_conversation to know that the member has been transferred from another conversation
    • attach member.transferred_to = new_conversation to know that this new member comes from a transfer
    • attach call.transferred to know that a transfer has happened in this call object
  • Added Call.id property, when the call is initialised. (leg_id/call_id) (Use this id to transfer this rtc member)

Fixes

  • Now the SDK won't kick the last member of a conversation in a call (it was causing most of the conversation:not-found issues when a call was terminated)

Internal Changes

  • moved conversation.rtcObjects to the media level

it was conversation.media.parentConversation.rtcObjects, Now you can access the rtcObjects in the media level conversation.media.rtcObjects

  • the single PeerConnection object (audio only flow) has also been moved to the media level. conversation.media.pc

3.0.0

BREAKING CHANGES

  • Conversation.members is now a Map()
  • Call.to members is now a Map()

to get a member object


conversation.members.get(member_id);

to loop through members


for (const member of conversation.members.values()) { ... }

2.2.0

New

  • NPM lib dependencies update

  • Added mos_report as the last param in ConversationClient#rtcstats:report when the audio stream is disabled.

  • support callstats.io

    • set the initial config: callstats: { enabled: true, AppID: 'xxx', AppSecret: 'yyy' },

Fix

  • on call hangup the rtc:terminate was sent two times

  • fix media.mute() for audio stream when the audio is enabled for a second time

Breaking Changes

  • drop support for development for Node v5

2.1.0

Breaking Changes

  • Screen share

    • screenshareExtensionId changed to screenShareExtensionId
new ConversationClient({
      debug: false,
      screenShareExtensionId: YOUR_EXTENSION_ID
    })
  • RTC stats

    • config params for rtcstats are now under a single object

before:

params.rtcstats_enabled = false
params.rtcstats_url = 'url'
params.rtcstats_events = true

now:

params.rtcstats.ws_url = 'url'
params.rtcstats.emit_events = true

New

  • Call stats event

    • initialise by setting initial config: new ConversationClient({rtcstats.emit_events:true});

    • listen for MOS for the Audio stream on Application.on('rtcstats:report', data);

  • Updated webRTC adapter (better support for browsers)

  • Internal lib dependency updates

  • Call object now has a direction (Outbound, Inbound)

  • Add minified version in public bundle dist/conversationClient.min.js

Fixes

  • change build/publish flow to include the dist/conversationClient.min.js

  • covering more use cases: listen your user's join and invite events on both application and conversation level

  • Timeout with success for Ice gathering for audio calls (mid solution until trickle is done)

  • Fix call status ANSWERED IP-PSTN case, should reflect the PSTN member joining the audio stream

  • Call status now does not go to a previous status

  • Switch to websocket protocol to fix disconnection issues

Internal optimisations

  • documentation for WebRTC stats reporting to WS server

    • initialise by setting initial config: new ConversationClient({rtcstats.ws_url:"wss://..."});

    • the WebSocket should then start receiving webrtc reports every 1s (reconnect timeout: 5000ms, retries 5) not yet configurable

Known Issues

  • media.mute() throws error when the audio has been disabled and enabled again