The Call Message Events feature allows your client-side and server-side applications to communicate via custom ("user-defined") messages during a Voice SDK call. The feature leverages the existing signaling connection, so you don't need to set up your own communication channel between your client-side and server-side applications.
Two Twilio REST API Resources are used for server-side implementation:
The JavaScript, iOS, Android, and React Native SDKs provide the following functionality for the client-side implementation of Call Message Events:
In order to implement the Call Message Events feature, you must use supported versions of the Voice SDK and Helper Libraries.
Client-Side SDK | Minimum Version Required |
---|---|
Voice JavaScript SDK | v2.2.0 |
Voice iOS SDK | v6.5.0 |
Voice Android SDK | v6.4.0 |
Voice React Native SDK | v1.0.0 |
Helper Library | Minimum Version Required |
---|---|
Node.js | v3.83.1 |
Java | v9.1.1 |
C# | v5.81.1 |
Python | v7.15.1 |
PHP | v6.43.1 |
Go | v1.1.1 |
Twilio CLI | v5.2.2 |
The Call Message Events feature works only for active Calls.
Client side
From the perspective of the SDK, a Call is active when both the signaling and media connections are established.
Select language/platform below to see how to active Calls are defined in the SDK.
The Call is active and ready for sending and receiving messages when the Call instance's status is "open"
or "ringing"
.
The status of the Call is retrieved via the call.status() method.
The Call instance's accept event is emitted when the Call state transitions to open
.
The Call instance's ringing event is emitted when the Call state transitions to ringing
.
Server side
From the server side perspective, an "active" Call is a Call Resource with a CallStatus
value of either in-progress
or ringing
.
The status for a Call Resource can be retrieved from the body of status callback requests or by fetching a Call Resource via API.
The general flow of sending a message from the server side to the SDK is as follows:
POST
request to the Call's
UserDefinedMessages endpoint
. This request contains the message to be sent.
You must have some way of retrieving the Call SID on your server side. One way to do this is with the statusCallback
and statusCallbackEvent
attributes in your <Client> and <Number> TwiML, in conjunction with an endpoint that handles status callback requests from Twilio.
Add logic to your client-side application that handles incoming messages.
Select your Voice SDK language/platform below to see an example of receiving messages in the SDK.
1call.on("messageReceived", (message) => {2console.log(JSON.stringify(message.content));3//the voiceEventSid can be used for tracking the message4console.log('voiceEventSid: ', message.voiceEventSid);5})
Once a Call is active, send a message by sending a POST
request to the Call's UserDefinedMessages endpoint. The message content is passed in the Content
parameter as a JSON string.
1// Download the helper library from https://www.twilio.com/docs/node/install2const twilio = require("twilio"); // Or, for ESM: import twilio from "twilio";34// Find your Account SID and Auth Token at twilio.com/console5// and set the environment variables. See http://twil.io/secure6const accountSid = process.env.TWILIO_ACCOUNT_SID;7const authToken = process.env.TWILIO_AUTH_TOKEN;8const client = twilio(accountSid, authToken);910async function createUserDefinedMessage() {11const userDefinedMessage = await client12.calls("CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")13.userDefinedMessages.create({14content: JSON.stringify({ key1: "Hello from the server side." }),15});1617console.log(userDefinedMessage.accountSid);18}1920createUserDefinedMessage();
1{2"account_sid": "ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",3"call_sid": "CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",4"sid": "KXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",5"date_created": "Wed, 18 Dec 2019 20:02:01 +0000"6}
Be sure you're using the correct Call SID when creating a subscription.
If the SDK end user (the recipient of the message) made an outgoing call, you must subscribe to the parent Call SID.
If the SDK end user (the recipient of the message) accepted an incoming call, you must subscribe to the child Call SID.
Learn more about Call legs and the SDKs on the Voice SDK Overview page.
Provided that the message was sent successfully from the server side, the SDK will receive the message. See the code samples above for SDK-specific handling of incoming messages.
In order to receive messages on your server from the SDK, you need to set up a subscription to the Call's messages. In the subscription, you specify where Twilio should send the messages. Once a subscription is created, the SDK end-user can send messages that Twilio will then send in an HTTP request to your server-side application.
The general flow of sending a message from the SDK to the server side is as follows:
POST
request to the Call's
UserDefinedMessageSubscriptions endpoint
.
call.sendMessage()
method is invoked in the SDK.
Callback
parameter when subscribing to a Call's messages.
statusCallback
and
statusCallbackEvent
attributes in your
<Client>
and
<Number>
TwiML, in conjunction with an endpoint that handles status callback requests from Twilio.
Add logic to your client-side application that:
call.sendMessage()
method during an active call
Select your Voice SDK language/platform below to see an example of sending a message from the SDK to the server side.
1// Errors related to Call Message Events are emitted by the Device instance.2device.on("error", function (twilioError) {3console.error(twilioError);4});56// a Call is active78// add listener for 'messageSent' event9call.on("messageSent", () => {10console.log("Message sent.")11});1213// create the Call Message14const callMessage = {15content: { key1: 'This is a messsage from the parent call' },16messageType: 'user-defined-message',17contentType: "application/json"18}1920// send the message21// the voiceEventSid can be used for tracking the message22sendMessageButton.onclick = () => {23console.log('Sending message.')24const voiceEventSid = call.sendMessage(callMessage)25}
You can only send messages during an active Call. If you have any UI elements that your SDK end user interacts with (e.g. a "Send Message" button), make sure that sending messages is only enabled during an active Call.
Once a Call is active, your server-side must set up a subscription to a Call's messages by making a POST
request to the Call's UserDefinedMessageSubscription Resource.
The Callback
parameter specifies your endpoint that will receive messages from Twilio.
1// Download the helper library from https://www.twilio.com/docs/node/install2const twilio = require("twilio"); // Or, for ESM: import twilio from "twilio";34// Find your Account SID and Auth Token at twilio.com/console5// and set the environment variables. See http://twil.io/secure6const accountSid = process.env.TWILIO_ACCOUNT_SID;7const authToken = process.env.TWILIO_AUTH_TOKEN;8const client = twilio(accountSid, authToken);910async function createUserDefinedMessageSubscription() {11const userDefinedMessageSubscription = await client12.calls("CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")13.userDefinedMessageSubscriptions.create({14callback:15"https://www.example.com/your-endpoint-that-can-receive-messages",16method: "POST",17});1819console.log(userDefinedMessageSubscription.accountSid);20}2122createUserDefinedMessageSubscription();
1{2"account_sid": "ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",3"call_sid": "CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",4"sid": "ZYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",5"date_created": "Wed, 18 Dec 2019 20:02:01 +0000",6"uri": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/UserDefinedMessageSubscriptions/ZYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.json"7}
Be sure you're using the correct Call SID when creating a subscription.
If the SDK end user (who is sending messages that you wish to receive) made an outgoing call, you must subscribe to the parent Call SID.
If the SDK end user (who is sending messages that you wish to receive) accepted an incoming call, you must subscribe to the child Call SID.
Learn more about Call legs and the SDKs on the Voice SDK Overview page.
Once a subscription has been set up, the SDK can now invoke the call.sendMessage()
event.
If a subscription was created and then the SDK sent a message successfully, your Callback
endpoint will receive the request from Twilio. The message from the SDK is contained in the Content
property of the request.
See an example of the Twilio's request to the Callback
endpoint below, followed by a description of the parameters in the request.
1{2ContentType: 'application/json',3Content: '{"key1":"This is a messsage from the SDK"}',4SequenceNumber: '1',5CallSid: 'CA0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',6Timestamp: 'Fri, 2 Dec 2022 22:02:49 +0000',7AccountSid: 'ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',8Sid: 'KXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'9}
Parameter | Description |
---|---|
ContentType | The Content-Type of the request. (Currently, Twilio only supports application/json.) |
Content | The message sent from the SDK as a JSON string. |
SequenceNumber | The order in which the messages were sent, starting from 0. |
CallSid | The SID of the Call Resource this message is associated with |
Timestamp | The timestamp when Twilio sent this message, given as UTC in RFC 2822 format. |
AccountSid | The Twilio Account SID associated with the message. |
Sid | A unique identifier for this message. This can be used for internal logging/tracking. |