Find a Flight Bot

Find a Flight Bot is a bot template available in the Library that demonstrates a sample SMS architecture. Use this template to create an SMS bot that interacts with end users and queries an external API with user-provided data to retrieve tailored information.

Getting Started: Download Bot

After logging into Communication Studio, you’ll be taken to the Bot Designer homepage, where all your bots (if you’ve created any) are listed. Click the blue plus button in the lower right corner, then select “Download from Library.”

Screen Shot 2018-04-26 at 12.14.17 PM

A window will open showing the available bot templates. Click the Download button beneath “Find a Flight Bot,” wait for the confirmation, and hit “Go to bot.”

Screen Shot 2018-04-30 at 2.51.36 PM

Alternatively, you can close the window and open the new bot from your Designer homepage.

Edit your flow

The sample use case demonstrated in this template is fairly simple, so there is only one flow in the bot.

Screen Shot 2018-04-30 at 2.52.13 PM.png

Click on this flow to open it up in view-only mode. Now you can see the tree of steps that make up the flow logic.

Screen Shot 2018-04-30 at 2.52.40 PM.png

Click the Edit button in the lower right corner to open the flow in edit mode and start configuring the steps.

Screen Shot 2018-04-30 at 2.56.00 PM.png

Next, we will go through and configure each step in the flow. The instructions that follow are identical to the “Find the Cheapest Flight” flow tutorial, so if you’ve already completed that, you can stop here.


As you may already know, every flow in the Designer must have some sort of gateway as its first step. The gateway step determines how and when the flow can be triggered to begin its execution, as well as setting up any necessary flow configuration for the channel in question. In this case, we are creating a flow that will be triggered by an incoming text message, so the gateway step in use is Wait for message (SMS). This will create an SMS listener on the bot phone number, so an SMS sent to that number will initiate the flow.

Click on the Wait for message (SMS) step, which, again, is the first step in the flow. The step is highlighted in red because it is missing some required configuration. In the sidebar on the right, you can see the step details, where the Bot phone number field is also highlighted in red. This indicates that the bot phone number is required for the step to function properly.

Screen Shot 2018-04-20 at 11.13.28 AM

Click the Bot phone number dropdown and select a number from the list. The step will now turn blue, indicating that the missing configuration has been provided.

Screen Shot 2018-04-20 at 11.14.08 AM

The next field in the step UI, End user phone number, has been left blank, because we want this flow to respond to anyone who might text in. Remember, this step is setting up our flow trigger(s). If you specify a phone number in this field, the flow will only initiate if it receives an incoming SMS from that phone number.  (For example, you might use this field if you wanted a flow to only respond to a certain group of VIP customers, or to a particular QA tester.)

The final field, Keyword or phrase, allows you to constrain the flow to only kick off if the text of an incoming SMS matches a certain text value. This is key if you want to have multiple flows listening on the same bot phone number, since two flows with the same trigger can’t logically coexist. (For example, you may have multiple tasks a user can perform by texting your business, and the different tasks are triggered by different keywords.)

In this case, the keyword required to initiate this flow is “flight”. You can change this if you wish, but we will leave it as-is for now. (Note that the keyword is not case-sensitive.)

At this point, if you haven’t saved any of your changes yet, click the Save button to do so. It’s a good idea to do this periodically.

Send First SMS

Now that the gateway has been configured, we can start looking at the way the flow will interact with the end user. The first step is to respond to their incoming message and let them know what the bot is capable of.

Click on the “welcome message” step, which uses the Send Message (SMS) step template. This step template allows you to send an SMS to the end user, then immediately proceed to the next step in the flow (without waiting for a response). Here, we are greeting the user with “Welcome! Thank you for using Travel Bot to find the best flight!” Feel free to adjust the content of this message to your liking.

Screen Shot 2018-04-20 at 11.17.31 AM.png

Notice that, since we set the bot phone number in our gateway, it has trickled down into this step and we don’t have to manually select it. The same will hold true for any other SMS steps in this flow, saving us time.

The End user phone number field, however, is not yet configured. In order to send this SMS to the person who initiated the flow, we need to use the merge field {incomingSMS} that the SMS gateway automatically creates. This merge field is a single JSON object that stores the number of the user who texted in, the bot number they texted, and the content of the message that triggered the flow.

Hover over the End user phone number field and click the Screen Shot 2018-04-17 at 12.06.27 PM button on the right to bring up the list of merge fields. Since this flow handles a lot of data, and some of the steps are already configured, the list of merge fields is quite long. Scroll until you see incomingSMS and select incomingSMS.endUserNumber.

Screen Shot 2018-04-20 at 11.20.46 AM

Great! Now this step is fully configured and will be able to send a text back to the user.

Prompt User for Departure City

Now, in order to start looking up flights for the user, we first need to know which city they’d like to fly out of. The Request Text Input (SMS) step allows us to do this by sending an SMS and waiting for a reply before continuing on with the flow. This step also saves the text content of the reply under a merge field, so the data can be used later in the flow.

Here, we are simply asking: “Please, enter the city you will travel from,” and saving the response under the merge field {currentLocation}.

Screen Shot 2018-04-20 at 11.27.49 AM

We also need to make sure that the step knows where to send the SMS. Click the Advanced dropdown to reveal the Bot phone number and End user phone number fields. Since we set these in the gateway and in a previous SMS step, the configuration has trickled down for us, saving us from having to set these parameters every time. However, it is good practice to just double-check them for correctness.

Screen Shot 2018-04-20 at 11.29.16 AM

Notify User of Lookup

Before we make our API call using {currentLocation}, we should let the user know that we received their response and there may be a short delay while we retrieve information. We use another Send Message (SMS) step to do this, since we want to proceed immediately to the next step in the flow after sending the SMS. Again, the bot and end user numbers have helpfully trickled down for us.

Screen Shot 2018-04-20 at 11.34.17 AM

Look Up Departure Airports

Now we can use the user’s choice of city to make an API call that will retrieve available airports in that city. The Make API request step allows you to make any kind of RESTful API request and save the response to a merge field for later use in the flow.

Here, we are querying the Skyscanner API to get the list of airports. The URL field shows the endpoint we will hit, and Request method lets us know that this is a GET request.

Screen Shot 2018-04-20 at 1.22.43 PM.png

Click the Query string parameters dropdown. There are two parameters being sent:  “apikey”, which authorizes our request, and “query”, where the {currentLocation} merge field is used to send the user’s choice of city.

Screen Shot 2018-04-20 at 1.46.09 PM

Finally, take a quick look at the Advanced dropdown. Note the merge field name: {outboundAirport} is where the results of this API call will be stored.

Screen Shot 2018-04-24 at 12.23.46 PM

Handle API Call Failures

Notice that the Make API request step has three exit branches. These branches represent different possible outcomes of the step. If the API call is successful, the step will exit via the “success” branch. If an error code is returned, the next step to execute will be the one under the “error” branch. Finally, in the event of a timeout, the “timeout” branch will come into play.

These three branches allow us to account for possible failures and take specific actions accordingly. First, we will look at the “error” and “timeout” branches before continuing down the “success” branch.

Under the “error” branch, there is a Send Message (SMS) step followed by a Go to step. This means that after sending an SMS, the flow will jump to some other step and continue executing from there. Here, the SMS step simply notifies the user of the error and asks for their city again.

Screen Shot 2018-04-20 at 1.53.35 PM

Then, the Go to a step in current flow step hops back over to “ask departure”. Notice how the “ask departure” step turns blue when you select the Go to step, so you can easily see where you are jumping to. If you click the dropdown here, you will see a searchable list of available flow steps to jump to.

Screen Shot 2018-04-20 at 1.55.41 PM.png

The “timeout” branch is almost identical, differing only in the content of the SMS message.

Screen Shot 2018-04-20 at 1.57.54 PM

Screen Shot 2018-04-20 at 1.58.30 PM

Under the “success” branch, the flow continues on with its subsequent tasks.

Check API Result

If we exit down the “success” branch, that means that the API call received a successful response. However, that doesn’t tell us whether there was actual data returned or not. The next step is a Check Condition step that looks at the returned list of departure airports to see whether any were returned. If the list is empty, there are no airports in the selected city, and this step will exit via the “else” branch. (Ignore the redness of the Check Condition step; that’s a false error.)

Similar to the failure branches of “Get airport departure list”, the “else” branch sends an informative SMS before jumping back to “ask departure.”

Screen Shot 2018-04-20 at 2.05.16 PM

On the other hand, if the list contains at least one airport, Check Condition will exit via “true.”

Fancy Code Step

The next step, “get the list”, does some fancy JavaScript to turn the list of airports into a human-readable piece of text with corresponding numbers for each list item. If you’re not a developer, just ignore this step. All you need to know is that it returns {outboundAirportList} which is text in the form of a numbered list that will be shown to the customer.

If you are a developer, this is the Execute JavaScript Code step, which allows you to use custom code to do whatever you want in a flow. Here, it’s pulling the list of airports from the API response, indexing it, and returning it as a string with the indices included.

Get User’s Choice of Airport

The next step, which uses the Request Text Input (SMS) template, displays the list of airports to the end user and asks for their selection in the form of a number. Their response is saved as {fromAirport}. Check the Advanced dropdown just to be sure, but Bot phone number and End user phone number should again have trickled down for you.

Screen Shot 2018-04-20 at 2.15.53 PM

Fancy Code Step

You can skip past this Execute JavaScript Code step. It’s just taking {fromAirport} (the user’s response for choice of airport) and using it to pull out the airport’s ID from {outboundAirport}. The airport’s ID will be used in a later API call.

Prompt User for Destination City

Now that we know the departure airport, we need to ask the user where they’re headed and see if there is a corresponding destination airport. Once again, the Request Text Input (SMS) step is used to prompt the user for a specific response, which in this case will be saved under the merge field {destination}. Here, the pre-filled text says “Now, please enter your destination point.” Feel free to edit this text, as we have. Don’t forget to check the Advanced dropdown to make sure the identifiers are present and correct.

Screen Shot 2018-04-24 at 12.31.59 PM.png

Look up Destination Airports

Once the user responds with a destination point, we must use that data to look up nearby airports. Once again, we will query the Skyscanner API, this time using {destination} as our “query” parameter instead of {currentLocation}.

Screen Shot 2018-04-24 at 12.37.24 PM.png

The API response will be stored under the merge field {inboundAirport}.

Screen Shot 2018-04-24 at 12.39.01 PM

Handle API Errors

Again, a combination of the Send Message (SMS) and Go to steps is used in the “error” and “timeout” branches to inform the user of a lookup failure and direct them back to the previous prompt.

Screen Shot 2018-04-24 at 12.40.48 PM

Screen Shot 2018-04-24 at 12.42.46 PM.png

Check API Result

Again, even if the API call to Skyscanner is a success, we need to make sure that there is actual data in the response for us to show to the end user. This “destination not empty” Check Condition step makes sure that there is at least one airport in the list of airports returned by Skyscanner.

Screen Shot 2018-04-24 at 12.45.01 PM

If the list is empty, there were no airports close to the user’s destination, and we notify the user as such with Send Message (SMS) before skipping back to a previous prompt step with Go to. Currently this jumps back to the original “ask departure” prompt to start the whole process over, but if you’d prefer to give the user the option to try another destination instead, you can change these steps accordingly.

Screen Shot 2018-04-24 at 12.47.12 PM.png

Fancy Code Step

This “get the list” Execute JavaScript Code step can be ignored; much like the earlier “get the list” step, it takes the list of airports from the API call, assigns each list item a corresponding number, and makes the list into a human-readable piece of text. This piece of text is stored under {inboundAirportList}.

Get User’s Choice of Airport (Destination)

Now, we use Request Text Input (SMS) again to present {inboundAirportList} to the user and ask for their numerical selection. This numerical selection will be saved under the merge field {toAirport}. Feel free to edit the messaging here.

Screen Shot 2018-04-24 at 12.56.56 PM

Fancy Code Step

Another JavaScript step you can ignore, “get iata” just gets the ID of airport selected by the user and stores it under {iataTo}.

Validate Departure and Arrival Choices

The “check cities match” Check Condition step compares the ID of the departure airport choice with the ID of the destination airport choice to make sure they differ from each other. Obviously, for our bot to find flights between two airports, they must not be the same airport.

Screen Shot 2018-04-24 at 1.07.41 PM.png

If the departure and destination airports happen to be the same, we use the Send Message (SMS) step to notify the user, then the Go to step to jump them back to the initial “ask departure” prompt.

Screen Shot 2018-04-24 at 1.19.58 PM.png

Prompt User for Dates

Again, Request Text Input (SMS) is used to ask for a departure date and save the response under {departureDate}. Note how the message content specifies the date format required for the later API call. (Advanced option: Add a Check Condition step to see whether the user formatted the date correctly; if not, re-prompt them.)

Screen Shot 2018-04-24 at 1.32.30 PM.png

The same step template is used to collect and store the return date:

Screen Shot 2018-04-24 at 1.33.48 PM.png

Notify User of Search in Progress

Since the next API call is more complex and may take a little longer, we use Send Message (SMS) to warn the user of the potential wait so they know the bot is still active.

Screen Shot 2018-04-24 at 1.36.13 PM

Retrieve Flights

Now we can finally use all this data we’ve collected from the user to find flights matching their criteria. Again, we will use Make API request to query the Skyscanner API.

Screen Shot 2018-04-24 at 1.39.46 PM.png

Unlike the previous API calls, merge fields are used here to dynamically insert data into the URL.

Screen Shot 2018-04-24 at 1.42.30 PM

The response will be saved under the merge field {flightFinder}.

Screen Shot 2018-04-24 at 1.44.01 PM

Also unlike previous API calls, the “error” and “timeout” legs don’t lead to re-prompts. The error leg simply sends a generic error SMS before ending the flow (meaning the user would need to text back in and start from the beginning), and the timeout leg sends an error message before jumping back to try the same API call with the same data again. Feel free to adjust the user experience by replacing the steps under these branches.

Screen Shot 2018-04-24 at 1.46.54 PM.png

Check Flight Results

If the API call is successful, we must check the result data to make sure there are flight options available. The “check flight exists” Check Condition step looks at the list of quotes returned in the API call ({flightFinder.Quotes}) to see if it has any members.

Screen Shot 2018-04-24 at 1.50.46 PM

If the list of quotes is empty, we notify the user and end the flow.

Screen Shot 2018-04-24 at 1.51.59 PM.png

Otherwise, we use a series of JavaScript steps to pull specific pieces of data out from the {flightFinder} API response and turn them into human-readable text.

Screen Shot 2018-04-24 at 1.53.16 PM

You can skip past all of these steps. Just know that they create merge fields for {originName}, {destinationName}, {minPriceQuote}, and {carrierName}, all of which will be used to show results to the user.

Show results to user

The last step in the flow, “flight found!”, uses Send Message (SMS) to display the details of the cheapest flight to the user. Notice the use of merge fields to dynamically construct the message.

Screen Shot 2018-04-24 at 1.58.18 PM.png

This is the end of the template, but you could enhance the user experience of this flow by adding additional steps; for example, try asking the user if they want to start over completely, or change certain variables, then jump them back in the flow accordingly.

Activate and test

Now all the steps are configured, and we are ready to try out our new flow! Go ahead and click the arrow next to the Save Flow button, and select Save & Activate.

Screen Shot 2018-04-24 at 2.01.06 PM

After about 30 seconds to a minute or so, you should see a notification that your activation was successful:

Screen Shot 2018-04-24 at 2.02.05 PM

Once the flow is active, you can test its functionality by sending an SMS with the keyword to the bot number.


After you have interacted with the flow, you can view the traffic. Exit edit mode on the flow and click on the Deployment tab in the sidebar. There you will see the Traffic dropdown where you can select a period of time and load the visual paths.

Screen Shot 2018-04-24 at 3.10.26 PM


You did it! Great job!