# Queued Callback and Voicemail (Flex UI 1.x.x)

> \[!NOTE]
>
> This guide is only for Flex UI 1.x.x, which [reached End of Life on June 30, 2024](/docs/flex/flex-ui-eol-reference). To build on a current version, we recommend you [upgrade to Flex UI 2.x.x](/docs/flex/developer/ui/migration-guide) and install the ready-to-use [Queued Callback and Voicemail](https://flex.twilio.com/admin/plugins/library/JG87cbea81dd292d6724298cedbeb6aced) plugin. You must be logged in to Twilio Console to access the Flex Plugin Library.

## Overview

> \[!WARNING]
>
> This solution features sample code that is provided "as is" and is not production grade. The featured code does not account for edge case handling, scalability, and reliability. It is not covered under Twilio's [Service Level Agreement (SLA)](https://www.twilio.com/en-us/legal/service-level-agreement) and [support plans](https://www.twilio.com/en-us/support-plans).

> \[!WARNING]
>
> This solution supports Flex applications that can handle up to 1 call per second. We do not recommend this solution if your contact center exceeds that limit as you will run into API limits enforced by TaskRouter.

The Queued Callback and Voicemail for Flex solution helps Flex admins automate handling of agent callback requests from customers instead of having them wait longer in a queue. In this solution, the customer hears the callback menu options as soon as they call the number provisioned on your Flex application. Your contact center agents will receive the details including the requested callback number, and a localized time for the customer's inbound call.

The call is on hold for the period of time that you've configured within [queue-menu.protected.js](https://github.com/twilio-labs/plugin-queued-callbacks-and-voicemail/blob/main/serverless/functions/queue-menu.protected.js#L57-L59). When the time period expires, it will go on and route according to the workflow configuration.

## Architecture

User leaving a voicemail message or requesting a callback from an agent

![Flowchart of voicemail or callback request process with icons for user, phone, and agents.](https://docs-resources.prod.twilio.com/38b25528f8d169e41db385cadc66c1dde42814e1a244d0721db8155ace53edf3.png)

Agent calling the user

![Icons of agent, plugin, flex, routing, call, and user.](https://docs-resources.prod.twilio.com/bff7e7b7f7ea0431f78588cf758015755c0ff67f26d8182b8cce79231209e0be.png)

This solution leverages [Twilio Studio](/docs/studio) and [Twilio Functions & Assets (Serverless)](/docs/serverless/api) to give the customer options to register for a callback or leave a voicemail. When the customer decides on:

* **Registering for a callback**

  * A new Callback task is created in TaskRouter
  * The task is routed to the same workflow that the originating call was on, which means that it follows the same logic of routing calls to agents as the originating call placed by the customer
* **Leaving a voicemail message**
  * Limitation: 20-30 second audio recording and transcription
  * After the agent gives the customer a callback (3 attempts), they get the option to delete the recording

## Prerequisites

To deploy this solution, you will need:

* An active Twilio account with Flex provisioned. Refer to the [Flex Quickstart](/docs/flex/admin-guide/setup/account-creation) to create one.
* npm version 6.0.0 or higher (type `npm -v` in your terminal to check)
* A Node.js [long-term-support (LTS) version](https://nodejs.org/en/about/releases/) installed, 14 recommended (type `node -v` in your terminal to check)
* [Native Dialpad configured on your Flex application](/docs/flex/admin-guide/setup/voice/dialpad/enable)
* [Twilio CLI](/docs/twilio-cli/quickstart#install-the-twilio-cli) along with the [Flex CLI Plugin](/docs/twilio-cli/plugins#available-plugins) and the [Serverless Plugin](/docs/twilio-cli/plugins#available-plugins). Run the following commands to install them:

  ```bash
  # Install the Twilio CLI
  npm install twilio-cli@2.0 -g
  # Install the Serverless and Flex as Plugins
  twilio plugins:install @twilio-labs/plugin-serverless
  twilio plugins:install @twilio-labs/plugin-flex
  ```

> \[!NOTE]
>
> If you're running Linux, click on the Linux tab for the [Twilio CLI installation instructions](/docs/twilio-cli/quickstart#install-the-twilio-cli). If you're running Windows, make sure to run the Windows command prompt as an administrator to install the Serverles/Flex plugins for the Twilio CLI. The Windows commands in this guide use PowerShell (for Node.js/npm installation).

> \[!NOTE]
>
> To provision Twilio resources and deploy this solution using a script, skip to the [download step](#download-the-flex-queued-callbacks-and-voicemail-plugin). After installing the dependencies, run `node provision` and follow the instructions.
>
> Make sure to [activate the correct Twilio account](#step-1) before deploying the Flex plugin.
>
> After the script is complete, [enable the plugin on your Flex application](#enable-the-plugin-on-your-flex-application).

## Deployment Time

30-45 minutes

## Tested Flex Versions and Operating Systems

* Flex v1.18.1 - 1.30.1
* macOS / Unix
* Windows 10

## Configure your Flex Workspace

In order to use the solution, you need to prepare your **Flex Task Assignment** workspace.

### Retrieve your Flex settings

#### Step 1

Navigate to your Flex project in the [Twilio Console](https://www.twilio.com/console). Copy your **ACCOUNT SID** and **AUTH TOKEN**, and create a new Twilio CLI profile using those credentials:

```bash
twilio profiles:create
```

You will be prompted to enter your Twilio Account SID, Auth Token, and a shorthand identifier for your profile. When choosing a shorthand identifier, pick one that is meaningful and that you can remember. Once your profile has been created, activate it by running:

```bash
twilio profiles:use PROFILE_ID
```

Keep in mind that this account will be used for the rest of the deployment. In order to switch accounts, use the following command:

```bash
twilio profiles:use DIFFERENT_PROFILE_ID
```

### Step 2

Retrieve your **Flex Task Assignment** workspace ID:

```bash
twilio api:taskrouter:v1:workspaces:list

```

**Example Workspace SID**

```bash
SID                                      Friendly Name               Prioritize Queue Order
WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX       Flex Task Assignment        FIFO

```

To retrieve your Flex workspace SID from the Twilio Console, navigate to the **TaskRouter Dashboard**.

### Step 3

In the Twilio Console, select your Flex project and navigate to **All Products & Services > TaskRouter > Workspaces > Flex Task Assignment > Task Channels**. Create two task channels: one for callback and one for voicemail, so you can route the associated tasks to available agents.

![Task channels list including voice, chat, SMS, video, email, callback, and voicemail.](https://docs-resources.prod.twilio.com/5f45a73ecfc2a839707beae78af246c57e965f8a3fa6922708cbdbf2162e40e9.png)

> \[!NOTE]
>
> Make sure the unique names are set to "callback" and "voicemail". Also, before you proceed to the next step, note that this solution is for use cases that may see up to 1,000 callback requests and voicemails queued at any given time. If you require more than that, please contact our Professional Services team to work with you on the appropriate architecture design.

### Step 4

Create a task queue for callback and voicemail tasks named **CallbackandVoicemailQueue**. Make sure to pass `1==0` as the queue expression. This effectively "queues" callback and voicemail tasks.

### Step 5

Create workflow filters for each callback attempt. In this guide, we will modify the "Assign To Anyone" workflow and configure three filters. Run the following command in a command shell:

* For each filter, replace the `queue` fields in the JSON configuration with the SIDs of the "Callback and Voicemail" queue `(WQXXX)` and the "Everyone" queue `(WQYYY)`.
* Pass the "Assign to Anyone" workflow SID `(WWXXX)` to the `--sid`  CLI flag.
* Also set the default queue to the SID of the "Everyone" Queue `(WQYYY)`. Replace the `--workspace-sid` value `(WSYYY)`in the API request with your Flex Task Assignment workspace.

## macOS/Linux

```bash
CONFIGURATION=$(cat << EOF
{
  "task_routing": {
    "filters": [
      {
        "filter_friendly_name": "Attempt 1",
        "expression": "(taskType=='callback' OR taskType=='voicemail') AND placeCallRetry==1",
        "targets": [
          {
            "queue": "WQXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
            "timeout": 10
          },
          {
            "queue": "WQYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"
          }
        ]
      },
      {
        "filter_friendly_name": "Attempt 2",
        "expression": "(taskType=='callback' OR taskType=='voicemail') AND placeCallRetry==2",
        "targets": [
          {
            "queue": "WQXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
            "timeout": 20
          },
          {
            "queue": "WQYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"
          }
        ]
      },
      {
        "filter_friendly_name": "Attempt 3",
        "expression": "(taskType=='callback' OR taskType=='voicemail') AND placeCallRetry==3",
        "targets": [
          {
            "queue": "WQXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
            "timeout": 30
          },
          {
            "queue": "WQYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"
          }
        ]
      }
    ],
    "default_filter": {
      "queue": "WQYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"
    }
  }
}
EOF
)

twilio api:taskrouter:v1:workspaces:workflows:update --sid="WWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" --workspace-sid="WSYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY" --configuration "$CONFIGURATION"
```

## Windows

First, set your required Queue SIDs, your Flex workspace SID, and your "Assign to Anyone" workflow SID as environment variables.

```bash
set QUEUESID1=WQXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
set QUEUESID2=WQYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
set WORKSPACESID=WSYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
set WORKFLOWSID=WWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

```

To confirm that an environment variable has been set, run `echo %ENVVAR%`.

```bash
twilio api:taskrouter:v1:workspaces:workflows:update --sid=%WORKFLOWSID% --workspace-sid=%WORKSPACESID% --configuration="{ ""task_routing"": { ""filters"": [ { ""filter_friendly_name"": ""Attempt 1"", ""expression"": ""(taskType=='callback' OR taskType=='voicemail') AND placeCallRetry==1"", ""targets"": [ { ""queue"": ""%QUEUESID1%"", ""timeout"": 10 }, { ""queue"": ""%QUEUESID2%"" } ] }, { ""filter_friendly_name"": ""Attempt 2"", ""expression"": ""(taskType=='callback' OR taskType=='voicemail') AND placeCallRetry==2"", ""targets"": [ { ""queue"": ""%QUEUESID1%"", ""timeout"": 20 }, { ""queue"": ""%QUEUESID2%"" } ] }, { ""filter_friendly_name"": ""Attempt 3"", ""expression"": ""(taskType=='callback' OR taskType=='voicemail') AND placeCallRetry==3"", ""targets"": [ { ""queue"": ""%QUEUESID1%"", ""timeout"": 30 }, { ""queue"": ""%QUEUESID2%"" } ] } ], ""default_filter"": { ""queue"": ""%QUEUESID2%"" } }}"
```

**Example API Response**

```bash
SID                                                                 Friendly Name      Document Content Type
WWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                                  Assign to Anyone   null

```

To learn about configuring more complex workflows, see [Create a Workflow Resource](/docs/taskrouter/api/workflow#create-a-workflow-resource) and [Configuring Workflows: Complex Routing Example](/docs/taskrouter/workflow-configuration).

## Download the Flex Queued Callbacks and Voicemail Plugin

**Step 1:** In your browser, download the [plugin source code](https://github.com/twilio-labs/plugin-queued-callbacks-and-voicemail/archive/main.zip) and unzip the files in a local directory.

**Step 2:** From `plugin-queued-callbacks-and-voicemail-main`, run `npm install` to install the plugin package dependencies.

## Deploy your Twilio Functions and Assets

We will deploy the functions associated with the Callback and Voicemail Flex plugin to your Flex application. The functions are called from the plugin you will deploy in the next step and integrate with TaskRouter, passing in required attributes to generate the callback and voicemail tasks, depending on the customer selection while listening to the in-queue menu options.

### Pre-deployment Steps

**Step 1:** From the root directory of your copy of the source code, change into **serverless** and rename `.env.example` to `.env`.

## macOS/Linux

```bash
cd serverless && mv .env.example .env

```

## Windows

```bash
C:\Users\xxxxxx\plugin-queued-callbacks-and-voicemail-main> cd serverless && move .env.example .env
```

**Output**

```bash
1 file(s) moved.
```

**Step 2:** Open `.env` with your text editor and modify `TWILIO_WORKSPACE_SID` with your Flex Task Assignment SID.

```bash
TWILIO_WORKSPACE_SID=WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```

**Step 3:** Run `npm install` to install your Serverless dependencies.

To deploy your Callback and Voicemail functions and assets, run the following:

```bash
twilio serverless:deploy --assets

```

> \[!NOTE]
>
> When running on Windows, you may see an error with the Twilio Serverless deployment command. To work around the issue, set your `TWILIO_ACCOUNT_SID` and `TWILIO_AUTH_TOKEN` as environment variables. Refer to the previous section for examples of how to set an environment variable in Windows.

**Example Output**

```bash
Deploying functions & assets to the Twilio Runtime

Username ****************************
Password ****************************
Service Name plugin-queued-callbacks-voicemail-functions
Environment dev
Root Directory /Users/name/Downloads/plugin-queued-callbacks-and-voicemail-main/serverless
Dependencies axios, moment, moment-timezone, twilio-flex-token-validator
Env Variables TWILIO_WORKSPACE_SID
Runtime default

✔ Serverless project successfully deployed

Deployment Details
Domain: plugin-queued-callbacks-voicemail-functions-xxxx-dev.twil.io
Service:
plugin-queued-callbacks-voicemail-functions (xxxx)
Environment:
dev (xxxx)
Build SID:
xxxxx
Runtime:
node16
View Live Logs:
https://www.twilio.com/console/functions/editor/xxxx/environment/xxxx
Functions:
[private] https://plugin-queued-callbacks-voicemail-functions-xxxx-dev.twil.io/helpers
[private] https://plugin-queued-callbacks-voicemail-functions-xxxx-dev.twil.io/options
[protected] https://plugin-queued-callbacks-voicemail-functions-xxxx-dev.twil.io/inqueue-callback
[protected] https://plugin-queued-callbacks-voicemail-functions-xxxx-dev.twil.io/inqueue-voicemail
[protected] https://plugin-queued-callbacks-voicemail-functions-xxxx-dev.twil.io/queue-menu
https://plugin-queued-callbacks-voicemail-functions-xxxx-dev.twil.io/inqueue-utils
Assets:
https://plugin-queued-callbacks-voicemail-functions-xxxx-dev.twil.io/assets/alertTone.mp3
https://plugin-queued-callbacks-voicemail-functions-xxxx-dev.twil.io/assets/guitar_music.mp3
```

Copy and save the domain returned when you deploy a function. You will need it in the next step.

If you forget to copy the domain, you can also find it by navigating to [Functions > API > Environments](https://www.twilio.com/console/functions/api) in the Twilio Console.

**Debugging Tip:** Pass the `-l` or logging flag to review deployment logs. For example, you can pass `-l debug` to turn on debugging logs.

## Create a Studio Flow

**Step 1:** With your Flex project selected, navigate to the [Studio Dashboard](https://www.twilio.com/console/studio).

**Step 2:** Click **Create new Flow**. Give it a friendly name. For example, "CallbackVoicemailFlow".

**Step 3:** Select **Start from scratch**. Click **Next**.

**Step 4:** Drag and drop **Send to Flex** from the Widget Library on the right corner of the screen.

**Step 5:** Connect it with the **Incoming Call** trigger.

**Step 6:** Select the **Send to Flex** widget. In the **Config** tab, enter the following details:

* **Widget Name:** Friendly name for your Send to Flex widget
* **Workflow:** Assign to Anyone
* **Channel:** Voice
* **Attributes:** `{ "type": "inbound", "name": "{{trigger.call.From}}", "direction": "inbound" }`
* **URL Method:** `POST`
* **Hold Music TwiML URL:** `https://<deployment-domain-name>/queue-menu?mode=main` (Replace with the value you saved from the Functions and Assets deployment step)

**Step 7:** Click **Save** and **Publish** to apply your changes.

![Twilio Studio flow showing trigger for incoming message, call, and REST API leading to send\_to\_flex\_1 widget.](https://docs-resources.prod.twilio.com/c1635b44fdc1c94cd3ba274f1afe75d9ca9cb8241ad06294a1323a487e71e2d3.png)

## Associate Incoming Calls with Studio Flow

**Step 1:** Navigate to the [Phone Numbers](https://www.twilio.com/console/phone-numbers/incoming) page in the Twilio Console and click on the number associated with your Flex application.

**Step 2:** In **Voice Configuration**, update the incoming call trigger with the Studio Flow that you created.

![Voice configuration with regional routing active, using Studio Flow and Webhook.](https://docs-resources.prod.twilio.com/0bb5f80d6bc7cb5c0025999f7e5d5f6c3f76cbf84baee40c377ebc0d6d9ede4d.png)

**Step 3:** Click **Save configuration**.

## Deploy your Flex Plugin

Once you have deployed the function, it is time to deploy the plugin to your Flex application.

Run the following commands in the plugin root directory. We will leverage the Twilio CLI to build and deploy the Plugin. First, rename `.env.example` to `.env`.

## macOS/Linux

```bash
mv .env.example .env
```

## Windows

```bash
C:\Users\mbermudez\plugin-queued-callbacks-and-voicemail-main>move .env.example .env
```

**Output**

```bash
1 file(s) moved.
```

Open `.env` with your text editor and modify the `REACT_APP_SERVICE_BASE_URL` property to the Domain name you copied in the previous step. Make sure to prefix it with "https://".

```bash
 # .env REACT_APP_SERVICE_BASE_URL=https://plugin-queued-callbacks-voicemail-functions-xxx-dev.twil.io
```

When you are ready to deploy the plugin, run the following in a command shell:

```bash
twilio flex:plugins:deploy --major --changelog "Change plugin to use the latest Flex plugin for the Twilio CLI" --description "Queued Callback and Voicemail Plugin"

```

### Example Deployment Output

```bash
✔ Validating deployment of plugin plugin-queued-callbacks-and-voicemail
⠧ Compiling a production build of plugin-queued-callbacks-and-voicemail
✔ Compiling a production build of plugin-queued-callbacks-and-voicemail
✔ Uploading plugin-queued-callbacks-and-voicemail
✔ Registering plugin plugin-queued-callbacks-and-voicemail with Plugins API
✔ Registering version v1.0.0 with Plugins API

🚀 Plugin (private) plugin-queued-callbacks-and-voicemail@1.0.0 was successfully deployed using Plugins API

Next Steps:
Run $ twilio flex:plugins:release --plugin plugin-queued-callbacks-and-voicemail@1.0.0 --name "Autogenerated Release 1602189036080" --description "The description of this Flex Plugin Configuration" to enable this plugin on your Flex application


```

### Enable the Plugin on your Flex application

The previous step only deploys your plugin. You still need to enable the Plugin on your Flex application. To enable, run the following:

```bash
twilio flex:plugins:release --plugin plugin-queued-callbacks-and-voicemail@1.0.0 --name "Queued Callback and Voicemail" --description "Enabling queued callback and voicemail using Solution Guide"
```

### View plugin on the Plugins Dashboard

After running the suggested next step, navigate to the [Plugins Dashboard](https://flex.twilio.com/admin/) to review your recently deployed plugin and confirm that it's enabled for your contact center.

You are all set to test **Queued Callback and Voicemail** on your Flex application!

> \[!WARNING]
>
> Keep in mind that your Agents need to refresh their browsers in order to get the latest changes.

## Testing the solution

**Step 1:** Log in as an admin to the Flex instance where you deployed the plugin.

**Step 2:** Change your status to **Available** in the upper right corner of the Flex UI. This enables you to receive incoming calls and messages (SMS or chat).

**Step 3:** Call the number displayed on the landing page of your Flex application.

**Step 4:** Press "1" to listen to the menu options:

Press "1" again to remain in the queue.

Press "2" to receive a callback. Follow the callback number confirmation prompt.

Press "3" to leave a voicemail for the agent. Follow the prompt and leave your voicemail message. Press `*` when you're done. Note that your voicemail will be transcribed up to 30 seconds.

**Step 5:** When choosing the "callback" option, a preview callback task pops up on the Agent Desktop after the configured "timeout" setting in your workflow filter. In this example, we set it to 10 seconds.

* Accept the task. Upon accepting the task, the agent should see an **Info** panel with all the callback details as shown in the following image:

![Interface showing callback request details with options to place call or requeue.](https://docs-resources.prod.twilio.com/337f877dd5e158c92bd91101e43a1d3d6f69b9bff4d1b6e89d543bd03698575f.png)

* The agent can either place the callback immediately or forward the call to a queue of other agents.
* After wrapping up the call with the customer, the agent should also complete the callback task.

**Step 6:** When choosing the "voicemail" option, a preview voicemail task pops up on the Agent Desktop after the configured "timeout" setting in your workflow filter. In this example, we set it to 10 seconds.

* Accept the task. On accepting the task, the agent should see an Info panel with all the voicemail audio and text transcription as shown in the following image:

![Voicemail task with transcript 'Hi I need help with building Thank you.' and call options.](https://docs-resources.prod.twilio.com/8c2c472f77494e2cc3822c6ab58a185f785210086cb1cc9da4f49af98115003e.png)

* Similar to the callback task, the agent can either place the callback immediately or forward the call to a queue of other agents. After the third requeue attempt, you then have the option to delete the recording.
* After wrapping up the call with the customer, the agent should also complete the voicemail task.
