Using ACD module for call queuing

Using ACD module for call queuing

Call queuing is required to process inbound calls to PBX or contact center, callers are put into queues where they wait for a free operator and listening to some music. IVR usually notifies a caller about his position in a queue and about estimated waiting time. Operators have controls to set their availability, because some time is required to put data about the previous call before answering the next one. VoxImplant has all the capabilities required to build contact center functionality including ACD (Automatic call distributor) that can be controlled using the ACD Module. In this tutorial, we will build a simple queue that is being processed by operators.

The following steps are required to build our contact center:

1. Create VoxImplant application (let's call it callcenter)

2. Create application users (they will be our call center operators)

3. Create Queue (in Settings menu) for the application and attach users to it

4. Create VoxEngine Scenario that will handle inbound calls and put them in a queue

5. Create application Rule to use the scenario to process calls

6. Create operator's web interface using Web SDK

VoxImplant Application

Open the Applications section of the control panel and create a new application, call it "callcenter". Full name will look like

Users (operators)

Switch to the Users section of the application and create a few users, call them operator1, operator2, etc. Assign them to the application we created earlier.

Creating Queue

Open the Queues tab of an application and create a new queue with the following parameters, and attach users to it:

Creating VoxEngine Scenario

Switch to Scenarios tab and create a new scenario:

// Enable ACD module

let request;
let originalCall;
let callerid;
let statusInterval;

VoxEngine.addEventListener(AppEvents.CallAlerting, handleInboundCall);

// Handle inbound call
function handleInboundCall(e) {
  originalCall =;
  callerid = e.callerid;
  // Add event listeners
  originalCall.addEventListener(CallEvents.Connected, handleCallConnected);
  originalCall.addEventListener(CallEvents.PlaybackFinished, handlePlaybackFinished);
  originalCall.addEventListener(CallEvents.Failed, cleanup);
  originalCall.addEventListener(CallEvents.Disconnected, cleanup);
  // Answer call

// Terminate call and session
function cleanup(e) {
  if (request) {
    // Remove call from queue
    request = null;
  // terminate session

// Play music after TTS finish
function handlePlaybackFinished(e) {'');

// Get suffix for the number
function ordinal_suffix_of(i) {
  const j = i % 10,
    k = i % 100;
  if (j === 1 && k !== 11)
    return i + 'st';
  else if (j === 2 && k !== 12)
    return i + 'nd';
  else if (j === 3 && k !== 13)
    return i + 'rd';
  return i + 'th';

// Call connected
function handleCallConnected(e) {
  // Put the call into the queue 'MainQueue'
  request = VoxEngine.enqueueACDRequest('MainQueue', callerid);

  // Get call status in queue after it was put in the queue
  request.addEventListener(ACDEvents.Queued, (acdevent) => {

  // Notify caller about his position in the queue
  request.addEventListener(ACDEvents.Waiting, (acdevent) => {
    const minutesLeft = acdevent.ewt + 1;
    let minutesWord = ' minute.';
    if (minutesLeft > 1) {
      minutesWord = ' minutes.';
    originalCall.say(`You are ${ordinal_suffix_of(acdevent.position)} `
      +`in a queue. Represetative will answer you in ${(acdevent.ewt + 1)} ${minutesWord}`, 
      {“language”: VoiceList.Amazon.en_US_Joanna});

  // Connect caller with operator
  request.addEventListener(ACDEvents.OperatorReached, (acdevent) => {
    VoxEngine.sendMediaBetween(acdevent.operatorCall, originalCall);
    acdevent.operatorCall.addEventListener(CallEvents.Disconnected, VoxEngine.terminate);

  // No operators are available
  request.addEventListener(ACDEvents.Offline, (acdevent) => {
    originalCall.say('All operators are currently offline, please try to call again later.',
      {“language”: VoiceList.Amazon.en_US_Joanna});
    originalCall.addEventListener(CallEvents.PlaybackFinished, (e) => {

  // Get current call status in a queue every 30 seconds
  statusInterval = setInterval(request.getStatus, 30000);

Call it 'ACD' and save. Now we need to connect the scenario to our application and connect some phone number to the application.

Buying Phone Number

Open Numbers section of the control panel and buy a phone number there:

After that you will need to attach the phone number to our application – go to the application's Numbers tab, open the Available numbers, select a number and click Attach:

Now we need to forward calls from the phone number to our ACD scenario.

Creating Application Rule

Edit our callcenter application – open the Routing tab and click the New rule button, let's call it InboundCalls and put our phone number into the Pattern input field, then choose the ACD scenario in the Available scenarios list:

Click Create rule and you will see the new rule in the application rules list:

Building Web Client for Operators using Web SDK

The last thing we need to finish our simple contact center is to build simple web interface for operators. VoxImplant Web SDK has all required capabilities for that. To specify current operator status we will be using setOperatorACDStatus function, where we should pass one of the statuses from VoxImplant.OperatorACDStatuses. When ACD status set to VoxImplant.OperatorACDStatuses.Ready incoming calls from a queue will be forwarded to the operator. Here is the UI of our simple call center user agent app:User AgentYou can download the code of the web app from our GitHub account. Don't forget to specify your account name in the code of the app (see ACCNAME variable).

Tags:call centerpstnacd
B6A24216-9891-45D1-9D1D-E7359CEB8282 Created with sketchtool.


Add your comment

Please complete this field.


Sign up for a free Voximplant developer account or talk to our experts