/flex-dialpad-addon-plugin-with-sip

Adds agent to agent outbound call and external number transfer to Twilio Flex native dialpad

Primary LanguageJavaScript

Native Flex Dialpad Add-on

The native Flex Dialpad does not support agent-to-agent direct calls or external transfers yet. This plugin is meant to be an add-on to the native Flex Diapad, adding both agent-to-agent direct calls and external transfers.

Flex plugin

A Twilio Flex Plugin allow you to customize the appearance and behavior of Twilio Flex. If you want to learn more about the capabilities and how to use the API, check out our Flex documentation.

How it works

This plugin uses Twilio Functions and WorkerClient's createTask method to create conferences and TaskRouter tasks for orchestration in both agent-to-agent calls and external transfers features.

Agent-to-agent direct call

This part adds a call agent section to the Outbound Dialer Panel. In this section, there is a dropdown where you can select the agent you want to call directly. After selecting and clicking the call button, the WorkerClient's createTask method is used to create the outbound call task having the caller agent as target. When the task is sent to this agent, the AcceptTask action is overridden so we can control all the calling process. Then, we use the reservation object inside the task payload to call the caller agent. This reservation object is part of the TaskRouter Javascript SDK bundled with Flex. The URL endpoint of this call is used and pointed to a Twilio Function that retuns a TwiML which in turns create a conference and sets the statusCallbackEvent. The latter endpoint will be used to create the called agent task.

In the called side, the AcceptTask action is also overridden and a similar calling process is done. The difference is that the URL endpoint points to a different Twilio Function that returns a simple TwiML which in turns calls the conference created on the caller side.

This feature is based on the work on this project.

External transfer

When in a call, a "plus" icon is added to the Call Canvas where you can add a external number to the call. This action executes a Twilio Function that uses the Twilio API to make a call and add this call to the current conference. In the Flex UI side, the participant is added manually and both hold/unhold and hangup buttons are available.

This feature is based on the work on this project.

Configuration

Flex Plugin

This repository is a Flex plugin with some other assets. The following describing how you setup, develop and deploy your Flex plugin.

Setup

Make sure you have Node.js as well as npm installed.

Afterwards, install the dependencies by running npm install:

cd 

# If you use npm
npm install

Development

In order to develop locally, you can use the Webpack Dev Server by running:

npm start

This will automatically start up the Webpack Dev Server and open the browser for you. Your app will run on http://localhost:8080. If you want to change that you can do this by setting the PORT environment variable:

PORT=3000 npm start

When you make changes to your code, the browser window will be automatically refreshed.

Deploy

Once you are happy with your plugin, you have to bundle it in order to deploy it to Twilio Flex.

Run the following command to start the bundling:

npm run build

Afterwards, you'll find in your project a build/ folder that contains a file with the name of your plugin project. For example, plugin-example.js. Take this file and upload it into the Assets part of your Twilio Runtime.

Note: Common packages like React, ReactDOM, Redux and ReactRedux are not bundled with the build because they are treated as external dependencies so the plugin will depend on Flex to provide them globally.

TaskRouter

Before using this plugin you must first create a dedicated TaskRouter workflow or just add the following filter to your current workflow. Make sure it is part of your Flex Task Assignment workspace.

  • ensure the following matching worker expression: task.targetWorker==worker.contact_uri
  • ensure the priority of the filter is set to 1000 (or at least the highest in the system)
  • make sure the filter matches to a queue with Everyone on it. The default Everyone queue will work but if you want to seperate real time reporting for outbound calls, you should make a dedicated queue for it with a queue expression 1==1

Twilio Serverless

You will need the Twilio CLI and the serverless plugin to deploy the functions inside the serverless folder of this project. You can install the necessary dependencies with the following commands:

npm install twilio-cli -g

and then

twilio plugins:install @twilio-labs/plugin-serverless

How to use

  1. Setup all dependencies above: the workflow and Twilio CLI packages.

  2. Clone this repository

  3. Copy .env.example to .env.development and to .env.production and set the following variables:

    • REACT_APP_SERVICE_BASE_URL: your Twilio Functions base url (this will be available after you deploy your functions). In local development environment, it could be your localhost base url.
    • REACT_APP_TASK_CHANNEL_SID: the voice channel SID
    • REACT_APP_HOLD_CUSTOMER_ON_TRANSFER: the value of this variable should be the string true if you want to put the customer on hold when starting an external transfer. If you don't want that, you can remove this variable from your .env file.
    • REACT_APP_UNHOLD_CUSTOMER_ON_HANGUP: the value of this variable should be the string true if you want to unhold the customer automatically when just two participants are in the conference. If you don't want that, you can remove this variable from your .env file.

    If you are going to make external transfers using SIP, you can follow the above but using the .env.sip.example file. Following are the additional environment variables you can set:

    • REACT_APP_EXTERNAL_SIP: the SIP endpoint to call when a number with less than 4 digits is added as a external transfer. This 4 digits max number should represent your resource number in the other provider and it will replace any placeholder with the format {{<any_string>}} in the SIP endpoint.
    • REACT_APP_SIP_ATTR_<NAME>: if you want to add some attributes to the SIP call with variables found inside the Task attributes, you can add as many attributes as you want where NAME is the name of the attribute and the value of this environment variable is the task attribute name. Remember, every atttribute will be pass through SIP with the X- initials.
    • REACT_APP_EXTERNAL_QUEUES: a list of queue names split by ,(comma). This list is used to redirect transfers meant to TaskQueues with these names to the external SIP address.
    • REACT_APP_EXTERNAL_SIP_TARGET_PATTERN: the Regex Pattern in order to recognize which target number should use SIP. Note that if the number matches the regex, the number itself will be added to the SIP address placeholder as explained above. For example, let's say that every number with less than 4 digits should be consider an external extension. Therefore, this environment variable should have this value ^\d{1,4}$.

Note: Remember that both .env.development and .env.production is for front-end use so do not add any type of key/secret variable to them. When developing, the .env.development is used while the .env.production is used when building and deploying the plugin. Also, just variables starting with the name REACT_APP_ will work.

Note about SIP: by using the SIP transfer, this plugin just implements COLD transfer. It was more of a project decision than a technical problem because as SIP transfers are going to external infrastructure, it seems a good idea to keep at least on agent in the call if some communication issue happens.

Note about SIP and Workers: if you want to redirect transfers meant to a worker to a external number/sip, you can add the attribute external to the worker with external number/sip.

  1. run npm install

  2. copy ./serverless/.env.sample to ./serverless/.env and populate the appropriate environment variables.

  3. cd into ./serverless/ then run npm install and then twilio serverless:deploy (optionally you can run locally with twilio serverless:start --ngrok=""

  4. cd back to the root folder and run npm start to run locally or npm run-script build and deploy the generated ./build/plugin-dialpad.js to twilio assests to include plugin with hosted Flex

Known issues

  1. When in an agent-to-agent call, the transfer button is disabled.
  2. When in an agent-to-agent call, an external transfer is done correctly but the UI does not reflect what is going on.

Old issues

Note: If you are suffering from any of the following issues, please update your plugin with the last version of this repository.

  1. In the first versions, the environment variables were set by the UI Configuration (please refer to this documentation) but it was overriding some other variables with no relation to this plugin. Because of that, some features inside Flex were breaking. Now, there are two files (.env.development and .env.production) that gather all the environment variables.
  2. Before, the worker's contact_uri was extracted from manager.user.identity which has its problems depending on its format. It is now being extract from manager.workerClient.attributes.contact_url directly. (Thanks to @hgs-berlee who pointed that out and suggested this solution)
  3. Before, when in an external transfer, the hold/unhold button was executing these actions on the first participant and not on the correct one. Now, this is fixed.

Disclaimer

This software is to be considered "sample code", a Type B Deliverable, and is delivered "as-is" to the user. Twilio bears no responsibility to support the use or implementation of this software.