Voice JavaScript SDK: Changelog
This is the Changelog for v2 of the Voice Javascript SDK. Click here to see the v1 Changelog.
If you are upgrading to version 2.3.0 or later and have firewall rules or network configuration that blocks any unknown traffic by default, you need to update your configuration to allow connections to the new DNS names and IP addresses. Please refer to this changelog for more details.
2.7.2 (September 21, 2023)
Changes
- Fixed an issue where audio in the Chrome browser is choppy when another application is also using the audio devices.
- Added missing documentation for the following events:
call.on('ringing', handler)
call.on('warning', handler)
call.on('warning-cleared', handler)
device.on('destroyed', handler)
2.7.1 (August 3, 2023)
Bug Fixes
- Fixed an issue where
call.sendMessage()
API throws an error if the SDK is imported as an ECMAScript Module (ESM) using the@twilio/voice-sdk/esm
path.
2.7.0 (August 1, 2023)
ECMAScript Module Support
Currently, the SDK is imported as a CommonJS Module (CJS) using the root path @twilio/voice-sdk
. With this release, the SDK contains an experimental feature that allows it to be imported as an ECMAScript Module (ESM) using the @twilio/voice-sdk/esm
path. As this is an experimental feature, some frameworks using bundlers like Vite
and Rollup
may not work. Full support for ESM will be available in a future release and will become the default import behavior of the SDK.
Example:
import { Device } from '@twilio/voice-sdk/esm';
2.6.1 (July 7, 2023)
Changes
- Fixed some security vulnerabilities shown by
npm audit
. - Removed unused dependencies.
- Replaced deprecated dependencies.
Bug Fixes
- Fixed an issue where calling
device.updateOptions
would reset thedevice.audio._enabledSounds
state. - Fixed an issue where custom DTMF sounds would not play. With this release, custom DTMF sounds should now play when configured during device initialization.
const device = new Device(token, {
sounds: {
dtmf8: 'http://mysite.com/8_button.mp3',
// Other custom sounds
},
// Other options
});
2.6.0 (June 20, 2023)
Changes
- The SDK now builds on NodeJS versions 16 and above without the
--legacy-peer-deps
flag. - Removed usage of NodeJS modules from the SDK and some dependencies. With this change, the SDK should now work with some of the latest frameworks that use the latest versions of bundlers such as Vite and Webpack.
- The AudioPlayer dependency has been incorporated into the SDK as part of a migration. This change fixes an issue where source maps are not properly loaded.
- Removed unnecessary files from the generated npm package.
- Links to source maps are now included in the generated npm package.
- The
ws
package has been moved todevDependencies
. - The SDK no longer depends on the
xmlhttprequest
npm package.
2.5.0 (May 9, 2023)
New Features
WebRTC API Overrides (Beta)
The SDK now allows you to override WebRTC APIs using the following options and events. If your environment supports WebRTC redirection, such as Citrix HDX's WebRTC redirection technologies, your application can use this new beta feature for improved audio quality in those environments.
2.4.0 (April 6, 2023)
Changes
-
Updated the description of Device.updateToken API. It is recommended to call this API after Device.tokenWillExpireEvent is emitted, and before or after a call to prevent a potential ~1s audio loss during the update process.
-
Updated stats reporting to stop using deprecated
RTCIceCandidateStats
-ip
anddeleted
.
Bug Fixes
-
Fixed an issue where a
TypeError
is thrown after rejecting a call then invokingupdateToken
. -
Fixed an issue (#87, #145) where the
PeerConnection
object is not properly disposed. -
Fixed an issue where
device.audio.disconnect
,device.audio.incoming
anddevice.audio.outgoing
do not have the correct type definitions. -
Fixed an issue where the internal
deviceinfochange
event is being emitted indefinitely, causing high cpu usage.
2.3.2 (February 27, 2023)
Bug Fixes
- Fixed an issue where a Twilio error is not returned when microphone access is blocked. Thank you @SiimMardus and @ostap0207 for your contribution.
2.3.1 (February 3, 2023)
Bug Fixes
- Fixed an issue where incoming sound will not stop playing after the call is disconnected. Thank you @kamalbennani for your contribution.
2.3.0 (January 23, 2023)
Changes
This release includes updated DNS names for Twilio Edge Locations. The Voice JS SDK uses these Edge Locations to connect to Twilio’s infrastructure via the parameter Device.Options.edge
. The current usage of this parameter does not change as the SDK automatically maps the edge value to the new DNS names.
Additionally, you need to update your Content Security Policies (CSP) if you have it enabled for your application. You also need to update your network configuration such as firewalls, if necessary, to allow connections to the new DNS names and IP addresses.
2.2.0 (December 5, 2022)
New Features
Call Message Events (Beta)
The SDK can now send and receive custom messages to and from Twilio's backend via the following new Call
APIs.
Please visit this page for more details about this feature. Additionally, please see the following for more information on how to send and receive messages on the server.
NOTE: This feature should not be used with PII.
Example
const device = new Device(token, options);
const setupCallHandlers = call => {
call.on('messageReceived', message => messageReceivedHandler(message));
call.on('messageSent', message => messageSentHandler(message));
};
// For outgoing calls
const call = await device.connect();
setupCallHandlers(call);
// For incoming calls
device.on('incoming', call => setupCallHandlers(call));
await device.register();
// For sending a message
const eventSid = call.sendMessage({
content: { foo: 'foo' },
messageType: Call.MessageType.UserDefinedMessage,
});
2.1.2 (October 26, 2022)
Bug Fixes
- Fixed an issue where insights data stops getting published after calling
device.updateOptions
.
2.1.1 (February 18, 2022)
Bug Fixes
- Ignoring a call will now properly stop the ringing sound
- NPM versioning has been fixed to specify >=12 rather than exactly 12
- Use DOMException instead of DOMError, which has been deprecated
- Removed npm util from the package, instead favoring native functions
2.1.0 (January 6, 2022)
New Features
Signaling reconnection support
The Voice JavaScript SDK now fully supports Call reconnection. If the media connection or signaling websocket is lost, the SDK is able to attempt to reconnect the Call. A Call can now potentially be recovered up to 30 seconds after a media or signaling connection loss.
The Twilio.Device
will emit a 'reconnecting' event when a connectivity loss occurs, and a 'reconnected' event upon successful reconnection.
There exists a limitation such that Signaling Reconnection and Edge Fallback are mutually exclusive. To opt-in to the Signaling Reconnection feature, a new option can be passed to the SDK: maxCallSignalingTimeoutMs
. If this value is not present in the options object passed to the Device
constructor, the default value will be 0
. Reconnection can only happen with an up-to-date AccessToken.
Customers relying on edge fallback, along with a small subset of customers using the 'roaming'
edge, will not automatically benefit from this feature without additional configuration. Go to the Edge Locations page for more information.
Keep AccessToken up to date with tokenWillExpire event and DeviceOptions.tokenWillExpire
The Voice JavaScript SDK now provides two additional features to help keep your AccessTokens up to date:
- The
'tokenWillExpire'
event, which will be emitted by the Twilio.Device before its associated AccessToken is set to expire. By default, it will be emitted 10 seconds before the AccessToken's expiration. - The
DeviceOptions.tokenRefreshMs
property that can configure the timing of the'tokenWillExpire'
event.
You can use these new features in conjunction with the device.updateToken()
method to automatically keep an AccessToken up to date.
In the following example, the 'tokenWillExpire'
event will be emitted 30 seconds (3000 milliseconds) before the AccessToken is set to expire, and the event listener for the 'tokenWillExpire'
event will retrieve a new AccessToken and update the Device's AccessToken with the device.updateToken()
method.
const device = new Device(token, {
// 'tokenWillExpire' event will be emitted 30 seconds before the AccessToken expires
tokenRefreshMs: 30000,
});
device.on('tokenWillExpire', () => {
return getTokenViaAjax().then(token => dev.updateToken(token));
});
Support for Twilio Regions
The Twilio Voice JavaScript SDK now supports Twilio Regions.
If you are part of the Twilio Regions Pilot and wish to specify a home region when using the Voice JavaScript SDK, you will need to:
- Create AccessTokens with API Keys and API Key Secrets that are stored in the specified Twilio Region, and include the Region name when creating the AccessToken. See example below.
- Use an edge location that matches your specified Region when instantiating your
Twilio.Device
.
Below is an example of how you would use the Node.js Helper Library to create AccessTokens for the Voice JavaScript SDK for a Region.
const accessToken = const accessToken = new twilio.jwt.AccessToken(
credentials.accountSid,
credentials.apiKeySid,
credentials.apiKeySecret, {
identity,
ttl,
region: 'au1',
},
);
const grant = new VoiceGrant({
outgoingApplicationSid: credentials.twimlAppSid,
incomingAllow: true,
});
accessToken.addGrant(grant);
Note: The API Key and Secret above must be created within the au1
region. It's recommended that the TwiML App used in the Voice Grant is also created in the same Region.
The example below shows how to pass the au1
-related edge location to the Twilio.Device
constructor.
const device = new Device(accessToken, {
edge: 'sydney',
});
The new Twilio.Device.home
accessor will return a string value of the home region of the device instance, given that it successfully connected with Twilio.
Existing EU customers can now migrate their Voice use-cases to the data center in Ireland to establish data residency within the region. In addition, new customers may now select Ireland as their region of choice for Voice related use cases. There is no additional cost to use the new data center in Ireland. To learn more about Regional Voice in Ireland, check out our blog post or head over to our Global Infrastructure docs to get started.
Device.identity
The Voice JavaScript SDK now exposes a Twilio.Device.identity
accessor.
Given that a Twilio.Device
has registered successfully with Twilio, the Twilio.Device.identity
accessor will return a read-only string containing the identity
that was passed to the AccessToken used to instantiate the Twilio.Device
.
Fixes
- Updated
ws
version to fix a potential security vulnerability - All event listeners will now be properly cleaned up after calling
Twilio.Device.destroy()
- When Insights fails to post an event, the SDK now logs a warning rather than an Uncaught Promise Rejection
2.0.0 (July 9, 2021)
Breaking API Changes
Device singleton behavior removed
Device must now be instantiated before it can be used. Calling Device.setup()
will no longer
work; instead, a new Device
must be instantiated via new Device(token, options?)
.
Connection renamed to Call
As Connection is an overloaded and ambiguous term, the class has been renamed Call to better indicate what the object represents and be more consistent with Mobile SDKs and our REST APIs.
Signaling connection now lazy loaded
Device.setup()
has been removed, and new Device(...)
will not automatically begin
connecting to signaling. There is no need to listen for Device.on('ready')
. Instead,
the signaling connection will automatically be acquired in one of two scenarios:
- The application calls
Device.connect()
, creating an outbound Call. In this case, the state of the signaling connection will be represented in the Call. - The application calls
Device.register()
, which will register the client to listen for incoming calls at the identity specified in the AccessToken.
Note on token expiration
As long as outgoing calls are expected to be made, or incoming calls are expected to be received,
the token supplied to Device
should be fresh and not expired. This can be done by setting a
timer in the application to call updateToken
with the new token shortly before the prior
token expires. This is important, because signaling connection is lazy loaded and will fail if
the token is not valid at the time of creation.
Example:
const TTL = 600000; // Assuming our endpoint issues tokens for 600 seconds (10 minutes)
const REFRESH_TIMER = TTL - 30000; // We update our token 30 seconds before expiration;
const interval = setInterval(async () => {
const newToken = await getNewTokenViaAjax();
device.updateToken(newToken);
}, REFRESH_TIMER);
Device states changed
The Device states have changed. The states were: [Ready, Busy, Offline]
. These
have been changed to more accurately and clearly represent the states of the
Device. There are two changes to Device state:
1. The states themselves have changed to [Registered, Registering, Unregistered, Destroyed]
. This
removes the idea of "Busy" from the state, as technically the Device can have an active
Call whether it is registered or not, depending on the use case. The Device will always
starty as Unregistered
. In this state, it can still make outbound Calls. Once Device.register()
has been called, this state will change to Registering
and finally Registered
. If
Device.unregister()
is called the state will revert to Unregistered
. If the signaling
connection is lost, the state will transition to Registering
or `Unregistered' depending
on whether or not the connection can be re-established.
The destroyed
state represents a Device
that has been "destroyed" by calling
Device.destroy
. The device should be considered unusable at this point and a
new one should be constructed for further use.
- The busy state has been moved to a boolean,
Device.isBusy
. This is a very basic shortcut for the logicreturn !!device.activeConnection
.
Device events changed
The events emitted by the Device
are represented by the Device.EventName
enum and represent the new Device states:
export enum EventName {
Destroyed = 'destroyed',
Error = 'error',
Incoming = 'incoming',
Unregistered = 'unregistered',
Registering = 'registering',
Registered = 'registered',
}
Note that unregistered
, registering
, and registered
have replaced
offline
and ready
. Although frequently used to represent connected or disconnected,
ready
and offline
actually were meant to represent registered
and unregistered
,
which was quite ambiguous and a primary reason for the change.
When the device is destroyed using Device.destroy
, a "destroyed"
event will
be emitted.
Device usage changes
The construction signature and usage of Device
has changed. These are the new API signatures:
/**
* Create a new Device. This is synchronous and will not open a signaling socket immediately.
*/
new Device(token: string, options?: Device.Options): Device;
/**
* Promise resolves when the Device has successfully registered.
* Replaces Device.registerPresence()
* Can reject if the Device is unusable, i.e. "destroyed".
*/
async Device.register(): Promise<void>;
/**
* Promise resolves when the Device has successfully unregistered.
* Replaces Device.unregisterPresence()
* Can reject if the Device is unusable, i.e. "destroyed".
*/
async Device.unregister(): Promise<void>;
/**
* Promise resolves when signaling is established and a Call has been created.
* Can reject if the Device is unusable, i.e. "destroyed".
*/
async Device.connect(options?: Device.ConnectOptions): Promise<Call>;
Listening for incoming calls:
const device = new Device(token, { edge: 'ashburn' });
device.on(Device.EventName.Incoming, call => { /* use `call` here */ });
await device.register();
Making an outgoing call:
const device = new Device(token, { edge: 'ashburn' });
const call = await device.connect({ To: 'alice' });
Device CallOptions and Call AcceptOptions standardized
The arguments for Device.connect()
and Call.accept()
have been standardized
to the following options objects:
interface Call.AcceptOptions {
/**
* An RTCConfiguration to pass to the RTCPeerConnection constructor.
*/
rtcConfiguration?: RTCConfiguration;
/**
* MediaStreamConstraints to pass to getUserMedia when making or accepting a Call.
*/
rtcConstraints?: MediaStreamConstraints;
}
interface Device.ConnectOptions extends Call.AcceptOptions {
/**
* A flat object containing key:value pairs to be sent to the TwiML app.
*/
params?: Record<string, string>;
}
Note that these now take a MediaStreamConstraints rather than just the audio constraints. For example:
device.connect({ To: 'client:alice' }, { deviceId: 'default' });
might be re-written as:
device.connect({
params: { To: 'client:alice' },
rtcConstraints: { audio: { deviceId: 'default' } },
});
Moved to new Error format
For backward compatibility, the new error format was attached to the old format under error.twilioError
:
class oldError extends Error {
//...
code: number;
message: string;
twilioError: TwilioError;
}
The new Error format is:
class TwilioError extends Error {
/**
* A list of possible causes for the Error.
*/
causes: string[];
/**
* The numerical code associated with this Error.
*/
code: number;
/**
* A description of what the Error means.
*/
description: string;
/**
* An explanation of when the Error may be observed.
*/
explanation: string;
/**
* Any further information discovered and passed along at run-time.
*/
message: string;
/**
* The name of this Error.
*/
name: string;
/**
* The original Error received from the external system, if any.
*/
originalError?: Error;
/**
* A list of potential solutions for the Error.
*/
solutions: string[];
}
Affected Error Codes
With the transition, the following error codes have changed: - 31003 -> 53405 | When ICE connection fails - 31201 -> 31402 | When getting user media fails - 31208 -> 31401 | When user denies access to user media - 31901 -> 53000 | When websocket times out in preflight
New Features
Device Options
Previously, Device.setup()
could only be used the set options once. Now, we've added
Device.updateOptions(options: Device.Options)
which will allow changing
the Device options without instantiating a new Device. Note that the edge
cannot be changed
during an active Call.
Example usage:
const options = { edge: 'ashburn' };
const device = new Device(token, options);
// Later...
device.updateOptions({ allowIncomingWhileBusy: true });
The resulting (non-default) options would now be:
{
allowIncomingWhileBusy: true,
edge: 'ashburn',
}
This function will throw with an InvalidStateError
if the Device has been
destroyed beforehand.
LogLevel Module
The SDK now uses the loglevel
module. This exposes
several new features for the SDK, including the ability to intercept log messages with custom
handlers and the ability to set logging levels after instantiating a Device
. To get an instance
of the loglevel
Logger
class used internally by the SDK:
import { Logger as TwilioClientLogger } from '@twilio/voice-client-sdk';
...
TwilioClientLogger.setLogLevel('DEBUG');
Please see the original loglevel
project for more
documentation on usage.
Deprecations
Connection Deprecations
- Removed
Connection.mediaStream
. To access the MediaStreams, useConnection.getRemoteStream()
andConnection.getLocalStream()
- Removed
Connection.message
in favor of the newerConnection.customParameters
. Where.message
was an Object,.customParameters
is aMap
. - Removed the following private members from the public interface:
Connection.options
Connection.pstream
Connection.sendHangup
- Fixed
Connection.on('cancel')
logic so that we no longer emitcancel
in response toConnection.ignore()
.
Device Option Deprecations
Some deprecated Device
options have been removed. This includes:
enableIceRestart
enableRingingState
fakeLocalDtmf
The above three removed options are now assumed true
. The new Device.Options
interface is now:
export interface Options {
allowIncomingWhileBusy?: boolean;
appName?: string;
appVersion?: string;
audioConstraints?: MediaTrackConstraints | boolean;
closeProtection?: boolean | string;
codecPreferences?: Connection.Codec[];
disableAudioContextSounds?: boolean;
dscp?: boolean;
edge?: string[] | string;
forceAggressiveIceNomination?: boolean;
maxAverageBitrate?: number;
rtcConfiguration?: RTCConfiguration;
sounds?: Partial<Record<Device.SoundName, string>>;
}
Fixes
MOS Calculation Formula
The formula used to calculate the mean-opinion score (MOS) has been fixed for extreme network conditions. These fixes will not affect scores for nominal network conditions.
1.15.0 (Feb 28, 2023)
New Features
WebRTC API Overrides (Beta)
The SDK now allows you to override WebRTC APIs using the following options and events. If your environment supports WebRTC redirection, such as Citrix HDX's WebRTC redirection technologies, your application can use this new beta feature for improved audio quality in those environments.
Device.Options.enumerateDevices
- Overrides the nativeMediaDevices.enumerateDevices
API.Device.Options.getUserMedia
- Overrides the nativeMediaDevices.getUserMedia
API.Device.Options.RTCPeerConnection
- Overrides the nativeRTCPeerConnection
class.connection.on('audio', handler(remoteAudio))
- Emitted after theHTMLAudioElement
for the remote audio is created.
Known Issues
- Volume levels currently report as zero and do not reflect the actual volume levels of the call. This issue does not affect the quality of the call but, might affect application behavior if you rely on these values.
- Only inbound calls are currently supported. Outbound calls will be available in a future release.
- Using
Device.audio.speakerDevices
andDevice.audio.setInputDevice
will not properly switch speaker and microphone devices. You need to recreate theDevice
object or refresh the page when the default microphone or speaker device is changed.
1.14.0 (Jan 27, 2021)
New Features
Allow Connection specific ICE Servers
Developers can now opt to override rtcConfiguration
set within Device.options
per specific outgoing and incoming Connection
s.
To use this feature, a new parameter rtcConfiguration
can be passed to Device.connect
and Connection.accept
. The function signatures are now described as below.
Device.connect(params?: Record<string, string>,
audioConstraints?: MediaTrackConstraints | boolean,
rtcConfiguration?: RTCConfiguration);
Connection.accept(audioConstraints?: MediaTrackConstraints | boolean,
rtcConfiguration?: RTCConfiguration);
Passing the rtcConfiguration
parameter to these functions will override any previously set rtcConfiguration
within Device.options
but not affect any other members set within Device.options
.
1.13.1 (Jan 11, 2021)
Additions
- Added support for Tokyo and Sydney interconnect locations. These edges can be used by interconnect customers by specifying
{ edge: 'sydney-ix' }
or{ edge: tokyo-ix' }
inDevice.setup()
ornew Device()
options.
1.13.0 (Nov 11, 2020)
1.13.0-beta2 has been promoted to 1.13.0 GA. Here’s a summary of what’s new in 1.13.0.
New Features
Voice diagnostics using runPreflight API
The SDK now supports a preflight test API which can help determine Voice calling readiness. The API creates a test call and will provide information to help troubleshoot call related issues. Please see the following for more details.
Connection warning data
Connection.on('warning') now provides data associated with the warning. This data can provide more details about the warning such as thresholds and WebRTC samples collected that caused the warning. The example below is a warning for high jitter. Please see Voice Insights SDK Events Reference for a list of possible warnings.
connection.on('warning', (warningName, warningData) => {
console.log({ warningName, warningData });
});
Example output:
{
"warningName": "high-jitter",
"warningData": {
"name": "jitter",
/**
* Array of jitter values in the past 5 samples that triggered the warning
*/
"values": [35, 44, 31, 32, 32],
/**
* Array of samples collected that triggered the warning.
* See sample object format here https://www.twilio.com/docs/voice/client/javascript/connection#sample
*/
"samples": [...],
/**
* The threshold configuration.
* In this example, high-jitter warning will be raised if the value exceeded more than 30
*/
"threshold": {
"name": "max",
"value": 30
}
}
}
Also in this release
-
Added
high-packets-lost-fraction
network warning. This new warning is raised when the average of the most recent seven seconds of packet-loss samples is greater than3%
. When the average packet-loss over the most recent seven seconds is less than or equal to1%
, then the warning is cleared. -
The behavior for raising the
constant-audio-level
warning has been updated. Now, the most recent ten seconds of volume values are recorded and then analyzed. If the standard deviation of these samples is less than 1% of the maximum audio value, then the warning is raised. When the standard deviation is greater than 1% and the warning has already been raised, then the warning is cleared. -
We now log an
outgoing
event to Insights when making an outbound call. This event also contains information whether the call is a preflight or not. -
Added a boolean field to the signaling payload for calls initiated by
Device.runPreflight
for debugging purposes.
1.12.5 (Sept 22, 2020)
Bug Fixes
- Fixed an issue introduced in Safari 13.1 that caused calls to continue playing after navigating away from the page.
- Fixed an issue where the disconnect sound plays after the caller cancelled the incoming call.
1.12.4 (Sept 4, 2020)
Bug Fixes
- Fixed an issue where an error is thrown if
Device
is imported and run in a NodeJS environment.
Changes
- The twilio.js SDK no longer supports the deprecated Edge Legacy browsers that rely on ORTC. See our deprecation notice for more details.
1.12.3 (August 14, 2020)
Changes
- We now log the selected ICE candidate pair to Insights. This will help with isolating issues should they arise.
- Fixed an issue where the transportClose event listener was not being cleaned up appropriately when a Connection is closed, causing MaxListenersExceededWarning on the console.
1.12.2 (August 6, 2020)
Bug Fixes
- Fixed an issue where calls on Safari 13.1.2 will intermittently fail and raise a 31003 error when establishing media connection. This usually happens when receiving or initiating the call.
1.12.1 (June 29, 2020)
Bug Fixes
- Fixed an issue where a
device.on('disconnect')
is emitted before raising adevice.on('cancel')
event. This usually happens when the caller cancels the incoming call before the SDK accepts it. - Fixed an issue where
sao-paolo
is expected as an edge name instead ofsao-paulo
.
1.12.0 (June 11, 2020)
New Features
SHAKEN/STIR Verification Status for incoming calls
Twilio Client's Connection class now has Connection.callerInfo.isVerified
, that can be used to display a trust indicator to the recipient when an incoming call, say from the public telephone network, has been verified under the SHAKEN/STIR framework.
A verified call that has been given highest attestation under SHAKEN/STIR means that the carrier that originated the call both (1) knows the identity of the caller, and (2) knows the caller has the right to use the phone number as the caller ID.
When your application receives a request webhook, that has the new StirStatus
parameter all you have to do is <Dial><Client>
and Twilio will implicitly pass the StirStatus
to the Javascript Client.
CallerInfo
The Connection.callerInfo
field returns caller verification information about the caller. If no caller verification information is available this will return null
.
class Connection {
// ...
callerInfo: CallerInfo | null;
}
A CallerInfo provides caller verification information.
interface CallerInfo {
isVerified: boolean;
}
Attributes
isVerified
- Whether or not the caller's phone number has been attested by the originating carrier and verified by Twilio using SHAKEN/STIR. True if the caller has been verified at highest attestation 'A', false if the caller has been attested at any lower level or verification has failed.
Example
device.on('incoming', connection => {
if (connection.callerInfo && connection.callerInfo.isVerified) {
console.log('This caller is verified by a carrier under the SHAKEN and STIR call authentication framework');
}
});
Read here to learn more about making and receiving SHAKEN/STIR calls to/from the public telephone network.
1.11.0 (May 21, 2020)
New Features
Twilio Edge Locations
This release includes support for the expansion of Twilio’s Global Infrastructure via Edge Locations which allows connectivity control into and out of Twilio’s platform. The Voice Client JS SDK uses these Edges to connect to Twilio’s infrastructure via the new parameter Twilio.Device.Options.edge
. This new parameter supersedes the now deprecated Twilio.Device.Options.region
. See Twilio.Device.Options.edge
API documentation for migration instructions.
Example
const device = new Device(token, { edge: 'ashburn' });
Support for automatic Edge location Fallback (Beta)
Deployments designed to connect to multiple Twilio Edge locations can take advantage of the new fallback mechanism. To enable the edge fallback, specify an array of edge names via Twilio.Device.Options.edge
. When enabled and a connection failure is encountered, the SDK will reattempt the connection to the next region in the list. For more details about how the fallback works, refer to Edge Fallback documentation.
Example
const device = new Device(token, { edge: ['ashburn-ix', 'san-jose-ix', 'roaming' ] });
Application Name and Version Logging Support
This release also introduces two new Device
options: appName
and appVersion
. The values will be logged to Insights. These can be used to correlate other insights events with the application generating them. This is useful for debugging purposes in cases where multiple versions are deployed e.g. When performing A/B testing.
Deprecations
Support for Microsoft Edge Legacy is now deprecated. Running device.setup()
on this browser will result with the console warning below. See this advisory for more information about important upcoming breaking changes with Microsoft Edge Legacy.
Microsoft Edge Legacy (https://support.microsoft.com/en-us/help/4533505/what-is-microsoft-edge-legacy)
is deprecated and will not be able to connect to Twilio to make or receive calls after September 1st, 2020.
Please see this documentation for a list of supported browsers
https://www.twilio.com/docs/voice/client/javascript#supported-browsers
1.10.3 (Apr 29, 2020)
Bug Fixes
- Fixed an issue where
rtcSample.rtt
raised byConnection.on('sample', rtcSample => ...)
was reported in seconds instead of milliseconds on Firefox and Chrome 81+. If your application convertsrtcSample.rtt
to milliseconds on these browsers, please remove the conversion. - Fixed an issue where, in rare cases, call insights were generated after a call was disconnected.
1.10.2 (Apr 22, 2020)
Bug Fixes
- Fixed an issue where an Angular project will not build when the SDK is used as a npm module.
Also with this release, we addressed an issue where certain device event handlers, when an exception is thrown, causes some connection event handlers to stop working. This causes potential side effects such as incoming ringtone not being able to stop after receiving a call.
Example
In the following example, connection.on('accept')
will not trigger if device.on('connect')
throws an error. With this fix, connection.on('accept')
handler should now receive the event.
connection.on('accept', () => {
console.log('This is my "accept" handler.');
});
device.on('connect', () => {
throw 'Something went wrong.';
});
Events affected
The following are the events affected and should be fixed with this release.
Device Events | Affected Connection Events |
---|---|
device.on('connect') | connection.on('accept') |
device.on('error') | connection.on('error') |
device.on('cancel') | connection.on('cancel') |
device.on('disconnect') | connection.on('disconnect') |
More information about NodeJS Events
As mentioned in our public documentation, the Device and Connection objects are EventEmitters. This release doesn't change the default behavior of EventEmitters
, where if one of the handlers on the same EventEmitter
object throws an exception, the rest of the event handlers will not receive the event. Consider the following example.
const myEmitter = new EventEmitter();
// Subscribe some event handlers
myEmitter.on('testevent', () => console.log('This is my handler 1'));
myEmitter.on('testevent', () => {
console.log('This is my handler 2');
throw 'Something went wrong';
});
myEmitter.on('testevent', () => console.log('This is my handler 3'));
// Emit an event
myEmitter.emit('testevent');
In the above example, testevent
has three handlers and are on the same EventEmitter object myEmitter
. If one of the handlers, in this case handler number 2, throws an error, the rest of the event handlers will not receive the event. In this case, handler 3 will not receive testevent
. This is a normal behavior on EventEmitters
and this SDK release doesn't change this behavior. This release only fixes the issue where if the events are coming from two different EventEmitter
objects - Connection
and Device
.
1.10.1 (Apr 6, 2020)
Improvements
Typescript declarations are now included with our NPM package. In the following example, Device
, Connection
, and their functions should have the correct typings.
import { Device, Connection } from 'twilio-client';
const token = ...;
const deviceOptions = ...;
const device: Device = new Device(token, deviceOptions);
const connection: Connection = device.connect(...);
...
connection.disconnect();
Bug Fixes
- Fixed an issue where
Device.on('incoming')
event is not raised when the incoming sound is stopped right after playing it. This is a timing issue which can happen if multiple incoming connections comes in almost at the same time. - Fixed an issue causing Android chrome to throw the error
This browser does not support audio output selection
. We now check if this is supported on the browser before attempting to update the output device.
1.10.0 (Feb 19, 2020)
Improvements
Added the ability to access the SDK logger instance using the loglevel npm module. Please refer to the loglevel documentation for a list of logger APIs.
For example, to set the log level:
import { getLogger } from 'loglevel';
const logger = getLogger(Device.packageName);
// Set log level on subsequent page loads and refreshes
logger.setLevel('DEBUG');
Also in 1.10.0
- https://sdk.twilio.com is now being used for serving the sound files. You may need to update your firewall rules and allow list AWS CloudFront IPs. Please refer to AWS IP address ranges documentation for more details.
- Updated npm dependencies to support node version 12.
- We now log RTCDtlsTransport state changes to Insights. This will help with isolating issues should they arise.
1.9.7 (Dec 6, 2019)
Added an experimental feature for Chrome browser to enable
Aggressive ICE Candidate Nomination. This feature can be enabled by setting forceAggressiveIceNomination
to true. If your deployment is on devices with one network interface and your 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.
Example:
Device.setup(TOKEN, {
forceAggressiveIceNomination: true
});
1.9.6 (Nov 22, 2019)
Improvements
- New improvements to media reconnection. ICE restart is now also requested when ICE gathering fails (transitions to complete and no ICE candidates were gathered), or ICE gathering exceeds 15 seconds and no ICE candidates were gathered.
- Locally gathered ICE candidates are now logged for debugging purposes.
1.9.5 (Nov 5, 2019)
Improvements
- You can now connect to our interconnect region in Singapore by setting the region option to
sg1-ix
. See Twilio Client Regions for the list of supported regions. Note that with this release, to support new regions without requiring an SDK update, we have removed the check for the region name passed toDevice.setup
. If an unsupported region is supplied,Device.on('error')
will be called. - We now log PeerConnection state changes to Insights. This will help with isolating issues should they arise.
1.9.4 (Oct 28, 2019)
Improvements
- We now report
audioInputLevel
andaudioOutputLevel
within the last second in the connection sample objectConnection.on('sample', handler(sample))
.
Bug Fixes
- Update querystring to clear cached audio files without CORS headers.
- Fixed an issue where
constant-audio-input-level
warning is not being emitted.
1.9.3 (Oct 15, 2019)
Bug Fixes
- Fixed an issue where audio files sometimes shows CORS errors on the console.
1.9.2 (Oct 3, 2019)
Bug Fixes
- Fixed an issue on Safari where
sample.mos
, emitted fromConnection.on('sample', handler(sample))
, is always null.
1.9.1 (Sept 13, 2019)
Improvements
- The Device sounds are now cached. They are only downloaded when
Device.setup()
is invoked.
1.9.0 (Sept 10, 2019)
New Features
Max Average Bandwidth API
By default, the Opus codec is set up with a transmission rate of around 32 kbps (40-50kbps on the wire). With this release, you are able to set a custom max average bitrate to better control how much bandwidth your VoIP application should use. See RFC-7587 section 7.1 for information about Max Average Bitrate.
The main purpose of this API is to set a lower max average bitrate to minimise bandwidth usage. This is particularly useful in deployments where bandwidth is at a premium. Where bandwidth is not of concern, you do not need to use this API. Max Average Bitrate can be set to as low as 6,000bps and as high as 51,000 bps. Values outside this range are ignored and the default Opus operation mode is used. See API Docs for more information.
As would be expected, lowering the max average bitrate impacts audio quality. We don’t recommend setting max average bitrate to a value below 8,000 bps. On the other hand, setting values over 32,000 bps will have negligible audio quality improvements.
This is currently not supported in Firefox due to this bug.
Example, to set a new max average bitrate to 16,000 bps:
Device.setup(TOKEN, {
codecPreferences: ['opus', 'pcmu'],
maxAverageBitrate: 16000,
});
Bug Fixes
- Fixed an issue causing multiple devices that are created in the same tab to get disconnected when one of the devices disconnects a connection.
1.8.1 (Aug 28, 2019)
Bug Fixes
-
Fixed an issue causing audio levels to be reported as zero when running as an extension, or when the browser tab is inactive or minimized.
-
Fixed an issue causing
Connection.status()
to returnpending
instead ofclosed
after callingConnection.reject()
.
1.8.0 (Aug 20, 2019)
New Features
Media Reconnection States and Events
This feature, when enableIceRestart
is enabled, allows for detecting when media connection fails which will trigger automatic media reconnection, and for detecting when media connection is restored.
New Events
We've added two new events that will fire when enableIceRestart
is enabled:
Connection.on('reconnecting', handler(error))
- raised when media connection fails and automatic reconnection has been started by issuing ICE Restarts. During this period,Connection.status()
will be set toreconnecting
.error
- Error object{ code: 53405, message: 'Media connection failed.' }
- Media reconnection triggers
- ICE Connection state transitions to
disconnect
and bytes sent and received in the last 3 seconds is zero. - ICE Connection state or PeerConnection state transitions to
failed
. Only Chrome browser will attempt an ICE restart with this trigger. Other browsers will immediately disconnect the call and raise an error31003
. This is due to browsers not fully supporting connection states during an ICE restart.
- ICE Connection state transitions to
Connection.on('reconnected', handler())
- raised when media connection has been restored which is detected when media starts flowing. Once reconnected,Connection.status()
will be set toopen
.
Retries
ICE restarts will be retried in the event that previous ICE restarts are unsuccessful. Retry attempts will happen when ICE Connection state or PeerConnection state transitions to failed
. If more than 30 seconds has elapsed during this transition, the call will disconnect and raise an error 31003
.
Improvements
- Added de1-ix to valid list of regions.
- Added
Device.version
to return sdk version - When applicable, errors emitted through Device.on('error') and Connection.on('error') now contain a twilioError field, providing more information about the error. This twilioError represents the new TwilioError format that will become the default Error format in 2.0.
// Error object
{
code: number,
message: string,
...
// New twilioError property
twilioError: {
causes: Array<string>,
code: number,
description: string,
explanation: string,
solutions: Array<string>,
message: string,
stack: string
}
}
Bug Fixes
- Fixed an issue causing local environment information to get bundled into the build artifact in local npm builds.
- Fixed an issue where ringing will not stop when network is disconnected.
1.7.7 (Sept 25, 2019)
Improvements
- Added de1-ix to valid list of regions.
Bug Fixes
- Fixed an issue causing local environment information to get bundled into the build artifact in local npm builds.
1.7.6 (Jul 23, 2019)
New Features
Automatic Media Reconnection
This feature was first introduced in 1.7.4 and was enabled by default.
With this release, we have introduced the enableIceRestart
reconnect flag to enable or disable Automatic Media Reconnection. The default is disabled. This will allow you to transition your code to utilise this feature. Example usage:
Twilio.Device.setup(TOKEN, { enableIceRestart: true });
Improvements
- We now show a more descriptive error in the console if WebRTC support isn't detected when not loaded over https.
Bug Fixes
- Fixed an issue where active connection was getting disconnected when the token expired.
- Fixed an issue where an answer during ICE reconnection was applied without a valid offer, resulting in the console error:
Failed to set remote answer sdp: Called in wrong state: kStable
.
1.7.5 (July 5, 2019)
Improvements
- Checking whether plan-b or unified-plan is default on the browser now happens on Device.setup() or on device initialization with a token, instead of on page load. This offloads creation of an RTCPeerConnection until we know Device will actually be used on the page.
Bug Fixes
- Fixed an issue where ICE restarts would continue to retry when a call got disconnected while ringing.
Device.destroy()
now properly disconnects all connections.- Fixed an issue where an answer was applied multiple times after creating an offer, causing console errors.
- Fixed an issue where low-bytes warning was raised if total bytes sent and received was zero or not supported, potentially causing some issues in Edge preventing audio from being heard after an ICE restart.
- Fixed an issue where ICE restart would not stop when connection drops on Firefox, causing console errors.
Known Issues
Updated July 16, 2019
The introduction of Automatic Media Reconnection in 1.7.4 is enabled by default. This functionality may affect program flow if you rely on Device.on('error', ...) with error code 31003 to update your UI or reconnect logic. This error is not thrown at the time of media interruption any longer. It is now sent after ICE restart is attempted and fails which may take 10s of seconds.
1.7.4 (June 21, 2019)
New Features
Automatic Media Reconnection
A call may be inadvertently disconnected when media is temporarily lost. With this release, we will attempt to reconnect the media before dropping the call with a process known as ICE restart.
If you are relying on Device.on('error', ...) with error code 31003, to update your UI or to initiate a reconnect, you will need to update your code to use Device.on('offline', ...) instead. The 31003 error code may not be reported for some time as ICE restarts are continually attempted.
Updated July 16, 2019
We have identified this as a potential breaking change and we will include an opt-in feature switch in the 1.7.6 release. We apologize for any inconvenience this may have caused you.
Improvements
- ICE Connections will now attempt to reconnect when they transition to the
failed
state, rather than immediately disconnecting. - We now report bytesSent and bytesReceived within the last second in the webrtc sample object (
RTCSample
). - We now begin monitoring for warnings 5 seconds after the start of a call (originally at 20 seconds).
Bug Fixes
- Fixed a bug where changing the input device then later calling
Connection.mute()
will not work. - Fixed a bug causing some signaling errors to not trigger an error event from Connection.
Known Issues
The following known issues will be addressed in an upcoming 1.7.5 release:
- ICE restarts may continue after successfully reconnecting, or a call has ended. This is benign, but may cause errors to be visible in the browser console.
- ICE restarts may begin after 5 seconds in Edge 42, causing audio loss for the local client. This does not affect Edge 44.
1.7.3 (May 16, 2019)
Improvements
- We now report audio codec and whether DSCP is enabled to Insights Metrics.
- Added new getter on Connection,
Connection.codec
, which will be populated with the audio codec used in the call as soon as the SDK receives that information from WebRTC. We currently do not get the audio code from FireFox. - We now emit a webrtc sample object (
RTCSample
) every second through a new event,Connection.on('sample')
.
Bug Fixes
- Fixed a bug causing the input stream to not be released after a Connection is created without calling
Device.audio.setInputDevice
and then later callingDevice.audio.setInputDevice
during the call when using a browser that supports the unified-plan SDP semantic. - Fixed an issue where audio ring tone plays on a different output device after reconnecting an external output device.
1.7.2 (May 3, 2019)
Bug Fixes
- Fixed an issue where some audio resources weren't being released after a call. Thank you to 西口瑛一(Eiichi Nishiguchi) 土橋雅一(Masakazu Tsuchihashi) and Leverages Co., Ltd. for helping us isolate this issue.
1.7.1 (Apr 29, 2019)
Unified Plan support
- Added support for Unified Plan.
- With this version, twilio-client.js uses the browser's default SDP format. Unified Plan SDP format is the default format used by Google Chrome 72+, Safari 12.2+, and Firefox since forever.
- Note If you are using twilio-client.js versions 1.7.0 or older, changing audio input devices during a call will break on Safari 12.2 onwards.
- See this advisory for SDP format migration impact.
Improvements
Updated the algorithm used to report the "Audio input level" and "Audio output level" Insight metrics. The levels are obtained directly from an AudioContext and are no longer read out from webrtc's legacy stats.
1.7.0 (Apr 4, 2019)
New Features
Opus and Codec Preference API
Opus and PCMU are the two codecs now offered and accepted by Twilio Client JS.
For 1.7 and all further 1.x releases, G.711 (PCMU) will continue to be the preferred codec offered. This is to avoid any potential breaking changes.
The following code illustrates how to make Opus the default codec:
var device;
// Setup Twilio.Device
device = new Twilio.Device(YOUR_TOKEN, {
codecPreferences: ['opus', 'pcmu']
});
The option codecPreferences can be passed in when instantiating a Device
instance or when calling Device.setup
to set the codecs preference. The default is set to [‘pcmu’, ‘opus’]
1.6.10 (Mar 20, 2019)
Bug Fixes
- Fixed a DSCP bug, which was causing the
dscp
flag to be ignored in Chrome due to a breaking change introduced in Chrome M72.
1.6.9 (Feb 21, 2019)
Additions
- Added
device.audio.setAudioConstraints()
anddevice.audio.unsetAudioConstraints()
. These methods allow setting a MediaTrackConstraints object to be applied to every timedevice.audio.setInputDevice()
is called, and any time an active input device is lost and the SDK gets new user media to fall back to another input device. If an input device is already set viadevice.audio.setInputDevice()
, these methods will immediately callsetInputDevice()
internally and return the resulting Promise, otherwise they will return a resolved Promise. The currently set audio constraints can be seen on the new read-only field,device.audio.audioConstraints
, which defaults tonull
.
Example:
device.audio.setAudioConstraints({ echoCancellation: true });
await device.audio.setInputDevice('default');
// Now we have a live input audio track, opened with echoCancellation:true
device.audio.setAudioConstraints({
autoGainControl: false,
echoCancellation: false,
noiseSuppression: false,
}).then(() => {
// We successfully applied the new constraints and should automatically hear the difference.
// Future calls to setInputDevice will also use these constraints until they're cleared.
}, err => {
// Something went wrong, most likely err is an OverconstrainedError. Let's roll back.
await device.audio.unsetAudioConstraints();
// We should now have a working input audio track again
});
1.6.8 (Feb 13, 2019)
Bug Fixes
- Applied a workaround to a Chrome regression introduced in M72 affecting speakerDevices.test() and ringtoneDevices.test().
Browser Support
- We are now using RTCP values for RTT when available. Initially, this will not affect Chrome because Chrome has not yet implemented support. Additionally, having access to RTT will allow Firefox to calculate and report MOS, however FireFox is currently affected by a regression causing jitter to be reported as 0, which may make MOS scores appear slightly higher until it's patched by Mozilla.
1.6.7 (Feb 12, 2019)
Insights
- Now sending ice gathering state change events to Insights as ice-gathering-state.
Bug Fixes
- Fixed a regression introduced in 1.6.0 causing falsey TwiML params (undefined, null, 0, false) to be stripped.
Twilio.Device.audio.disconnect()
will now toggle whether the disconnect sound should play while already on an active call.
Additions
- Increased default websocket backoff maximum from 3000ms to 20000ms, and added the
backoffMaxMs
option toDevice.setup()
options that takes a time in milliseconds to override this default. The minimum allowable value is 3000ms. Example:Device.setup(token, { backoffMaxMs: 45000 });
1.6.6 (Feb 5, 2019)
Dependency Updates
- Updated
ws
dependency to latest. Only affects npm package because the CDN artifact of twilio.js uses the browser's WebSocket implementation.
1.6.5 (Dec 3, 2018)
Bug Fixes
- Fixed an issue introduced in 1.6.3 preventing metrics from being published to Insights.
1.6.4 (Nov 30, 2018)
Additions
- Added NetworkInformation data to a new Insights event,
network-change
, which is sent first when a new Connection is established, and then any time thereafter the network information changes. See the support browser chart here.
1.6.3 (Nov 19, 2018)
Bug Fixes
- Stopped sending Insights events that aren't associated with a CallSid or TempCallSid as they can't be tracked.
Additions
- Added Device.setup option
{ fakeLocalDTMF: true }
that uses imitation DTMF sounds instead of the default real DTMF sounds, preventing an issue where DTMF tones would sometimes register twice.
1.6.2 (Nov 8, 2018)
Addition
- Updated default RTCConfiguration object to ensure forward compatibility when
plan-b
is deprecated. - Added an
rtcConfiguration
field to IDeviceOptions, which takes an RTCConfiguration object that gets passed to any created RTCPeerConnections. Example:
Device.setup(token, {
rtcConfiguration: { iceTransportPolicy: 'relay' },
});
1.6.1 (Oct 3, 2018)
Bug Fixes
- Re-assigning the master output device mid-call, particularly when calling
device.disconnectAll()
, will no longer throw an exception or pause script execution. - Fixed
closeProtection
feature - Added EventEmitter interface (
on
,addListener
,removeListener
, etc...) to Device singleton.
1.6.0 (Aug 29, 2018)
New Features
- Added the ability to receive and handle incoming calls while on an active call behind a new flag,
allowIncomingWhileBusy
. When set to true, Device's default behavior of silently ignoring the incoming call is removed, and the incoming call will instead cause Device to emit an "incoming" event. If accepted, the prior active call will be immediately disconnected, and the incoming call will be accepted, replacing the prior active call.
Twilio.Device.setup(token, { allowIncomingWhileBusy: true });
- Added support for custom incoming parameters from TwiML as
Map<string, string> Connection.customParameters
. When a TwiML application sends custom parameters using the<Parameter>
noun, these parameters will be added toConnection.customParameters
. For example:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial>
<Client>
<Identity>alice</Identity>
<Parameter name="foo" value="bar"/>
<Parameter name="baz" value="123"/>
</Client>
</Dial>
</Response>
device.on('incoming', connection => {
assert.equal(connection.customParameters.get('foo'), 'bar');
assert.equal(connection.customParameters.get('baz'), '123');
});
Note that the following restrictions apply to the Parameter noun:
- Parameter name must be a string, up to 32 bytes.
- Parameter value must be a string, up to 128 bytes.
- Up to 8 parameters can be sent per dial.
1.5.2 (Nov 29, 2018)
Addition
- Updated default RTCConfiguration object to ensure forward compatibility when
plan-b
is deprecated.
1.5.1 (Aug 15, 2018)
Bug Fixes
- Updated Insights logic to point to new endpoint, fully supporting Insights when using Access Tokens
1.5.0 (Aug 08, 2018)
New Features
Twilio.Device
may now be instantiated multiple times via
const device = new Twilio.Device(token, options);
Twilio.Device.setup()
may now be called with Access Tokens, in addition to Capability Tokens.Twilio.Device.destroy()
will now completely clear out the Device, allowingDevice.setup()
to be called with a new set of options
Bug Fixes
- We now ensure all Audio resources are cleaned up after closing a Connection
Deprecations
- Twilio Client is moving toward the standard EventEmitter interface, meaning events should be managed with
.on(eventName, handler)
and.removeListener(eventName, handler)
, replacing our legacy handlers (such as.accept(handler)
,.error(handler)
, etc...). The following methods are deprecated:
Device.cancel(handler)
Device.connect(handler)
Device.disconnect(handler)
Device.error(handler)
Device.incoming(handler)
Device.offline(handler)
Device.ready(handler)
Connection.accept(handler)
Connection.cancel(handler)
Connection.disconnect(handler)
Connection.error(handler)
Connection.ignore(handler)
Connection.mute(handler)
Connection.reject(handler)
Connection.volume(handler)
These have been replaced with the following EventEmitter events:
Device.on('cancel', handler)
Device.on('connect', handler)
Device.on('disconnect', handler)
Device.on('error', handler)
Device.on('incoming', handler)
Device.on('offline', handler)
Device.on('ready', handler)
Connection.on('accept', handler)
Connection.on('cancel', handler)
Connection.on('disconnect', handler)
Connection.on('error', handler)
Connection.on('mute', handler)
Connection.on('reject', handler)
Connection.on('volume', handler)
Note that there is no Connection#ignore
event. The Connection.ignore(handler)
method is actually a backward-compatible listener for the Connection.on('cancel', handler)
event.
1.4.35 (Nov 29, 2018)
Addition
- Updated default RTCConfiguration object to ensure forward compatibility when
plan-b
is deprecated.
1.4.34 (Aug 29, 2018)
- Fixed an issue causing disconnected sound to not play by default.
1.4.33 (Jul 05, 2018)
- Updated AudioPlayer dependency to the newly published @twilio/audioplayer package.
1.4.32 (Apr 19, 2018)
Bug Fixes
- Fixed a regression introduced by 1.4.31 (rolled back on Apr 18) causing region passed to Device.setup to be ignored.
1.4.31 (Apr 16, 2018)
Bug Fixes
- Fixed a WebSocket issue occasionally resulting in "Cannot register. Token not validated." errors.
1.4.30 (Mar 28, 2018)
Bug Fixes
- Added
Twilio.Device.isSupported
flag which should betrue
if WebRTC or ORTC is supported. Iffalse
, it's an indicator thatDevice.setup
should not be called (it will throw an unsupported exception). - Fixed an issue where an internal listener wasn't being cleaned up when disconnecting a call, resulting in EventEmitter warnings when opening more than 10 calls in a row.
1.4.29 (Mar 6, 2018)
Bug Fixes
- Fixed a build issue causing the twilio-client npm package to fail when run through webpack or browserify.
1.4.28 (Feb 28, 2018)
Additions
- The JS Twilio Client SDK has been added to npm! https://www.npmjs.com/package/twilio-client
- Added licenses to both artifacts (js and min.js)
Bug Fixes
- Added a fallback for when posting metrics to Insights fails, so that a warning is logged in the console rather than an exception being thrown.
1.4.27 (Jan 31, 2018)
Bug Fixes
- Fixed an issue causing Insights timestamps to be undefined and breaking application flow in some environments.
- Fixed an issue causing one-way audio for all calls after the first when using
Device.audio.setInputDevice()
- Fixed an issue causing sounds not to play correctly in Chrome when a non-default output device was selected by
Device.audio.speakerDevices
orDevice.audio.ringtoneDevices
.
1.4.26 (Dec 8, 2017)
Bug Fixes
- Fixed an issue causing input audio to be lost after calling Device.audio.setInputDevice('default') and then removing and replacing the USB headset.
- Fixed an issue causing outbound calls to break after the final audio output device was removed and replaced.
- Removed circular references so that the Connection object can be serialized.
- Fixed an issue causing WebSockets to become unrecoverable when the token expired while the socket is offline or disconnected.
1.4.25 (Nov 15, 2017)
Feature support
- Added support for the answerOnBridge feature of TwiML by adding a new
ringing
Connection state andConnection#ringing
event behind the flag:Twilio.Device.setup(token, { enableRingingState: true })
. With both theanswerOnBridge
property and theenableRingingState
flag enabled in the consuming application, the Connection state is now be more granular: -
ringing
state is transitioned to when the callee is notified of the incoming call
-
open
state is transitioned to when the callee has accepted the call
Bug fixes
- Fixed an issue causing the
Device.sounds
deprecation warning to be logged every time the library was loaded. - Fixed an uncommon issue causing "Cannot call register of undefined" errors when destroying the Device.
1.4.24 (Sep 21, 2017)
Browser Support
- Removed babel libraries, which were causing increased file size and clashing with the same libraries included in consuming applications.
- Enabled volume support, as Safari's support of AudioNode is now stable.
1.4.23 (Sep 19, 2017)
Browser Support
- Added experimental support for Safari 11. All functionality has been enabled in Safari 11, with a couple caveats:
-
- Audio output selection and availabeOutputDevices are disabled as Safari does not yet support
HTMLAudioElement.setSinkId
- Audio output selection and availabeOutputDevices are disabled as Safari does not yet support
-
- The volume APIs are temporarily disabled in Safari as a related WebAudioAPI feature was sometimes causing tabs to crash in our testing. We will be re-evaluating this and looking to re-enable this feature going forward.
1.4.22 (Sep 12, 2017)
Bug Fixes
- Fixed a bug causing the ringtones of multiple incoming calls to stack, and then continuing to ring after one is answered.
- Fixed a bug causing Electron applications to report one-way audio.
- Fixed a bug causing additional websockets to be created when Device.setup is called while the existing websocket is temporarily disconnected.
- Fixed a bug causing a tab to play the incoming ringtone indefinitely in the case where an unfocused tab receives an incoming call, and is then focused after that call is canceled.
1.4.21 (Aug 11, 2017)
Bug Fixes
- Insights token should now correctly update when
Device.setup
is called with a new token. - Any changes made to the input/output device selection while a call is incoming should now always be respected.
1.4.20 (Jul 14, 2017)
Bug Fixes
- Fixed a bug in Chrome causing 0 jitter to be reported as undefined, and MOS to be reported as 1
1.4.19 (Jul 13, 2017)
Bug Fixes
- Fixed a bug causing the wrong RTCStats timestamps to be used, sometimes resulting in seemingly missing Insights data.
1.4.18 (Jul 11, 2017)
Bug Fixes
- Fixed a race condition causing the incoming ringtone to continue ringing after a call had already been accepted or rejected.
- Completely removed incoming call sound duration. Once an incoming call is accepted or rejected, the ringtone will stop immediately in all cases.
1.4.17 (Jul 6, 2017)
Regions
- Added support for the new interconnect region aliases: ie1-ix (Ireland), us1-ix and us2-ix
Bug Fixes
- Fixed a bug causing constant audio input level warnings to be raised in newer Chrome versions
- Minimum incoming call sound duration has been reduced from 2000ms to 100ms
1.4.16 (Jun 19, 2017)
Bug Fixes
- Reverted behavior of
Device.activeConnection()
to return the first received incoming call when there is no active, ongoing call. This behavior was inadvertently changed in 1.4.15. In the next breaking release, this behavior will be changed so thatDevice.activeConnection()
correctly only returns the active connection if one exists.
1.4.15 (Jun 15, 2017)
Bug Fixes
- Fixed a bug causing device to ring instead of being ignored when a new call comes in during an ongoing call after re-registering with a new token.
Browser Compatibility
- Removed ws dependency, we instead use the native Websocket now. This should make file size smaller, and make the library fully es5-compatible.
- Implemented support for standard WebRTC statistics, maintaining backward compatibility with google-prefixed stats.
Regions
- Added support for German region
de1
1.4 Public Beta: 1.4.14 (Apr 3, 2017)
Bug Fixes
- Fixed a bug sometimes causing "Twilio not defined" failures in Edge.
- Fixed Connection.mute() so that the call stays muted after switching input devices.
Browser Compatibility
- Updated Connection.sendDigits to use the new RTCDTMFSender in Firefox 52 and above.
API Changes
- Added
connection.getRemoteStream()
andconnection.getLocalStream()
to retrieve the local/remote streams being used in the Connection.
1.4 Public Beta: 1.4.13 (Mar 17, 2017)
Bug Fixes
- A disconnected input device should now be usable by Device.audio.setInputDevice() after being reconnected.
1.4 Public Beta: 1.4.12 (Mar 08, 2017)
Bug Fixes
- Twilio's ORTC adapter will now be used over the native WebRTC components introduced in Edge build 15019. This distinction will remain until Edge's native WebRTC support satisfies all of Twilio Client's dependencies.
- The incoming ringtone sound should now continue playing when one of multiple incoming calls is rejected, ignored or canceled and other incoming calls remain.
1.4 Public Beta: 1.4.11 (Feb 24, 2017)
New Features
- Input Device Fallback - When an active input device is lost, we will now fall back to a backup input device on Chrome and Edge. Firefox does not currently provide a way to detect when an active input is lost.
Browser Compatibility
- [Edge] Switching input devices is now fully supported in Edge.
- [FF] Due to lack of support for opening multiple audio input devices, support for the
Device.audio.setInputDevice
has been completely disabled in Firefox. - [FF] Additionally, helpful error messages have been added to Twilio Client's getUserMedia request failures to help identify when user media requests fail due to Firefox's audio input device limitation.
- See the bottom of the 1.4 Overview page for a complete chart of browser compatibility.
Bug Fixes
Device.audio.unsetInputDevice()
will no longer throw an error if called synchronously inside theDevice.incoming()
handler.- Tracks will now always properly be stopped. As long as
Device.audio.inputDevice
is null and there is no active call, all user media should be properly released. Device.audio.setInputDevice()
will now work properly when the client is the caller or callee.- When the incoming sound fails to load or play, the
Device.incoming
handler will still be fired after a maximum timeout of 2 seconds. Pausing execution (by adding an alert or prompt on Device.incoming) should no longer prevent the incoming ringing sound from playing. Note that in Chrome, the incoming sound will only play once as the paused script execution will prevent looping behavior. - Exceptions should no longer be logged to the console whenever a new device is found.
Interconnect
- Added a new interconnect region:
ie1-tnx
CSP Compliance
- Removed a legacy dependency that contained
eval
statements; no more should be present.
1.4 Public Beta: 1.4.10 (Jan 18, 2017)
Bug Fixes
- Device.setup now properly updates Device with the new token data when called.
- Connection#warning will now be emitted, instead of
Connection#error
, when ICE liveliness checks fail. This serves to differentiate between fatal and non-fatal ICE events.
1.4 Public Beta: 1.4.9 (Dec. 20, 2016)
New Features
- Audio Output Selection – Using the new Device.audio API, developers may now specify which audio output device(s) to play Client sounds through, in browsers that support the feature (As of writing, Chrome 49 and above). The incoming ringtone sound is separated into its own audio channel, allowing it to be played out of a different set of output devices than in-call audio if desired.
- Audio Input Selection - Additionally, the Device.audio API allows developers to swap the input device during an ongoing call, or set the input device and test it before making a call.
- Volume Indicators - Twilio Client's Connection class now reports the input and output volumes of the call, making it easier for developers to show real-time volume indicators in their UI.
- Custom Sounds - Twilio Client now supports passing custom sounds to Device.setup to be used in place of Twilio's default sounds.
- Twilio Interconnect (TNX) Support - Twilio Client now supports connecting through Twilio Interconnect (TNX) for certain regions. As of writing, connecting to regions
us1
andus2
on TNX connection provisioning is supported in Client viaus1-tnx
andus2-tnx
region parameters, respectively.
1.4 Public Beta: 1.4.4 (Dec. 9, 2016)
New features
- Quality Warnings - Twilio Client's Connection class now emits real-time warnings when it detects potential call quality problems, and emits a warning cleared event when that issue clears up.
- User Feedback - Twilio Client's Connection class now accepts user feedback on call quality through the Connection.postFeedback API.
API changes
- Device.sounds - We have added deprecation warnings for Device.sounds, and moved its functionality over to the new Device.audio API.
Bug Fixes
- Close protection will now continue to work after the active token has expired.
- Connection.accept will no longer throw a breaking exception when called twice (Though we still recommend only calling this once!)
twilio.js 1.3
1.3.21 (Aug 11, 2017)
Bug Fixes
- Insights token should now correctly update when
Device.setup
is called with a new token.
1.3.20 (Jul 18, 2017)
Bug Fixes
- Fixed a bug in Chrome causing 0 jitter to be reported as undefined, and MOS to be reported as 1
- Fixed a bug causing the wrong RTCStats timestamps to be used, sometimes resulting in seemingly missing Insights data.
1.3.19 (Jul 6, 2017)
Regions
- Added support for the new interconnect region aliases: ie1-ix (Ireland), us1-ix and us2-ix
- Added support for German region 'de1'
Future-proofing
- Added support for standard RTCStats object
1.3.18 (Apr 3, 2017)
Insights
- Updated Connection.sendDigits to use the new RTCDTMFSender in Firefox 52 and above.
1.3.17 (Mar 22, 2017)
Insights
- The
constant-audio-output-level
is now reported as an INFO level event, rather than WARNING in order to reduce false positives. This event may fire if the other side of the call is muted.
1.3.16 (Jan 18, 2017)
Bug Fixes
- Device.setup now properly updates Device with the new token data when called.
- ICE liveliness checks will now generate an appropriate Insights event when the connection is lost or regained.
1.3.15 (Nov 11, 2016)
- Increased the delay at beginning of a call before enabling monitoring for network issues to counteract the newer versions of Chrome which cause RTT to be reported abnormally high for the first 10-15 seconds of a call, which was causing false positives to be thrown.
1.3.14 (Nov 2, 2016)
- Fixed some internal logic causing ignored-by-local event to be logged multiple times in Insights
- Added / modified other Insights fields to improve logging.
1.3.13 (Oct. 26, 2016)
- Added browser specific error information for microphone access failure (31201).
1.3.12 (Aug. 22, 2016)
- Close protection will now still work correctly after token has expired, if a call is active.
- Added additional fields to Insights metrics payloads.
1.3.11 (May 27, 2016)
- Removed an erroneous field from the payload format that gets sent to Twilio Insights.
1.3.10 (May 20, 2016)
- Adjusted call quality warning events that get sent to Twilio Insights.
1.3.9 (May 6, 2016)
- Added more lifecycle events to be sent to Twilio Insights. Adjusted existing lifecycle events to new schema.
1.3.8 (May 6, 2016)
- Added RTC monitoring and warnings to the events that are sent to Twilio Insights.
1.3.7 (Apr. 18, 2016)
Bug Fixes
- Miscellaneous bug fixes regarding lifecycle event logging.
- Further improvements to internal call quality metrics logging.
1.3.6 (Apr. 8, 2016)
Bug Fixes
- Improvements to internal call quality metrics logging.
1.3.5 (Mar. 11, 2016)
Bug Fixes
- Fixed asset loading in Chrome extension.
1.3.4 (Feb. 25, 2016)
New features
- Region selection – Developers can now choose to connect their users to a specific Twilio Client data center, or continue to allow Twilio's Global Low Latency routing to select the lowest-latency path. See the documentation for more information.
- Static IP addresses for Twilio Client media – Twilio Client now establishes media connections from a static range of IP addresses. See the Twilio Client documentation for a list of the IP address ranges that Twilio is currently using. See the documentation for the list of IP address ranges.
- Support for ORTC in Microsoft Edge beta releases - Microsoft Edge beta releases now support ORTC. Now you can use Twilio Client in Microsoft Edge to make and receive calls without Flash.
- DSCP support - Twilio Client 1.3 enables DSCP by default in browsers that support it.
Functionality removed
- Presence - We have removed support for Presence in twilio.js 1.3.
- Flash support - We have removed support for Flash in twilio.js 1.3.
API changes
- The error passed to
error()
's handler function no longer contains theinfo
property. This property previously contained theflash.net.NetConnection
object. Twilio.Device.setup()
no longer acceptsrtc
in itsparams
argument. Twilio Client will use WebRTC or ORTC if either API is available in the browser, Flash is no longer an option.presence()
has been removed. Presence is longer supported in Twilio Client.getMediaEngine()
has been removed, since Flash is no longer supported.
1.2 (Feb. 25, 2016)
Deprecated features
- Presence - Added deprecation warnings to Presence functionality, as these features have been removed in twilio.js 1.3.
- Flash support - Added deprecation warnings to Flash functionality, as this feature has been removed in twilio.js 1.3.
1.2 (Oct. 6, 2015)
Bug Fixes
- No longer raises the "MediaStream.stop is deprecated" warning in Google Chrome
- No longer raises the "MediaStream.ended is deprecated" warning in Google Chrome
New Features
- Allow twilio.js and other Twilio JavaScript SDKs to be included on the same page
sendDigits
usesRTCDTMFSender
where supported
1.2 (Sep. 18, 2015)
Bug Fixes
- Resolved an issue where Chrome 45 users were occasionally unable to accept calls.
New Features
- Improved remote troubleshooting abilities
1.2 (Aug. 12, 2015)
Bug Fixes
- Resolved an issue where Flash users may have been unable to place or accept calls when using the
simplePermissionDialog
option. - Compatibility code enabling support for versions of Chrome older than 26 has been rewritten so as not to affect non-standard WebRTC implementations.
1.2 (Oct. 23, 2014)
New Features
- On ICE disconnect, raise an error "ICE liveness checks failed. May be having trouble connecting to Twilio." with error code 31003. This can occur when the browser believes a previously active connection is no longer properly connected. This can happen due to changing network conditions, etc.
- On ICE failure, raise an error "ICE negotiation with Twilio failed. Call will terminate." with error code 31003, and terminate the call. This can occur when the browser is unable to connect to Twilio's WebRTC gateways. Common causes for this error include firewall rules which block connectivity to Twilio's media servers or firewall rules which block outgoing UDP.
- Log additional client-side WebRTC statistics for better troubleshooting call quality issues:
audioInputLevel
andaudioOutputLevel
.
1.2 (Sep. 29, 2014)
Bug Fixes
- Provide a more useful warning if too many event handlers are registered.
- Fix a bug where internal event handlers were not being unregistered.
1.2 (Sep. 16, 2014)
New Features
- Add a new
audioConstraints
setting to select a specific microphone, or turn off features like auto-gain control. - Collect client-side WebRTC statistics for troubleshooting call quality issues.
- Add a new function,
Twilio.Device.getMediaEngine()
, for checking whether WebRTC or Flash is being used.
Bug Fixes
- No longer raise an exception when the capability token expires if an error
handler has been registered on
Twilio.Device
.
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.