Skip to content

Quickstart Guide (Calling)

Sreekanth Narayanan edited this page Jan 1, 2024 · 24 revisions

Introduction

Welcome to the Quick Start Guide for the Calling module. This guide is designed to provide developers with a concise walkthrough to swiftly set up, authorize, and test the core calling functionalities within the module. 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!

Importing Calling SDK

To import the latest stable version of the Calling SDK one can use NPM or CDN.

NPM

The Calling SDK is available to be consumed from NPM.

npm install @webex/calling@3.0.0-next.21
(or)
yarn add @webex/calling@3.0.0-next.21
import Calling from 'webex/calling';

CDN

 A built, minified version of the Calling SDK is also provided. It can be accessed as mentioned below:

<script src="https://unpkg.com/webex@2.59.8-next.8/umd/calling.min.js"></script>

Initialize Calling SDK

To initialize Calling SDK, either a Webex object or Webex configuration is required.

Option 1

  1. Initialize Webex object. (Refer to importing and initializing the Web SDK to find the steps for this)
  2. Register with Webex Device Manager (WDM) and establish mercury connection.
  3. Pass Webex object and calling configuration as arguments and create new Calling instance which will initialize different client modules that it offers. (Refer to the table in the Calling Configuration section to identify Calling Configuration attributes)
const calling  = await Calling.init({webex, callingConfig});

Option 2

  1. Pass Webex configuration and calling configuration and create new Calling instance. (Refer to the attribute sectionto identify configuration attributes for Webex Configuration)
  2. Wait for Calling instance to be ready by listening for the event.
  3. Once the event is received, call the register API to trigger Webex Device Manager registration, establishing mercury connection and initializing the various client modules within Calling.
// Set 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"
    }
  };

// Set calling configuration

const callingConfig = {
  clientConfig : {
    calling: true,
    contact: true,
    callHistory: true,
    callSettings: true,
    voicemail: true,
  },
  callingClientConfig: {
    logger: {
      level: 'info'
    },
  },
  logger: {
    level: 'info'
  }
}  

// Create Calling object

const calling  = await Calling.init({webexConfig, callingConfig});
let callingClient;
calling.on("ready", () => {
    calling.register().then(() => {
        callingClient = calling.callingClient;	
    });
});

Authorize with Webex Calling

Initiating 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 easily 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 callingClient. Currently, only a single
// line is supported in the Calling package

const line = Object.values(callingClient.getLines())[0];

// Listen to the registered event from line

line.on("registered", (lineInfo) => {
    console.log("Line information: ", lineInfo);
});

line.register();

Calls

Starting an outgoing call to a designated destination involves a sequence of steps. Initially, capturing the microphone stream is paramount; 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.

const localAudioStream  = await Calling.createMicrophoneStream({audio: true});

const call = line.makeCall({
    type: 'uri',
    address: 'destination',
  });

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 to 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 on 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 these 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();

Note: Client objects will be created based on calling configuration inside Calling instance.

Calling Configuration

This is the example of calling configuration.

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,
		}
	},
	logger: {
		level: string
	}
}

Following tables cover different configuration attributes present inside calling configuration.

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
  • EU-CENTRAL
String No Yes
2. serviceIndicator String No Yes
2.a. domain Identifies which service is using Calling SDK String Yes Yes
2.b. indicator String No No
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. One of `silent error warn log
Clone this wiki locally