Web Calling SDK | Quickstart Guide
Welcome to the Quick Start Guide for the Webex Calling SDK. This guide is designed to provide developers with a concise walkthrough to swiftly set up, authorize, and test the core calling functionalities within the Calling SDK.
By following the sequential flow of this document and integrating the provided code snippets, you'll be able to authenticate your application and initiate your first calls. Whether you're new to Webex's Calling SDK or looking to brush up on the basics, this guide ensures a streamlined experience to get you up and running in no time. Let's dive in!
anchorImport the Calling SDK
anchorTo import the latest stable version of the Calling SDK you can use NPM or CDN.
NPM
We test against the Active LTS (Long Term Support) version of Node.js and use npm@6
to run security audits.
The Calling SDK is available as a nodejs
module via NPM. You can install it using either yarn
or npm
utilities:
npm install @webex/calling
or
yarn add @webex/calling
To import the Calling SDK:
import Calling from 'webex/calling';
CDN
A minified version of the Calling SDK is also provided via the unpkg.com
Content Delivery Network (CDN). To include the CDN Calling SDK:
<script src='https://unpkg.com/webex/umd/calling.min.js'></script>
anchorInitialize the Calling SDK
anchorTo initialize the Calling SDK, you can use either a Webex object or Webex configuration. The initialization of the SDK also depends on how it is being consumed in the application. The process varies between the CDN and NPM forms of consumption.
Option 1
This option includes different steps based how you consume the SDK in your application.
CDN
- Initialize a Webex object with an access token and required configuration. Refer to the Quickstart guide on how to initialize the
webex
object. You can also refer to thewebexConfig
object in Option 2 as a reference. - Register with Webex Device Manager (WDM) and establish a mercury connection.
- Pass the
webex
andcallingConfig
objects as arguments and create a newCalling
instance which initializes the different client modules. (Refer to the table in the Calling Configuration section to identify Calling Configuration attributes).
const calling = await Calling.init({ webex, callingConfig });
NPM
- Initialize a Webex object with an access token and required configuration. Refer to the Quickstart guide on how to initialize the
webex
object. You can also refer to thewebexConfig
object in Option 2 as a reference. - Register with Webex Device Manager (WDM) and establish a mercury connection.
- Pass the
webex
andCallingClientConfig
as arguments and create a newCallingClient
instance.
import {createClient} from '@webex/calling';
const callingClientConfig = {
logger: {
level: 'info'
},
serviceData: { // This configuration is optional for Webex Calling. It is mandatory for Webex Contact Center
indicator: 'contactcenter',
domain: 'rtw.prod-us1.rtmsprod.net'
},
};
const callingClient = await createClient(webex, callingClientConfig);
Similarly, initialize other client modules available in the Calling SDK to utilize features like voicemail and contacts.
import {createVoicemailClient, createContactsClient} from '@webex/calling';
const config = {
logger: {
level: 'info'
},
};
const vmClient = await createVoicemailClient(webex, config);
const contactClient = await createContactsClient(webex, config);
Option 2
- Pass the
webexConfig
andcallingConfig
objects as arguments and create a newCalling
instance. (Refer to the attribute section for Webex configuration attributes). - Wait for the Calling instance to be ready by listening for the
ready
event. - Once the
ready
event is received, call theregister()
method to trigger Webex Device Manager registration, which establishes a mercury connection and initializes the various client modules within Calling object.
// Create the Webex configuration
const webexConfig = {
config: {
logger: {
level: 'debug' // Set the desired log level
},
meetings: {
reconnection: {
enabled: true
},
enableRtx: true
},
encryption: {
kmsInitialTimeout: 8000,
kmsMaxTimeout: 40000,
batcherMaxCalls: 30,
caroots: null
},
dss: {}
},
credentials: {
access_token: 'access_token'
}
};
// Create the calling configuration
const callingConfig = {
clientConfig: {
calling: true,
contact: true,
callHistory: true,
callSettings: true,
voicemail: true
},
callingClientConfig: {
logger: {
level: 'info'
}
},
logger: {
level: 'info'
}
};
// Create the Calling object
const calling = await Calling.init({ webexConfig, callingConfig });
let callingClient;
calling.on('ready', () => {
calling.register().then(() => {
callingClient = calling.callingClient;
});
});
This option is not available if you consume the SDK using NPM. Use Option 1 instead.
anchorAuthorize with Webex Calling
anchorInitiating the authorization process with Webex Calling is the first step to harness the communication capabilities of the SDK. Before diving into call operations, you must first obtain the Line
object from the CallingClient
. Once you have the Line
object in hand, you can invoke the line.register()
function to create a device, laying the groundwork for initiating and managing voice calls. Before triggering the register()
method, however, it's crucial to listen for the registered
event to ensure the device is successfully registered and ready for operations. This section will guide you through these steps.
// Get Line object from the callingClient. Currently, only a single
// line is supported in the Calling package
const line = Object.values(callingClient.getLines())[0];
// Listen for the registered event from the line
line.on('registered', (lineInfo) => {
console.log('Line information: ', lineInfo);
});
line.register();
anchorPlace a Call
anchorStarting an outgoing call to a designated destination involves a sequence of steps. First, you need to capture the microphone stream, since this step ensures your application is set to transmit voice. Once the microphone stream is in place, you'll need to create the Call
object from the Line
.
You can create a microphone stream in a couple of ways.
Option 1
In this option, you'll use the createMicrophoneStream()
within the Calling
object to fetch the default microphone on the system. This option is only available when consuming the SDK via CDN.
const localAudioStream = await Calling.createMicrophoneStream({ audio: true });
const call = line.makeCall({
type: 'uri',
address: 'destination'
});
await call.dial(localAudioStream);
Option 2
This option is available to you if you consume the SDK via NPM. You'll need to use the LocalMicrophoneStream
class from the SDK to create a microphone stream.
import {LocalMicrophoneStream} from '@webex/calling';
const localStream = navigator.mediaDevices.getUserMedia({audio: true});
const audioTrack = localStream.getAudioTracks()[0];
const localMicStream = new LocalMicrophoneStream(new MediaStream([audioTrack]));
const call = line.makeCall({
type: 'uri',
address: 'destination'
});
await call.dial(localMicStream);
As you navigate through the intricacies of initiating and managing calls, it's vital to note that the Call
object is not just a static entity but a dynamic one, emitting various events during the course of a call. By actively listening for these events, developers can gain insights into the different transitions and states that a call might enter, be it ringing
, connected
, or ended
. Monitoring these events allows for a more responsive and intuitive user experience, as your application can adjust in real-time based on the call's status. For instance, you might update the user interface to reflect when a call is on hold or when the other party has picked up. Incorporating this event-driven approach will ensure a robust and interactive calling experience for your users.
call.on('progress', (correlationId) => {
console.log('Call is ringing at the remote end');
});
call.on('connect', (correlationId) => {
console.log('Call has been answered');
});
call.on('established', (correlationId) => {
console.log('Call is now established. Media flows both ways');
});
call.on('disconnect', (correlationId) => {
console.log('Call has been disconnected');
});
call.on('remote_media', (track) => {
// Remote media information received from the SDK. This is relayed to the
// application using the remote_media event
document.getElementById('remote-audio').srcObject = new MediaStream([track]);
});
With the Call
object ready, you can then utilize the dial
method, incorporating the previously acquired microphone stream. This method combines the audio input with the call initiation, facilitating a communication link to your desired destination. This guide elucidates each step, providing you with a clear path to efficiently manage and initiate outgoing calls.
await call.dial(localAudioStream);
Handling incoming calls requires a similar approach. The first step involves listening for the incoming_call
event on the Line
. This event signals the arrival of an incoming call and provides the initial alert to the application. Once this event is detected and an incoming call is acknowledged, the focus shifts to the Call
object. Here, similar to outgoing calls, developers should actively listen to the set of events emitted by the Call
object. These events provide real-time updates about the call's status, such as whether it's been answered, or disconnected. Once those listeners are ready, you can call the answer
method to answer the call.
let incomingCall;
line.on('incoming_call', (incomingCall) => {
console.log('Incoming call arrived. Call information', incomingCall);
});
incomingCall.on('disconnect', (correlationId) => {
console.log('Call has been disconnected');
});
incomingCall.on('remote_media', (track) => {
// Remote media information received on the SDK. This is relayed to the
// application using the remote_media event
document.getElementById('remote-audio').srcObject = new MediaStream([track]);
});
incomingCall.answer();
Client objects will be created based on the calling configuration inside a Calling
instance.
anchorCalling Configuration Details
anchorThis is the definition for a callingConfig
object:
callingConfig: {
clientConfig: {
calling: boolean,
contact: boolean,
callHistory: boolean,
callSettings: boolean,
voicemail: boolean,
},
callingClientConfig: {
logger: {
level: string
},
discovery: {
country: string,
region: string,
},
serviceData: {
domain: string,
indicator: string,
guestName: string
}
},
logger: {
level: string
}
}
The following tables cover the different configuration attributes present inside the callingConfig
object.
Client Configuration
S.no | Attribute | Description | Data Type | Default Attribute? | Public Attribute? |
---|---|---|---|---|---|
1. | calling | Toggles the availability of the callingClient module. | Boolean | No | Yes |
2. | contact | Toggles the availability of the contactClient module. | Boolean | No | Yes |
3. | callHistory | Toggles the availability of the callHistory module. | Boolean | No | Yes |
4. | callSettings | Toggles the availability of the callSettings module. | Boolean | No | Yes |
5. | voicemail | Toggles the availability of the voicemailClient module. | Boolean | No | Yes |
Calling Client Configuration
S.no | Attribute | Description | Data Type | Default Attribute? | Public Attribute? |
---|---|---|---|---|---|
1. | discovery | Object | No | Yes | |
1.a. | country | Country from where the device registration is triggered. It has to be an Alpha-2 code as per ISO 3166-1 standards. Here's the list of officially assigned Alpha-2 codes from Wikipedia. | String | No | Yes |
1.b. | region | Region from where the device registration is triggered. It should be one of the following: AP-SOUTHEAST , US-EAST , EU , or EU-CENTRAL . | String | No | Yes |
2. | serviceData | it represents the service data of the SDK. | String | No | Yes |
2.a. | domain | Identifies which service is using the Calling SDK. | String | Yes | Yes |
2.b. | indicator | The type of service being used in the SDK. Its value should be CALLING , CONTACT_CENTER , or GUEST_CALLING . | ServiceIndicator | No | No |
2.c. | guestName | The guestName attribute is used in the SDK to indicate the name of the guest within a calling service. | String | No | Yes |
3. | logger | Logger configuration. | Object |
Logger Configuration
S.no | Attribute | Description | Data Type | Default Attribute? | Public Attribute? |
---|---|---|---|---|---|
1. | level | Maximum log level that should be printed to the console. Possible values:silent , error , warn , log , info , debug , trace | String | Yes |