Voice JavaScript SDK: Twilio.Device
You’re viewing the documentation for the 2.X version of the Voice JavaScript SDK. View the Migration Guide to learn how to migrate from 1.X to 2.X or view the 1.x-specific documentation.
The Twilio Client JavaScript SDK has been renamed to Twilio Voice JavaScript SDK.
The Device
object is available when the JavaScript SDK is included in your application. It represents a softphone that communicates with Twilio to facilitate inbound and outbound audio connections.
For the full API reference, view the autogenerated documentation on GitHub.
Throughout this page, you will see device
with a lowercase "d" and Device
with an uppercase "D".
Device
refers to the Device
object provided by the SDK.
device
represents an instance of a Device
, created with the new
keyword:
const device = new Device(token);
Table of Contents
Instantiate a Device
A new instance of a Device
should be constructed by using the new
keyword and passing an Access Token as the first argument. The constructor also takes an optional second argument, DeviceOptions
.
No signaling channel will be opened when instantiating a new Device
. The signaling WebSocket will be opened when either device.register()
or device.connect()
are called.
The maximum number of characters for the identity
provided in the Access Token is 121. The identity
may only contain alpha-numeric and underscore characters. Other characters, including spaces, or exceeding the maximum number of characters, will result in not being able to place or receive calls.
Instantiate a Device without DeviceOptions
const device = new Device(token);
The DeviceOptions
parameter is optional. The Device
instance's options can be updated after instantiation using the device.updateOptions()
method.
Instantiate a Device with DeviceOptions
Examples of using DeviceOptions
to specify an Edge location:
// Instantiate the device with a specified edge location
const device = new Device(token, { edge: 'ashburn'};
// Instantiate the device with a specified edge and auto-fallback functionality
const device = new Device(token, { edge: ['ashburn', 'sydney'] };
To see all of the possible properties, see the DeviceOptions section below.
DeviceOptions
The Device
instance can be configured using the DeviceOptions
parameter in two ways: during instantiation with the new
keyword or by calling device.updateOptions()
.
const deviceOptions = {
edge: 'ashburn',
}
// pass the options object as the second argument in Device constructor
const device = new Device(token, deviceOptions);
// or
// use the updateOptions method after instantiating the device
const device = new Device(token);
device.updateOptions(deviceOptions);
DeviceOptions
is a JavaScript object with the properties listed in the table below. All properties are optional.
Options Property | Description |
allowIncomingWhileBusy Boolean default: |
Whether the |
appName string |
A name for the application that is instantiating the |
appVersion string |
A version for the application that is instantiating the |
closeProtection Boolean or string default: |
Setting this property to
Setting the property to a |
codecPreferences string[] default: |
An array of codec names ordered from most-preferred to least-preferred. Opus and PCMU are the two codecs currently supported by Twilio Voice JS SDK. Opus can provide better quality for lower bandwidth, particularly noticeable in poor network conditions. Examples: |
disableAudioContextSounds Boolean |
Whether AudioContext sounds should be disabled. Useful for troubleshooting sound issues that may be caused by AudioContext-specific sounds. If set to |
dscp Boolean |
Whether to use googDscp in RTC constraints |
edge string[] or string default: |
The Edge location to connect to. If using an array of edges, sort by highest priority to lowest priority. The array will be used to provide auto fallback functionality. Check the If the |
enumerateDevices function |
Pass a custom enumerateDevices function to override what Twilio uses when requesting a list of available media input and output devices. |
forceAggressiveIceNomination Boolean default: |
Experimental feature. Sets whether the If your deployment is on devices with one network interface and your Round Trip Time (RTT) to Twilio's Servers is typically greater than 96 milliseconds, this feature may help reduce call connect time. As this is an experimental feature, we don't recommend enabling this until after testing it thoroughly in your deployment. |
getUserMedia function |
Pass a custom getUserMedia function to override what Twilio uses to create an input MediaStream. |
logLevel number |
The Voice JavaScript SDK exposes a loglevel-based logger to allow for runtime logging configuration. You can set this property to a number which corresponds to the log levels shown below. |
maxAverageBitrate number |
Max average bitrate to better control how much bandwidth your VoIP application should use. See RFC-7587 section 7.1. Only applicable when using Max Average Bitrate can be set to as low as Values outside this range are ignored and the default Opus operation mode is used. Lowering the max average bitrate impacts audio quality. The recommended bitrate for speech is between If you set |
maxCallSignalingTimeoutMs number default: |
The maximum duration in milliseconds the Twilio.Device will attempt to reconnect to the most-recently-used edge in the event of a signaling connectivity loss. After the provided time has passed during reconnection attempts, the Twilio.Device will then use edge fallback. The default value of Since the Twilio.Device will only attempt to reestablish connectivity for up to 30 seconds, the maximum value you would want to use here is Note: This property is only related to users relying on edge fallback and some users using the 'roaming' edge. |
RTCPeerConnection function |
Overrides the native RTCPeerConnection class. By default, the SDK will use the For example, if the browser supports In order to avoid this issue, you need to explicitly set the SDP format that you want the SDK to use with the See the example below. Assuming the
|
sounds object |
A JavaScript object with key/value pairs of sound names (as the key) and URLs (as the value). See the deviceOptions.sounds properties section below for all available properties (keys for the deviceOptions.sounds object) and the default sounds provided by the SDK. Note: The incoming ringtone will loop for at least two seconds and as long as the incoming call is pending. All other sounds will play once; DTMF tones will be cut short if they exceed one second, while outgoing and disconnect sounds will be cut short if they exceed three seconds. |
tokenRefreshMs number default:
|
The number of milliseconds before the AccessToken's expiry that the Twilio.Device will emit the The default is 10 seconds (10000 milliseconds). |
Example:
Specify an Edge location using DeviceOptions
// pass options object during device instantiation
const device = new Device(token, { edge: 'ashburn' });
// or
// pass options object using the updateOptions method
const device = new Device(token);
device.updateOptions({ edge: 'ashburn' });
Example:
Specify an Edge location and custom sounds
const deviceOptions = {
edge: 'ashburn',
sounds: {
incoming: 'http://mysite.com/incoming.mp3',
outgoing: 'http://mysite.com/outgoing.mp3',
dtmf8: 'http://mysite.com/8_button.mp3'
}
}
// pass options object during device instantiation
const device = new Device(token, deviceOptions);
// or
// pass options object using the updateOptions method
const device = new Device(token);
device.updateOptions(deviceOptions);
deviceOptions.sounds properties and default sounds
The available properties on the deviceOptions.sounds
object are listed in the left column of the table below. In the right column, there are audio players to hear the default sounds provided by the Voice JavaScript SDK.
deviceOptions.sounds property | Default sound |
---|---|
incoming |
|
outgoing |
|
disconnect |
|
dtmf1 |
|
dtmf2 |
|
dtmf3 |
|
dtmf4 |
|
dtmf5 |
|
dtmf6 |
|
dtmf7 |
|
dtmf8 |
|
dtmf9 |
|
dtmf0 |
|
dtmfs |
|
dtmfh |
|
Methods
This section contains descriptions of the methods available on a Device
instance.
|
device.addListener(eventName, listener)
Add an event listener to the Device
instance. This is an alias for device.on()
.
See the Events section of this page to see the full list of events emitted by a Device
instance.
Parameter | Data Type | Description |
eventName | string or symbol |
The event emitted by the |
listener | function |
The function that will be called when the specified event is emitted |
Example:
If you want to know when your Device
instance is ready to receive incoming calls, listen for the 'registered'
event.
const device = new Device(token);
device.addListener('registered', device => {
console.log('The device is ready to receive incoming calls.')
});
See the Node.js Events Docs for more information.
device.connect(ConnectOptions)
Attempts a new connection to the Twilio application that you associated with the Access Token used when instantiating the Device
instance.
This method will return a Promise with a Call object. You should keep track of this
Call
object to monitor/modify the active call.
To end the call, you can use the .disconnect()
method on the Call
object or use the device.disconnectAll()
method.
const device = new Device(token);
let call = await device.connect({
params: {
To: '+15551234567'
}
});
ConnectOptions
device.connect()
takes an optional ConnectOptions argument. The ConnectOptions object is a JavaScript object with optional params
, rtcConfiguration
, and rtcConstraints
properties.
Example:
const device = new Device(token);
let call = await device.connect({
params: {
To: "+15551234567"
agent: "Smith",
location: "Matrix"
},
rtcConstraints: {
audio: true
},
rtcConfiguration: {
iceServers: [{
urls: "stunserver.example.com",
username: "username@twilio.com",
credential: "webrtcCredential"
}]
}
})
params
property
A JavaScript object containing key/value pairs to be sent to the Twilio application. These params
will be passed to your application as GET or POST parameters.
The total length of all params
passed to device.connect()
must not exceed 800 bytes. See How to Share Information Between Your Applications for more information.
Your application should not assume that these parameters are safe since any user can call this function with whatever parameters they want.
For example, the following code will pass the params
key/value pairs agent=Smith
and location=Matrix
to the Twilio application associated with this Device
instance's Access Token.
const device = new Device(token);
let call = await device.connect({
params: {
agent: "Smith",
location: "Matrix"
}
});
rtcConfiguration
property
An RTCConfiguration dictionary to pass to the RTCPeerConnection constructor. This allows you to configure the WebRTC connection between your local machine and the remote peer.
rtcConstraints
property
A MediaStreamConstraints dictonary to pass to getUserMedia when making or accepting a Call. This allows you to configure the behavior of tracks returned in the MediaStream.
Each browser implements a different set of MediaTrackConstraints
, so consult your browser's implementation of getUserMedia
for more information.
device.destroy()
Destroys the Device
instance.
This method will disconnect all calls, unbind audio devices, destroy the stream (which causes the unregistered
event to be emitted), and then the Device
instance will emit the destroyed
event. Then, all event listeners attached to the Device
instance are cleaned up.
const device = new Device(token);
device.destroy();
device.disconnectAll()
Disconnect all Calls
associated with the Device
instance.
Example:
A user clicks on a Hang Up button in the browser, which calls device.disconnectAll()
to end the current Call.
const device = new Device(token);
// A click on a 'Hang Up' button calls this method
const hangupCall = () => {
device.disconnectAll();
console.log('The call has ended.');
}
device.emit(eventName, ...args)
Calls each of the event listeners registered for the event named eventName
. The listeners will be called in the order they were registered. Any arguments passed in after the eventName
will be passed to the event listeners.
Parameter | Data Type | Description |
eventName | string or symbol |
The event emitted by the |
args | any |
The arguments that will be passed to the event listener(s) for the specified event |
See the Node.js Events Docs for more information.
device.eventNames()
Returns an array of event names for which the Device
instance has registered event listeners.
See the Node.js Events Docs for more information.
device.getMaxListeners()
Returns the current maximum number of event listeners for the Device
instance.
By default, the maximum number of listeners is 10, and is set by the static Device.defaultMaxListeners
property or the dynamic device.setMaxListeners(number)
method.
See the Node.js Events Docs for more information.
device.listenerCount(eventName)
Returns the number of listeners listening to the event named eventName
on the Device
instance.
Parameter | Data Type | Description |
eventName | string or symbol |
The name of the event for which you want to retrieve the listener count |
See the Node.js Events Docs for more information.
device.listeners(eventName)
Returns an array of the listeners registered on the Device
instance for the event named eventName
.
Parameter | Data Type | Description |
eventName | string or symbol | The name of the event for which you want to retrieve the listeners |
See the Node.js Events Docs for more information.
device.off(eventName, listener)
Removes the listener
for the event named eventName
. This is an alias for device.removeListener()
.
const device = new Device(token);
const handleSuccessfulRegistration = () => {
console.log('The device is ready to receive incoming calls.')
}
device.on('registered', handleSuccessfulRegistration);
device.off('registered', handleSuccessfulRegistration);
See the Node.js Event Docs for more information.
device.on(eventName, listener)
Add an event listener to the Device
instance. This is analogous to the Device.addListener()
method.
See the Events section of this page to see the full list of events emitted by the Device
instance.
Parameter | Data Type | Description |
eventName | string or symbol |
The event emitted by the |
listener | function |
The function that will be called when the specified event is emitted |
Example:
If you want to know when your Device
instance is ready to receive incoming calls, listen for the 'registered'
event.
const device = new Device(token);
device.on('registered', device => {
console.log('The device is ready to receive incoming calls.')
};
device.once(eventName, listener)
Adds a one-time listener to the Device
instance for the event named eventName
.
Parameter | Data Type | Description |
eventName | string or symbol |
The event emitted by the |
listener | function |
The function that will be called when the specified event is emitted. The listener function will be removed and then invoked one time. |
See the Node.js Events Docs for more information.
device.prependListener(eventName, listener)
Adds a listener function to the beginning of the listeners array for the event named eventName
.
Calling this multiple times with the same eventName
and listener
arguments will add the listener again, meaning that the listener will be called multiple times when the specified event is emitted.
Parameter | Data Type | Description |
eventName | string or symbol |
The event emitted by the |
listener | function |
The function that will be called when the specified event is emitted. The listener will be added to the beginning of the listeners array for the specified event. |
See the Node.js Events Docs for more information.
device.prependOnceListener(eventName, listener)
Adds a one-time listener to the beginning of the listener array for the specified event.
Parameter | Data Type | Description |
eventName | string or symbol |
The event emitted by the |
listener | function |
The function that will be called the next time the specified event is emitted. The listener will be removed from the listeners array before being invoked. |
See the Node.js Events Docs for more information.
device.rawListeners(eventName)
Returns an array of the listeners associated with the event named eventName
. This includes any wrappers.
Parameter | Data Type | Description |
eventName | string or symbol |
the event for which you want to retrieve the listeners array (includes any wrappers) |
See the Node.js Events Docs for more information.
device.register()
Register the Device
instance with Twilio, allowing it to receive incoming calls. This will open a signaling WebSocket, so the browser tab may show the 'recording' icon.
It is not necessary to call device.register()
in order to make outgoing calls.
const device = new Device(token);
const handleSuccessfulRegistration = () => {
console.log('The device is ready to receive incoming calls.')
}
device.on('registered', handleSuccessfulRegistration);
device.register();
Some browsers will throw errors on pages that play audio that isn't initiated by a user gesture. Twilio recommends calling device.register()
in response to a user gesture, such as a click. One popular and intuitive way to implement this is to add a button that will call device.register()
.
Example:
A user clicks on a Start Device button that will fire device.register()
to enable the Device
instance to receive incoming calls. Once registered, the Device
instance will emit the 'registered'
event.
const device = new Device(token);
// Listen for the 'registered' event
device.on('registered', () => {
console.log('The device is ready to receive calls.')
})
// A 'Start Device' button click calls this method
const startDevice = () => {
console.log('Registering the device to receive calls.');
device.register();
}
device.removeAllListeners(eventNames?)
Removes all listeners on the Device
instance if no argument is passed. This is not recommended.
The optional eventNames
parameter is an array of event name strings.
If eventNames
argument is passed, only those listeners will be removed. This is only recommended for events and event listeners that you have added, not those created by the SDK.
const device = new Device(token);
// removes all event listeners
device.removeListeners();
// removes the listeners for the "event1" and "event2" events
device.removeListeners(["event1", "event2"]);
See the Node.js Events Docs for more information.
device.removeListener(eventName, listener)
Removes the listener specified by the eventName
and listener
arguments. This is analogous to device.off()
.
const device = new Device(token);
const handleSuccessfulRegistration = () => {
console.log('The device is ready to receive incoming calls.')
}
device.on('registered', handleSuccessfulRegistration);
device.removeListener('registered', handleSuccessfulRegistration);
See the Node.js Events Docs for more information.
device.setMaxListeners(number)
Set the maximum number of event listeners allowed on this Device
instance. The default maximum is 10.
Calling this method will change only the maximum allowed on this specific instance of a Device
. If you want to change the maximum number of listeners allowed for all Device
instances, consider setting the static Device.defaultMaxListeners
property on the global Device
object provided by the SDK.
Note: device.setMaxListeners(number)
will have precedence over Device.defaultMaxListeners
.
const device = new Device(token);
device.setMaxListeners(20);
device.unregister()
Unregister the Device
instance with Twilio. This will prevent the Device
instance from receiving incoming calls.
The Device
instance will emit the 'unregistered' event when successfully unregistered with Twilio.
const device = new Device(token);
// Listen for the 'unregistered' event
device.on('unregistered', () => {
console.log('The device is no longer able to receive calls.')
})
const unregisterDevice = () => {
console.log('Unregistering the device.');
device.unregister();
}
device.updateOptions(options)
Set the options used within the Device
instance.
See the DeviceOptions section above for the full list of available options.
Example:
Specify an Edge location and custom sounds
const options = {
edge: 'ashburn',
sounds: {
incoming: '',
outgoing: '',
dtmf8: ''
}
}
const device = new Device(token);
device.updateOptions(options);
device.updateToken(token)
Update the token used by this Device
instance to connect to Twilio.
If the token expires, the Device
instance will not be able to receive or make calls. It will also prevent statistics from being sent to Voice Insights.
It is recommended to call this API after device.tokenWillExpire
event is emitted, and before or after a call to prevent a potential ~1s audio loss during the update process.
In the future, as Twilio explores signaling reconnection support, keeping this token updated will be important for automatically restoring connection to a Call
or re-registering the Device
instance.
Example:
// time to live for the token, in milliseconds
const timeToLive = 600000; // 10 minutes
const refreshBuffer = 30000; // 30 seconds
const token = await getTokenViaAjax({ timeToLive });
const device = new Device(token);
setInterval(async () => {
const newToken = await getTokenViaAjax({ timeToLive });
device.updateToken(token);
}, timeToLive - refreshBuffer);
Events
destroyed Event
Emitted when the Device
has been destroyed.
Listen for the 'destroyed'
event.
const device = new Device(token);
device.on('destroyed', () => {
// Do something
});
error Event
Emitted when the Device
instance receives an error.
The event listener will receive a TwilioError
and when applicable, a reference to the Call
object that was active when the error occured. See the TwilioError section below for more information on the TwilioError
object.
Listen for the 'error'
event.
const device = new Device(token);
device.on('error', (twilioError, call) => {
console.log('An error has occurred: ', twilioError);
});
TwilioError
The format of the TwilioError
returned from the error event is a JavaScript object with the following properties:
Property | Description |
causes string[] |
A list of possible causes for the error |
code number |
The numerical code associated with this error |
description string |
A description of what the error means |
explanation string |
An explanation of when the error may be observed |
message string |
Any further information discovered and passed along at runtime. |
name string |
The name of this error |
originalError (optional) string |
The original error received from the external system, if any |
solutions string[] |
A list of potential solutions for the error |
See a list of common errors on the Voice SDK Error Codes Page.
incoming Event
Emitted when an incoming Call
is received. An event listener will receive the Call
object representing the incoming Call
.
Listen for the 'incoming'
event.
const device = new Device(token);
device.on('incoming', call => {
// Do something
});
registered Event
Emitted when the Device
instance is registered and able to receive incoming calls.
Listen for the 'registered'
event.
const device = new Device(token);
device.on('registered', () => {
// Do something
});
registering Event
Emitted when the Device
instance is registering with Twilio to receive incoming calls.
Listen for the 'registering'
event.
const device = new Device(token);
device.on('registering', () => {
// Do something
});
tokenWillExpire Event
Emitted when the Device
instance's AccessToken is about to expire.
Use the refreshTokenMs
property on the DeviceOptions object to set a custom warning time. The default is 10 seconds (10000 milliseconds) prior to the AccessToken expiring.
Listen for the 'tokenWillExpire
' event.
You can use this event along with device.updateToken()
to automatically retrieve a new AccessToken and update the AccessToken on the Device instance, as shown in the example below:
device.on('tokenWillExpire', () => {
const token = getNewTokenViaAjax();
device.updateToken(token);
});
unregistered Event
Emitted when the Device
instance has unregistered with Twilio.
Listen for the 'unregistered'
event.
const device = new Device(token);
device.on('unregistered', () =>
// Do something
});
Accessors
device.audio
Return the AudioHelper
object used by the Device
instance. See the device.audio docs for more information.
device.calls
Returns an array of Call
s that this Device
instance is maintaining.
Modifying one of these calls will have the same affect as modifying the same Call as it was returned by device.on('incoming')
or device.connect()
.
const device = new Device(token);
// make an ougoing call
device.connect({ params: { To: "+15551234567" } });
console.log(device.calls);
// Prints:
// []
device.edge
Returns the Edge value the Device
instance is currently connected to. The value will be null when the Device
instance is offline.
const device = new Device(token);
device.on("registered", () => {
console.log(device.edge);
});
device.register();
// Prints:
// ashburn
device.home
Returns the home Twilio Region the Device
instance is connected to as a string. The value will be null
when the Device
instance is offline.
const device = new Device(token);
console.log(device.home);
// The default region for the JavaScript SDK is US-1
// Prints:
// 'us1'
device.identity
Returns the identity
string that is associated with the Device
instance's current AccessToken.
This accessor is only populated when the Device
instance has successfully registered with Twilio.
device.isBusy
Returns a Boolean for whether the Device
instance is currently on an active Call
const device = new Device(token);
console.log(device.isBusy);
// Prints:
// false
// make an outgoing call
device.connect({ params: { To: "+15551234567" });
console.log(device.isBusy);
// Prints:
// true
device.state
Returns the state of the Device
instance
const device = new Device(token);
console.log(device.state);
// Prints:
// unregistered
The possible Device
instance states are:
unregistered
- TheDevice
instance is not registered with Twilio and cannot accept incoming callsregistering
- TheDevice
instance is registering with Twilio to accept incoming callsregistered
- TheDevice
instance is registered with Twilio and can accept incoming callsdestroyed
- TheDevice
instance has been destroyed and will not be able to make or receive new calls
Use event listeners on the Device
instance to give the user feedback when the Device
instance's state changes. See the Best Practices Page for more information.
device.token
Returns the token used by this Device
instance
const device = new Device(token);
console.log(device.token);
// Prints:
// eyJhbGciOiJIUzI1NiIsInR5cCI6Ikp....
You can use the JWT debugger to decode and inspect the token.
Static Methods
Static methods should be called on the Device
global object provided by the SDK.
Device.runPreflight(token, options?)
Returns a PreflightTest
object representing a test call to Twilio which provides information to help troubleshoot call related issues.
Example:
const preflightTest = Device.runPreflight(token, options);
A Twilio.PreflightTest
object represents a test call to Twilio which provides information to help troubleshoot call related issues. You never instantiate it directly, but it's returned when you call Device.runPreflight(token, options)
.
See the PreflightTest Page for more information.
Static Properties
Static properties are those properties that only exist on the global Device
object.
Device.defaultMaxListeners
Use this to change the default maximum number of event listeners permitted on all instances of a Device
.
Device.defaultMaxListeners = 20;
If you need to change the maximum number of event listeners on a specific Device
instance, call the device.setMaxListeners(number)
method on that instance.
Note: device.setMaxListeners(number)
will have precedence over Device.defaultMaxListeners
.
Static Accessors
Static accessors should be called on the Device
global provided by the SDK.
Device.isSupported
Returns a Boolean for whether or not this SDK is supported by the current browser
console.log(Device.isSupported);
// Prints:
// true
Device.packageName
Returns the package name of the SDK
console.log(Device.packageName);
// Prints:
// @twilio/voice-sdk
Device.version
Returns the current SDK version
console.log(Device.version);
// Prints:
// 2.0.0
Need some help?
We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd by visiting Twilio's Stack Overflow Collective or browsing the Twilio tag on Stack Overflow.