Gracefully Handle Long Running Asynchronous Operations in Twilio Studio

September 22, 2020
Written by
Alan Klein
Twilion
Reviewed by
Diane Phan
Twilion

Studio Async Long Running

As part of a customized interactive IVR experience built on top of Twilio, you often need to fetch data from external APIs. Sometimes, it may take that API more than ten seconds to respond to a request. Ten seconds is the maximum time the Studio HTTP Request Widget and Run Function Widget synchronously waits for a response. What then?

In this post, I’ll show you how you can architect a solution that will extend Studio’s response times beyond 10 seconds. We also use a Twilio conference with music on hold, to avoid extended periods of silence during these requests.

Prerequisites

In order to follow this tutorial, you will need:

  • Ngrok, the localhost tunneling tool, to allow you to run Express locally from your laptop for testing and development
  • Node.js
  • Sample Code
  • Express
  • A Twilio account and active number. If you don’t have an account, go ahead and create one now.

App Overview and Set Up

This blog will detail the steps you can take to initiate an asynchronous request to your API while placing the customer into an on hold conference – with music to avoid an awkward silence.

Once your API request is done running, you will initiate a response back to Twilio to end the customer holding conference. This allows Studio to continue on to the following Widget which requests the resulting data and continues on with your amazing customized experience. The JavaScript setTimeout method is used to simulate a long running asynchronous task.

Ngrok

Ngrok creates a tunnel to your local server and allows it to receive requests from the Internet (Twilio needs to communicate with your localized application). Applications that are not yet deployed, or are only running locally, frequently require a service like Ngrok for testing.

If you haven’t used Ngrok before, see these instructions for downloading and installing Ngrok. Otherwise, in a new command prompt tab or window, run the following command ngrok http 3000.

Make note of the unique Forwarding HTTPS address as we will make use of that URL later in the article.

Ngrok forwarding address in the terminal

Node

Use your command prompt to install Node.js using Homebrew. If you don’t want to use Homebrew to install Node.js, check out their complete download instructions.

Sample Code

Download or clone this GitHub repo to your desktop.

  1. Type cd blogAsyncStudio in your terminal to see the project files that were cloned from the GitHub repository.
  2. Rename the file, .env.example to .env and edit the file to contain your unique TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN. Be aware that if you have environmental variables with the same name, they will take precedence over what is defined in the .env file.
  3. Run the command npm install inside your project directory.
  4. Type npm start to start the Express server which is listening by default on port 3000. The Express server has two controllers provisioned, which will be used by the two HTTP Request Widgets in Studio. These controllers are accessed directly from the Internet via Ngrok which we set-up earlier.

Studio Flow

Instead of walking through the creation of the Studio Flow, you should import my JSON representation of the flow which you can find here. I’ll explain the flow in turn.

Import the Studio Flow

  1. To get started, go to the Manage Flows Studio page, then click either the red Create new Flow button if this is your first Flow, or the red plus (+) sign if it’s not your first Flow. Here are some screenshots of what your Studio Flow dashboard may look like:

Studio Flow creation when you don't have Flows created

Or

Studio Flow creation when you have Flows created in the past
  1. Give your Flow a name. I called mine "studioAsyncBlog". Scroll down and select Import from JSON from the menu and click on the Next button.
  2. Replace the contents of the edit box with the JSON that can be downloaded here, and click Next.

    You should see the Studio canvas rendered out for you, as shown below:

Studio Flow with an Async long-running result
  1. Keep in mind that with the Ngrok free plan, if you stop and restart Ngrok, your custom URL will change, so you may need to repeat these steps below.
  2. Edit the initiateAsyncRequest widget, and edit the REQUEST_URL by changing out the replaceme portion with your unique ngrok URL hostname from earlier. Your unique Ngrok URL should look similar to this after removing replaceme: "https://replaceme.ngrok.io/studioInitiateAsync". Click Save.
  3. Edit the getAsyncResultAfterCompletion widget, and edit the REQUEST_URL "https://replaceme.ngrok.io/studioGetAsyncData" by changing out the replaceme portion with your unique Ngrok URL hostname from earlier. Click Save.
  4. Click on the Publish button at the top of the page to publish the changes to your Studio Flow.

What is this Studio Flow doing?

This Studio flow in conjunction with the Express controllers simulates a long running asynchronous operation. Twilio Studio first greets the customer in the “initialGreeting” widget.

The HTTP Request Widget, initiateAsyncRequestcontacts the Express /studioInitiateAsync controller which simulates the initial asynchronous request. In our example, using the setTimeout method and a random timer between 5 and 15 seconds inclusive for the delay. This happens in the repo you downloaded, specifically app.js, when Studio calls the Express /studioInitiateAsync controller.

Studio then places the customer into a music on hold conference during this simulated operation to avoid extended silence.

Once the random timeout value simulating the long running asynchronous operation expires, the holding conference will be programmatically ended (handled by the endConference function). The Studio Connect Call To Widget, used to place the user into the conference, will continue on to the Connected Call Ended path as seen in the holdWhileAsyncProcessCompletes Flow.

The next widget, getAsyncResultAfterCompletion HTTP Request Widget, will fetch the results (static JSON in our test case) from the extended asynchronous operation for incorporation into the Studio Flow which will be recited by the WrapItUpReciteReturnedData Say/Play widget. In my example: Winston Klein.

Configure your Twilio number & test it out!

Now that your Studio flow is built, let’s configure your Twilio number to test it out.

Visit the Phone Numbers console.

If you’re not familiar with how to configure a Twilio number for incoming calls, click on the number you want to use for your “studioAsyncBlog” Studio flow in your Active Numbers here.  Scroll down to the “A CALL COMES IN” dropdown in the Voice & Fax section. Select Studio Flow.

Find the Flow you just created in the Select a Flow dropdown to the right. Follow the same process for “PRIMARY HANDLER FAILS”. Under “CALL STATUS CHANGES”, copy the Webhook URL under your Studio Flow Trigger Widget and paste it into the text box. Make sure that this is set to HTTP POST.

The last two steps are there to avoid stuck executions.

Studio webhook URL location on the canvas

Finally, click Save at the bottom, and you’ll be all set to test a call to your Twilio number.

Setting up a webhook with a Studio URL for Voice & Fax in Twilio

Go ahead and dial your Twilio phone number to hear this asynchronous operation in action.

Gracefully handling long running asynchronous operations in Twilio Studio

So much for those awkward silences! We’ve shown you how to leverage a Twilio conference and associated music on hold to place a customer into an entertaining holding pattern.  You have achieved the long running asynchronous operations Studio badge!

There may be a number of different ways to solve this challenge. I am curious what variations you come up with – for some ideas, you might find inspiration from Twilio’s Zack Pitts answering some questions about Studio. Happy building!

Alan Klein is a Principal Solutions Engineer based in Atlanta, GA Office. Alan is a Serverless solution champion and Programmable Voice and Elastic SIP Trunking SIP Expert at Twilio. He's currently focused on furthering his knowledge in Node.js and front-end development and sharing his knowledge with others. You can reach him at aklein [at] twilio.com or on Twitter at @SystemsEng.