With their lightweight nature and ability to execute JavaScript, Functions are an excellent companion to Studio Flows. Whether you need to gather some data from an API or run any other custom code to fit your business logic, Functions help to fill in the gaps in your application that existing Studio widgets may not cover.
In order to ease the integration of Functions into your Studio Flows, Studio provides the Run Function widget. This widget, as the name implies, allows you to run a Twilio Function; you may pass in any desired parameters, and leverage any generated values later on in your Studio Flow.
To test this out we'll create a Studio Flow that accepts incoming text messages, prompts the user for their desired dog breed, and returns an MMS containing some text and an image of their requested breed (assuming they provided a valid breed). The finished flow would look like this:
request-breed
, and provide the following prompt:
_10Hello! Please respond with your requested dog breed to receive a photo! 🐶
Before we can proceed any further, we must first create the Function that we'll be calling in the next step of the Flow.
In order to run any of the following examples, you will first need to create a Function into which you can paste the example code. You can create a Function using the Twilio Console or the Serverless Toolkit as explained below:
If you prefer a UI-driven approach, creating and deploying a Function can be done entirely using the Twilio Console and the following steps:
https://<service-name>-<random-characters>-<optional-domain-suffix>.twil.io/<function-path>
test-function-3548.twil.io/hello-world
.
Your Function is now ready to be invoked by HTTP requests, set as the webhook of a Twilio phone number, invoked by a Twilio Studio Run Function Widget, and more!
Studio Widgets can handle the elements of gathering user input and sending back a response text. However, custom logic like handling breed names that contain spaces lives best inside of a Function.
Let's add some code to this Function. Install axios
as a Dependency, copy the following code example into your Function, save, and deploy your Service so that we can look more closely at how to integrate the Run Widget into a Studio Flow.
Note that this Function expects an input of breed
, and returns JSON that includes some text
and an image url
.
If you're curious about why we're using axios
and keywords such as async
and await
, be sure to read up on how to make API requests in Functions.
_41const axios = require('axios');_41_41exports.handler = async (context, event, callback) => {_41 // Any parameters provided to the Function will be accessible from `event`._41 // In Function Parameters, we defined `breed` as the inbound Body from_41 // our Send & Wait For Reply Widget. We can access that via `event.breed`._41 // To minimize the potential for errors, lowercase and trim the user input._41 let dogBreed = event.breed.toLowerCase().trim();_41_41 // The Dog API also supports sub-breeds, so we need to handle that case._41 // For example, if the user requests "Golden Retriever", we need to format_41 // the breed as "retriever/golden"._41 if (dogBreed.includes(' ')) {_41 const [subBreed, breed] = dogBreed.split(' ');_41 dogBreed = `${breed}/${subBreed}`;_41 }_41_41 const dogApiUrl = `https://dog.ceo/api/breed/${dogBreed}/images/random`;_41_41 try {_41 // Make the request to the Dog API. Remember to use `await` since this_41 // is an asynchronous request!_41 const response = await axios.get(dogApiUrl);_41 // Return the response to the Send & Wait For Reply Widget._41 return callback(null, {_41 text: `Here's an image of a ${event.breed}! 🐶`,_41 // The `message` property of the response is the URL of the dog image._41 url: response.data.message,_41 });_41 } catch (error) {_41 // Remember to handle any errors that may occur!_41 // In the case of a 404, the breed was not found._41 if (error.response && error.response.status === 404) {_41 return callback(null, {_41 text: `Sorry, we couldn't find any ${event.breed}s 🥲`,_41 });_41 }_41 // Otherwise, there may have been a network or server error._41 return callback(error);_41 }_41};
Once your prompt is complete, drag a Run Function widget onto the canvas, and connect it to the Reply
condition of the request-breed
widget.
You'll be able to provide a name for the widget (get-doge-image
), a configuration that will point this widget at your intended Function, and any parameters or arguments that you'd like to pass from the Flow to the Function when it's executed.
For this example, we'll point the Run Function widget at our Function, which was deployed to the doge
Service in a production environment, and the path to the Function is /get-doge
. Replace the Service, Environment, and Function configuration options with the values specific to the Function you created earlier.