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.
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
- Sample Code
- 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.
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.
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.
Download or clone this GitHub repo to your desktop.
cd blogAsyncStudioin your terminal to see the project files that were cloned from the GitHub repository.
- Rename the file,
.envand edit the file to contain your unique
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.
- Run the command
npm installinside your project directory.
npm startto 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.
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
- 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:
- 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.
- 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:
- 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.
- Edit the
initiateAsyncRequestwidget, and edit the
REQUEST_URLby changing out the
replacemeportion 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.
- Edit the
getAsyncResultAfterCompletionwidget, and edit the
REQUEST_URL"https://replaceme.ngrok.io/studioGetAsyncData" by changing out the
replacemeportion with your unique Ngrok URL hostname from earlier. Click Save.
- 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
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:
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.
Finally, click Save at the bottom, and you’ll be all set to test a call to your Twilio number.
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.