Javascript (Web/Browser)
This guide details the key classes and methods provided in the Bandwidth WebRTC Javascript Client SDK.
There are two important classes in the SDK:
BandwidthUA
- the User Agent (UA), which can be thought of as a phoneBandwidthSession
- the Session, which can be thought of as a call
Initialization/management of the client and the creation of calls is managed by the UA, and, once a call is in progress, it can be altered by making changes to the Session.
Client
Import the Client
import { BandwidthUA } from '@bandwidth/bw-webrtc-sdk';
const client = new BandwidthUA();
Client Initialization
There are a number of key initialization steps that are required in the web client before the client is capable of placing calls. This ensures that:
- The Client is appropriately configured, and capable of connecting to the WebRTC Gateway.
- The account security token has been made available to the SDK to ensure that all calls will be associated with the correct account.
- The events that will happen on active calls, and with the websocket connection can be appropriately intercepted by the client and handled.
- The connection with the WebRTC Gateway can be established and removed.
- This is done by making changes to an instance of the UA with some of the methods described below.
Once all of the above initialization steps have been completed, the client is in a position to place calls to the Bandwidth Network via the WebRTC Gateway, and respond to events from the network that result.
client.setServerConfig();
/**
* Configures the Bandwidth server.
* @param {Array} serverAddresses - serverAddresses: inetSocket Address List of the Bandwidth servers
serverAddresses [integer]: Two elements array list; where each array in the list contains the inetSocket Address of the Bandwidth servers and priority.
* @param {string} serverDomain - String of the domain name to which to register.
* @param {Array} [iceServers = []] - List of the STUN and TURN servers. If it is used as an empty list during the call opening, an external STUN server is not used. This mode is useful when the phone is used towards an SBC server.When the iceServers list is empty, after the call opens, the client still periodically sends STUN requests to the port used for the RTP stream for checking that the RTC channel is alive.
* @returns {void}
*/
setServerConfig(serverAddresses, serverDomain, iceServers = []) {
return this.#bandwidthUA.setServerConfig(serverAddresses, serverDomain, iceServers);
}
The setServerConfig
method takes 3 parameters that establish the relationship between the client and the network for making calls.
This method should be called prior to any attempts to perform any other client or calling functions.
There are three parameters for the setServerConfig method call:
serverAddresses
: List of the Bandwidth WebRTC gateway FQDNserverDomain
: String containing the domain name to use in interactions with the WebRTC Gateway. This domain is a necessary portion of the endpoint addresses.iceServers
: List of the STUN and TURN servers, containing STUN:// or TURN:// IP addresses. This optional parameter is by default set as an empty list []. If it is used as an empty list, an external STUN server is not used during the creation of the call. This mode is useful when the client has direct visibility of the public network IP addresses of the Bandwidth WebRTC Gateway.
client.setOAuthToken(token)
/**
* Sets the access token to OAuth2 authorization.
* This token is used while communicating with Bandwidth to authorize the user access.
* The Oauth token usage makes the password usage redundant.
* @param {?string} token - 'null' can be used to clear the authorization token.
* @param {boolean} [useInInvite = true] - If 'false', the "Authorization: Bearer" header token is added only to the SIP REGISTER request.
* This is used if the SBC supports early versions of the Authorization bearer specification.
* If 'true', the "Authorization: Bearer" header token is added to the SIP REGISTER and INVITE requests.
This is used if the SBC supports the latest version of the Authorization bearer specification.
* @returns {void}
*/
setOAuthToken(token, useInInvite = true) {
this.#bandwidthUA.setOAuthToken(token, useInInvite);
}
All calls from web and mobile clients require a security token generated by Bandwidth to be present with any request to establish a call to the Bandwidth Network.
The setOAuthToken
method invoked on an instance of the UA will cause this token to be registered with the client, and used in subsequent calls to ensure that the calls are authentic and contain the correct account information.
client.init()
The init
method is used to establish the connection to the Bandwidth WebRTC gateway. This method is only valid once the UA has been configured.
client.deinit()
The deinit
method reverses the action of the init method, removing the connection between the client and the Bandwidth WebRTC gateway.
client.isInitialized()
Checks if the init()
method was called.
client.checkAvailableDevices()
/**
* This method has two functions:
Checks if the WebRTC API is supported in the used browser. If not, the Promise object will be rejected with the following string: “WebRTC is not supported in the browser”.
Checks available devices (speaker, microphone and camera). If the speaker is not connected, the speaker Promise object is rejected with the following string:
“Missing a speaker! Please connect one and reload”
* If the microphone is not connected, the microphone is rejected with the following string:
“Missing a microphone! Please connect one and reload”
* @returns {Promise} The Promise object is resolved with hasWebCamera Boolean value and is rejected with a string describing the problem.
*/
checkAvailableDevices() {
return this.#bandwidthUA.checkAvailableDevices();
}
This method has two functions:
Checks if the WebRTC API is supported in the used browser.
If this is not supported, the Promise object will be rejected with the following string: “WebRTC is not supported in the browser”.
Checks available devices (speaker, microphone and camera).
If the speaker is not connected, the speaker Promise object is rejected with the following string: “Missing a speaker! Please connect one and reload”
If the microphone is not connected, the microphone is rejected with the following string: “Missing a microphone! Please connect one and reload”
client.setListeners(listeners)
There is little value in sending a call towards the Bandwidth network if there is no feedback on events that happen in the network while completing the call.
The setListeners
UA method allows the registration of callback functions that, if registered, will be invoked on various network and connection events, allowing the client to respond to normal and error conditions that are encountered in the network.
The setListeners
configuration method is invoked on an instance of the UA, and has a single listeners object as the parameter.
This listener object contains six or more elements, each of which is a function that will be invoked on the detection of the event in the network.
An example of setting the different listeners in a React Application would be as follows:
import { useEffect, useState } from 'react';
const [myState, setMyState] = useState('');
useEffect(() => {
client.setListeners({
loginStateChanged: function (isLogin, cause) {
console.log("Client state changed. Cause: " + cause);
// eslint-disable-next-line default-case
switch (cause) {
case 'connected':
console.log('client>>> loginStateChanged: connected');
break;
case 'disconnected':
console.log('client>>> loginStateChanged: disconnected');
if (client.isInitialized())
// after deinit() phone will disconnect SBC.
console.log('Cannot connect to SBC server');
break;
case 'login failed':
console.log('client>>> loginStateChanged: login failed');
break;
case 'login':
console.log('client>>> loginStateChanged: login');
break;
case 'logout':
console.log('client>>> loginStateChanged: logout');
break;
}
},
outgoingCallProgress: function (call, response) {
console.log('client>>> outgoing call progress');
console.log("Call: ", call);
console.log("Response: ", response);
setMyState('foo');
},
callTerminated: function (call, message, cause) {
console.log('client>>> call terminated callback');
console.log("Call: ", call);
console.log("Message: ", message);
console.log("Cause: ", cause);
setMyState('foo');
},
callConfirmed: function (call, message, cause) {
console.log('client>>> callConfirmed');
console.log("Call: ", call);
console.log("Message: ", message);
console.log("Cause: ", cause);
setMyState('foo');
},
callShowStreams: function (call, localStream, remoteStream) {
console.log('client>>> callShowStreams');
console.log("Call: ", call);
console.log("Local Stream: ", localStream);
console.log("Remote Stream: ", remoteStream);
setMyState('foo');
},
incomingCall: function (call, invite) {
console.log('client>>> incomingCall');
console.log("Call: ", call);
console.log("Invite: ", invite);
setMyState('foo');
},
callHoldStateChanged: function (call, isHold, isRemote) {
console.log('client>>> callHoldStateChanged');
console.log("Call: ", call);
console.log("Is Hold: ", isHold);
console.log("Is Remote: ", isRemote);
setMyState('foo');
}
});
}, [myState]);
Listener Methods
The below methods are available once the client is initialized and ready to make calls.
loginStateChanged: function(isLogin, cause)
The provided function is invoked when the connection state between the Bandwidth WebRTC server and the Client changes. This can occur when a requested connection is established in a bi-directional manner, or when that connection fails. There are other causes of this event that will be documented elsewhere.
outgoingCallProgress: function(call, response)
The provided function is invoked when there is a change in the state of the call from the client. A classic example of this is when a ringing state is detected.
callTerminated: function(call, message, cause)
The provided function is invoked when the call ends. A cause for the end of the call is provided.
callConfirmed: function(call, message, cause)
The provided function is invoked when the system has determined that the call has been accepted by the Bandwidth WebRTC gateway, and further progress of the call is anticipated.
callShowStreams: function(call, localStream, remoteStream)
The provided function is invoked when media streams have been established. This often corresponds with the answering of the call.
callHoldStateChanged(call, isHold, isRemote)
If the system is configured to support hold state conditions, this function will be invoked on changes in the hold state of the call.
Creating a Call
activeCall = client.makeCall(tn)
/**
* Making the outbound call
* @param {String} destinationNumber destination number including country code
* @param {[]} extraHeaders extra headers to send along with the call
* @returns {Object} ActiveCall instance
*/
async makeCall(destinationNumber, extraHeaders) {
return this.#bandwidthUA.call(false, `+${destinationNumber}`, extraHeaders);
}
The call method invoked on the UA instance will cause the configured and connected UA to launch a call towards the Bandwidth network. Yes - it is that simple.
The call method takes two parameters:
- A destination telephone number for the outbound call. This TN should be a valid telephone number in E164 format (ex. +19195551234).
- A list of extra headers to send along with the call. This is an optional parameter (ex.
["User-to-User:abc123;encoding=jwt"]
.
The call method returns an instance of a Session object, providing a handle that can be used for subsequent modification of the call while it is in progress.
Session
The Session object is returned by the client.makeCall()
method, and represents the call that has been established.
Methods
Once the UA has been configured and the connection to the Bandwidth WebRTC Gateway has been established, it is time to make and manage calls. Once the setup is done, the rest is relatively straightforward.
activeCall.terminate();
Once a call has been established, one of the possible call modification actions is to end (or terminate) the call. The terminate method on the Session object will be used to cause the call to end.
activeCall.sendDTMF(digit)
If a session represents a call that has established an end-to-end connection, the sendDTMF
method will cause a specified DTMF tone to the far end of the call connection.
The digit parameter is single character string containing a character from the set [0-9,#,*]. This action is undefined if there is no audio connection to the destination of the call.
activeCall.hold(placeCallOnHold)
If a session represents a call that has established an end-to-end connection, the hold
method places the call on a (local) hold, or removes it from a hold state if it is currently held.
The single boolean parameter indicates that the call is to be held (true) or removed from hold (false). This action is undefined if there is no audio connection to the destination of the call.
activeCall.muteAudio(muted)
Once a call has been established, this method could be used to mute the audio.
activeCall.isLocalHold()
Returns a boolean value indicating whether the call is currently held as the result of an activeCall.hold(true) action.