Skip to contentSkip to navigationSkip to topbar
Rate this page:
On this page

Migrating to Voice JavaScript SDK 2.0


(information)

Info

This migration guide covers up to version 2.7.2. Please refer to the Voice JavaScript SDK: Changelog page for more details if you are upgrading to a newer version.


Benefits

The newest version of the SDK will always have the latest and greatest features, bug fixes, and security patches. We're always adding new capabilities - below is shortlist of notable investments we've made in versions 2.x.

New Features and Improvements

Modern design patterns

The SDK has been updated to use more modern design patterns. Library APIs now use Promises where asynchronous actions occur to help keep your code concise and clean. When registering for incoming calls or making an outgoing call, you can now use the returned Promise to keep your application UI up-to-date.

Support for modern Javascript frameworks

This feature was released with versions 2.6.0 and 2.7.0.

SDK Eventing

Twilio in-band websocket messaging. The SDK now supports the ability to send messages to and receive messages from backend services through the existing websocket connection.

This feature was released with version 2.2.0.

More descriptive errors

Older, more generic, error codes have been replaced with more descriptive error codes and objects.

VDI Support

The library now has support for VDI environments, such as Citrix HDX.

This feature was released with version 2.5.0.

Improved performance and security

Fixed memory leaks, removed MediaDevice polling, addressed security vulnerabilities, and removed deprecated dependencies.

This feature was released with version 2.6.1.


How can I import the new library into my project?

The library source is hosted in a new GitHub repository. The recommended way to install the module is through npm.

2.x versions of the Voice Javascript SDK are now published under @twilio/voice-sdk.

1.x versions of the Voice Javascript SDK are still available as twilio-client.

In the interest of promoting best practices, 2.0 and newer releases will not be uploaded to the Twilio CDN. Existing versions (prior to 2.0) and any further 1.x release will continue to be served via the CDN. However, we still strongly recommend not to link directly to these files in production as it introduces the potential for interruption due to CDN outages.

For customers currently using the CDN, there are a couple of options for switching:

  • If your project uses npm, install the latest version of @twilio/voice-sdk . From here, the built distribution files will be available under node_modules/@twilio/voice-sdk/dist .
  • If your project does not use npm, it's possible to download the latest built artifacts and serve it from your own servers. Each release will have its own tag on GitHub . Download the latest release (the newest tag without -rc ), unzip it, and navigate to /dist for the twilio.js and twilio.min.js files.

Breaking Changes

Updated DNS names

If your application uses Content Security Policies (CSP), they need to be updated along with other network configurations such as firewall rules, etc. to allow connections to the new DNS names and IP addresses.

Accurate naming

We've renamed the Connection class to Call. This shouldn't affect any public API; however, some internal method names have been updated. Therefore, any code accessing internal methods will break if not updated.

Removal of the Device singleton

As part of adapting to modern design patterns, the singleton behavior of Device has been removed.

If your code is similar to the following on 1.x:


_10
const device = Twilio.Device;

Your code on 2.x should create a Device like this:


_10
const device = new Device(token, deviceOptions);

Device instantiation

Create a new Device by invoking the constructor. The device.setup method is no longer supported.

If your code is similar to the following on 1.x:


_10
const device = Twilio.Device.setup(...);

Your code on 2.x should create a Device like this:


_10
const device = new Device(token, deviceOptions);

Updating Device configurations after constructing

Additionally, device.setup will no longer work for updating the Device instance after it has been created. Instead, use device.updateOptions(deviceOptions) to update any of the Device instance options.

Lazy signaling setup

The SDK now performs setup only when necessary, decreasing time to a ready application state and only making network connections when needed.

This means that the Device constructor is synchronous and will not cause a signaling channel to be opened. The signaling websocket will be opened when either:

  • device.register is invoked, which registers the Device instance to receive incoming calls.
  • device.connect is invoked, which places an outbound call.

If your application needs to monitor the Device instance registration status, the following events are emitted by the Device instance:

In the scenario such that you are making an outbound call and have not previously registered for inbound calls, you can invoke Call.status to observe the signaling connection status.

Keep the AccessToken up to date

The AccessToken can be updated with device.updateToken(accessToken: AccessToken).

Prior to registering for inbound calls with device.register() or making an outbound call with device.connect(), you can ensure that the AccessToken is valid by listening to the tokenWillExpireEvent.

The following is an example of how to use this feature:


_13
/**
_13
* This function would fetch an AccessToken from your backend services.
_13
*/
_13
async function getAccessToken(): string;
_13
_13
const token = await getAccessToken();
_13
const options = { ... };
_13
const device = new Device(token, options);
_13
_13
device.on(Device.EventName.TokenWillExpire, async () => {
_13
const newToken = await getAccessToken();
_13
device.updateToken(newToken);
_13
});

Device state

Device status has been removed and refactored as Device state. Note that we no longer represent busy as part of the Device state. You can check if the Device is busy by using the device.isBusy getter method. The ready status has been renamed to Device.State.Registered. The offline status has been renamed to Device.State.Unregistered. An important note is that ready and offline have always indicated registration status rather than signaling connection status. This change aims to clear up confusion.

Call options

The functions to accept an incoming call and make an outgoing call now have their parameters standardized. Please see Call.AcceptOptions and Device.ConnectOptions. Note that Device.ConnectOptions extends the Call.AcceptOptions type. Also note that the option types take MediaStreamConstraints as opposed to MediaTrackConstraints. Please see this resource for more information.

Error handling

Error reporting is now more descriptive. For backward compatibility, the existing error format is attached under the error.twilioError member of the new error objects.

Error codes

Some generic error codes have been replaced with more specific and precise error codes. See the following table for changed error codes.

Former Error CodeNew Error CodeError Description
3100353405Ice connection failure
3120131402Unable to acquire user media
3120831401User denies access to user media
3190153000Websocket timeout during preflight

Call ringing states

In a prior version, we included ringing states on Call, which were enabled behind the DeviceOptions property enableRingingState. We have removed this flag in 2.0, as it is now on by default.

For full functionality, this still requires setting answerOnBridge in your TwiML. However, even without answerOnBridge, the Call will go through the new ringing state briefly before transitioning to open. When answerOnBridge is enabled, the ringing state will begin when the recipient's phone begins ringing, and transition to open when they have answered and media is established.

Call 'cancel' event

This event is no longer raised in response to a local call.ignore(). Instead, it will only be raised when the remote end has canceled the call.


Device Options

Changes

A plus (+) sign denotes an addition to the SDK with 2.x.

A dash (-) denotes a removal from the SDK with 2.x.

audioConstraints


_10
-audioConstraints?: MediaTrackConstraints | boolean;

This functionality has been moved to device.connect and call.accept.

codecPreferences


_10
-codecPreferences?: Connection.Codec[];
_10
+codecPreferences?: Call.Codec[];

The functionality of this option remains the same, but the type has changed to reflect the Call class rename.

debug


_10
-debug?: boolean;

This functionality is now covered by the logLevel option.

enableIceRestart


_10
-enableIceRestart?: boolean;

This functionality is now enabled by default.

fakeLocalDTMF


_10
-fakeLocalDTMF?: boolean;

This functionality is now enabled by default.

enumerateDevices


_10
+enumerateDevices?: any;

This parameter enables VDI support.

getUserMedia


_10
+getUserMedia?: any;

This parameter enables VDI support.

logLevel


_10
+logLevel?: LogLevelDesc;
_10
_10
type LogLevelDesc =
_10
| 0 | 1 | 2 | 3 | 4 | 5
_10
| 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent'
_10
| 'TRACE' | 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'SILENT';

This parameter allows for finer control over logged messages. This option supersedes the functionality that Device.Options.debug and Device.Options.warnings used to provide in a standardized way.

region


_10
-region?: string;

Connecting by region name is deprecated. Please use edge.

rtcConfiguration


_10
-rtcConfiguration?: RTCConfiguration;

This functionality has been moved to device.connect and call.accept.

maxCallSignalingTimeoutMs


_10
+maxCallSignalingTimeoutMs?: number;

This parameter enables the new Signaling Reconnection feature.

RTCPeerConnection


_10
+RTCPeerConnection?: any;

This parameter enables VDI support.

warnings


_10
-warnings?: boolean;

This functionality is now covered by the logLevel option.

tokenRefreshMs


_10
+tokenRefreshMs?: number;

This parameter adjusts the event timing of the tokenWillExpire event.


Device Events

Changes

A plus (+) sign denotes an addition to the SDK with 2.x.

A dash (-) denotes a removal from the SDK with 2.x.

cancelEvent


_10
-cancelEvent(connection: Connection): void;

The device object will no longer emit a cancel event for canceled incoming calls. Instead, attach a listener to the Call.Event.Cancel event.

connectEvent


_10
-connectEvent(connection: Connection): void;

The device object will no longer emit a connect event when an outgoing call is established. Instead, use the return value from device.connect.

destroyedEvent


_10
+destroyedEvent(): void;

New API. Raised when the Device has been destroyed.

disconnectEvent


_10
-disconnectEvent(connection: Connection): void;

This functionality is now provided by Call.Event.Disconnect.

errorEvent


_10
-errorEvent(connection: Connection): void;
_10
+errorEvent(error: TwilioError, call?: Call): void;

The listener signature for this event has now changed. It will only emit a call as the second parameter when the error is call related, otherwise signaling errors are surfaced as the first parameter to this event.

incomingEvent


_10
-incomingEvent(connection: Connection): void;
_10
+incomingEvent(call: Call): void;

The functionality of this event has not changed, only the names of the parameters as the Connection class has been renamed to Call.

offlineEvent


_10
-offlineEvent(device: Device): void;
_10
+unregisteredEvent(): void;

This event has been renamed to Device.Event.Unregistered.

readyEvent


_10
-readyEvent(device: Device): void;
_10
+registeredEvent(): void;

This event has been renamed to Device.Event.Registered.

registeringEvent


_10
+registeringEvent(): void;

New API. Raised when the Device has started the registration process, in effect after Device.register has been invoked.

tokenWillExpireEvent


_10
+tokenWillExpireEvent(device: Device): void;

New API. Raised when the token passed to the Device is about to expire. The time interval of this event and when the token will actually expire is configurable, see Device.Options.tokenRefreshMs.


Device Properties

Changes

A plus (+) sign denotes an addition to the SDK with 2.x.

A dash (-) denotes a removal from the SDK with 2.x.

connections


_10
-connections: Connection[];
_10
+calls: Call[];

Renamed to reflect the class name change.

isInitialized


_10
-isInitialized: boolean;

The application code should observe the registration status of the Device, either through the registration events or Device.state.

sounds


_10
-readonly sounds: Partial<Record<Device.SoundName, (value?: boolean) => void>> = {};

Use Device.audio to access any sound related functionality.

constructor


_10
-constructor(): Device;
_10
-constructor(token: string, options?: Device.Options): Device;
_10
-constructor(token?: string, options?: Device.Options): Device;
_10
+constructor(token: string, options: Device.Options = {}): Device;

A Device can no longer be constructed without a token.

activeConnection


_10
-activeConnection(): Connection | null | undefined;

The application code should keep track of all calls made or received.

Event handler setters


_10
-cancel(handler: (connection: Connection) => any): this;
_10
-connect(handler: (connection: Connection) => any): this;
_10
-disconnect(handler: (connection: Connection) => any): this;
_10
-error(handler: (error: Connection) => any): this;
_10
-incoming(handler: (connection: Connection) => any): this;
_10
-offline(handler: (device: Device) => any): this;
_10
-ready(handler: (device: Device) => any): this;

Removed deprecated event handler setter methods.

connect


_10
-connect(params?: Record<string, string>, audioConstraints?: MediaTrackConstraints | boolean, rtcConfiguration?: RTCConfiguration): Connection;
_10
-connect(paramsOrHandler?: Record<string, string> | ((connection: Connection) => any), audioConstraints?: MediaTrackConstraints | boolean, rtcConfiguration?: RTCConfiguration): Connection | null;
_10
+async connect(options: Device.ConnectOptions = {}): Promise<Call>;

Consolidated all options into an options object parameter. See device.connect.

region


_10
-region(): string;

Connecting by region is deprecated. See Device.edge.

setup


_10
-setup(token: string, options: Device.Options = {}): this;

The Device is now lazily set up when making an outgoing call or registering for incoming calls.

status


_10
-status(): Device.Status;
_10
+get state(): Device.State;

Renamed. See device.state.

home


_10
+get home(): string | null;

New API.

identity


_10
+get identity(): string | null;

New API.

isBusy


_10
+get isBusy(): boolean;

New API.

registerPresence


_10
-registerPresence(): this;
_10
+async register(): Promise<void>;

Registration is an asynchronous action and the API now surfaces that with a Promise.

unregisterPresence


_10
-unregisterPresence(): this;
_10
+async unregister(): Promise<void>;

Unregistration is an asynchronous action and the API now surfaces that with a Promise.

updateOptions


_10
+updateOptions(options: Device.Options = {}): void;

New API to update the options of a device after the device has been constructed.


Call Properties

This class has been renamed from Connection to Call.

Changes

A plus (+) sign denotes an addition to the SDK with 2.x.

A dash (-) denotes a removal from the SDK with 2.x.

callerInfo


_10
-readonly callerInfo: Connection.CallerInfo | null;
_10
+readonly callerInfo: Call.CallerInfo | null;

The type annotation of this property has been changed to reflect the class name change.

direction


_10
-get direction(): Connection.CallDirection;
_10
+get direction(): Call.CallDirection;

The type annotation of the return value has been changed to reflect the class name change.

mediaStream


_10
-mediaStream: IPeerConnection;

Private class member, removed from public API. Instead, use the following APIs to get the MediaStream objects associated with a call.


_10
getLocalStream(): MediaStream | undefined;
_10
getRemoteStream(): MediaStream | undefined;

Event handler setters


_10
-accept(handler: (connection: this) => void): void;
_10
-disconnect(handler: (connection: this) => void): void;
_10
-cancel(handler: () => void): void;
_10
-error(handler: (error: Connection.Error) => void): void;
_10
-ignore(handler: () => void): void;
_10
-mute(handler: (isMuted: boolean, connection: this) => void): void;
_10
-reject(handler: () => void): void;
_10
-volume(handler: (inputVolume: number, outputVolume: number) => void): void;

Setting event handlers is now removed. Please use Call.on or Call.addListener.

accept


_10
-accept(audioConstraints?: MediaTrackConstraints | boolean, rtcConfiguration?: RTCConfiguration): void;
_10
+accept(options?: Call.AcceptOptions);

Call options have been consolidated into a single object parameter. See call.accept.

cancel


_10
-cancel(): void;

Removed deprecated API. To disconnect from an outgoing call at any time, use call.disconnect.

postFeedback


_10
-postFeedback(score?: Connection.FeedbackScore, issue?: Connection.FeedbackIssue): Promise<void>;
_10
+postFeedback(score?: Call.FeedbackScore, issue?: Call.FeedbackIssue): Promise<void>;

The functionality of this API remains intact. The method parameters have been renamed to reflect the Call class name change.

status


_10
-status(): Connection.State;
_10
+status(): Call.State;

The type of the return value has been renamed to reflect the Call class name change.

unmute


_10
-unmute(): void;

This deprecated API has been removed. Please use the following for the same effect.


_10
const call = device.connect();
_10
...
_10
call.mute(false); // unmutes the call


Rate this page: