A good chatbot can elegantly handle much of the communication with your users. In this tutorial, we'll build a chatbot with NativeChat, Twilio and SMS.
Over the last decade, the paradigm of communications has changed. We use to talk to each other face to face or on a phone, while lately we tend to communicate more and more through text. Furthermore, we find it more and more comfortable to communicate through channels like SMS, WhatsApp or Viber—each more or less popular depending on where in the world you are. As a result of which, companies need to adapt and provide different ways of communication channels for their customer and employees.
This is where chatbots come in handy. Chatbots can work 24/7, are great at handling repetitive tasks, and can provide a queue-free form of communication. A well-designed chatbot can handle a big portion of the communication with your users while leaving your trained employees to handle more complicated or unique scenarios.
In this article, we will look into building a chatbot with NativeChat, Twilio and SMS. We will start with an overview of how it all works, go through the required configuration, then we will add handling of straightforward questions and answers, and finally, we will create a step-by-step conversation that will guide a user to complete a bigger task.
NativeChat is used to define a chatbot—the kind of questions and answers that it should handle, and to build all step-by-step conversation flows.
Twilio is used as a connector that forwards messages from/to SMS to/from NativeChat.
In more detail: When a user sends an SMS message (1), Twilio forwards that message to NativeChat (2). NativeChat then analyses the message, prepares a response and sends the response (3) to the user via Twilio (4).
To configure the above workflow we need do some configuration both in Twilio and NativeChat.
This should be done as follows:Ste
Sign Up
If you don't have a Twilio account, you should first sign up for your free Twilio trial account. Twilio will give you a small preloaded balance to test Twilio's functionality. You will not be charged for Twilio phone numbers or usage until you upgrade.
Dashboard
Next, you should go to your Console Dashboard, which is your home for finding your Twilio credentials, checking your usage, procuring a phone number and more.
From the Console Dashboard, you should take note of ACCOUNT SID
and AUTH TOKEN
.
You can use the copy buttons to copy each value in the clipboard.
Twilio Messaging Service
Next, you should head to the Messaging Services page to create and configure a new Messaging Service. Go to Programmable SMS => Services.
To add a new service, press the big blue plus button.
Next, give your new service a name like NativeChat Chatbot Service.
Then set the use case to Chat Bot/Interactive 2-Way.
Finally, you need to head to the Messaging Service -> Numbers, and add an SMS capable Twilio number.
If you don't have an SMS capable Twilio number yet, you can press the blue plus button and select Buy a Number.
Once you have an SMS capable Twilio number, click on the Add an Existing Number link and select the number that you want to use.
Make a copy of your Twilio SMS number, as you will need it to configure your NativeChat project.
Sign Up
If you don't have a NativeChat account, you should create a free trial account.
Create Project
From the NativeChat console, create a new chatbot project.
Choose Blank Bot
, set the Name to ACME Ride
, and press Create bot button.
Trial Accounts Publish
If you are using a Trial Account then most likely the Twilio functionality won't be enabled for you out of the box.
But, don't worry this can be enabled quite easily. Go to the Publishing tab and press on the Contact Us link.
This will take you to our Contact Us page.
Just fill in a few details, and tell us that you want to use the Twilio Channel and someone from our team will enable it for you.
Publish
Once the Twilio Channel has been enabled for you, go to the Publishing tab, and press Publish
in the Twilio
segment.
Enter the Account SID
and the AUTH TOKEN
from Twilio Console Dashboard.
Then for the Telephone number
provide your Twilio SMS number
from your Twilio Messaging Service, and press the Update button.
Webhook Url
Finally, copy the provided Webhook Url
.
Webhook URL
Go back to Twilio Console.
On your mobile phone, open your SMS application and say "Hi" to your Twilio SMS number. In response you should get something like this:
And just like that we managed to configure both NativeChat and Twilio to let the user communicate with our chatbot via SMS.
Now, that we have a working configuration, it is time for us to make our chatbot do something useful.
As part of this article, we will build a chatbot for a taxi company. It will allow users to ask some questions about the services offered, and also take them through a conversation to book a taxi ride. To book a taxi ride the chatbot will ask the user a few questions—like pick-up & drop-off locations, date/time and type of service they need—and finally, it will send the booking request to a server.
Every chatbot should be capable of answering useful questions. Such as:
Q: Do you have electric cars?
A: Our company is environmentally conscious. All our cars are either electric or hybrid.
Q: What type of cars do you offer?
A: We offer:
Regular (4 passengers, 2 suitcases)
TaxiXL (6 passengers, 4 suitcases)
VIP (3 passengers, 3 suitcases, high comfort)
These are always two step interactions:
Training a chatbot to answer questions is fairly straightforward. It is all done from the Question answering page.
You can find the Question answering page in two ways:
Instructions
Open the Question answering page.
First, we need to create a new category to hold all our Questions and Answers.
Press the + Add a category button, set the category name to QnA
and press the Create category button.
Now, we can add our questions and answer in the QnA
category.
Press the + Add a question button and set the following fields to:
Note, the Group name is used as a name for each Question and Answer, which comes useful when we need to check logs to see which QnA was identified by the chatbot.
Then Save changes.
Like this:
Note that you can provide multiple expressions for the question. This tells the chatbot that there are many ways of invoking this QnA.
Also, you can provide multiple answers. In this case, the chatbot will randomly pick one of the answers and return it to the user. This way the chatbot could answer the same question in many ways.
Then you can add then second question, with the following fields to:
And Save changes.
Test
Finally, we can test our questions.
Open your SMS Client and ask:
Test with NativeChat
You can also test your chatbot in the NativeChat portal, with the built-in test window.
Note that the visual part of the chatbot might be slightly different, as this is used for testing web-based chatbots. For example, a web-based chatbot can display clickable buttons, while your SMS Client can only display buttons in the form of plain text. However, this should be perfectly fine to test that the flow works as expected.
Let's give it a go. Go to the test window which is located on the right-hand side, and send messages like:
And the chatbot should respond with a relevant answer.
Before we jump into building a step-by-step conversation to allow a user to book a ride, we should go over the possibilities and limitations of a SMS based chatbot.
The user can send via SMS:
20-June-2020
, Tomorrow
, or in 30 minutes
The chatbot in return can send:
SMS Clients cannot display conversational UI elements, like:
Now let's have some fun and build a step-by-step conversation that will help our users book a taxi.
The chatbot should ask the user for:
And finally, the chatbot should send the booking to the server, and provide the user with a confirmation number.
Whenever I need to add a new conversation, I like to start by creating a new conversation with a simple message like "Hello from Conversation Name." This way, I can quickly wire up all the important parts and test that the conversation gets triggered as expected. Then once I am happy with that, I can go back to the conversation, and start working on the conversation flow.
Create Conversation
Step-by-step conversations are defined in JSON, which we can work on at the Cognitive Flow page.
The Cognitive Flow page comes with a built-in Monaco Editor, which is just like any other powerful IDE. You get access to built-in code snippets (just start typing
conv
and the editor will show you a list of options), context-based IntelliSense (press CTRL+Space and you will see a list of relevant properties and code snippets) auto-formatting (each time you save your code, it will fix the formatting and indentation), syntax errors highlights, and most of the features that you would expect from an IDE like Visual Studio Code (highlight a word, press CMD+D or CTRL+D a few times and you can use the multi-edit feature).
The whole JSON structure is divided into three settings:
Let's add a new conversation to "conversations"
, which we will call "book-ride"
.
To do that we need to create a new line after line two (this is where we begin defining the "conversations"
property).
The easiest way to do that is to go to line two and press CTRL + Enter (on Windows) or CMD + Enter (on macOS).
Then we need to add the code for our new conversation. Start typing conv
—this will display a number of code snippets—and select conversation-goal
and press enter. This will generate the following code snippet for you:
"conversation-name": {
"type": "goal",
"steps": [
]
}
Now just change "conversation-name"
to "book-ride"
, and add a comma at the end of this code-snippet. Like this:
"book-ride": {
"type": "goal",
"steps": [
]
},
Next we need to add a message step that will say "Hello from book-ride." Go inside the steps array and start typing stme
and select step-message
. Then set the message text to "Hello from book-ride." The beginning of your JSON code should look like this:
{
"conversations": {
"book-ride": {
"type": "goal",
"steps": [
{
"type": "message",
"messages": [
"Hello from book-ride"
]
}
]
},
"welcome": {
...
How To—Video
Here is how I do that:
Conversation Trigger
Next, we need to instruct the chatbot when to trigger the book-ride
conversation.
To do that we need to configure Conversation Triggers, which are a set of expressions—like "I need a taxi" or "Book a ride"—that are linked with the book-ride
conversation.
Navigate to the Training tab, then to Conversation triggers
Press the [+ Add new] button
Set Conversation name to book-ride
Add Trigger expressions:
Save changes
The conversation trigger should look like this:
Test
Now we can test the chatbot with expressions like:
At this point, the chatbot should be able to react to the above expressions and start the book-ride
conversation to help the users book their taxi. The set of triggering expressions is something that should evolve over time.
As your chatbot matures, you need to keep updating them to make sure that your chatbot can handle most of the user's expressions.
It is important to understand what NLP is, how it works, and how to optimise your chatbot training. Understanding these concepts will help your build chatbots with a better understanding of user input. You can get started with the following two articles:
Great, now that the chatbot knows when to start the book-ride
conversation, it is time for us to tell it how to handle this conversation.
First the chatbot should ask for the pick-up location.
To do that we will need to use a question step, and remember user response as address-from
entity.
Entities are like variables. They are placeholders for the chatbot to remember what values have been provided.
Your chatbot will only ask for the entities that it doesn't have the values for.
Go back to the Cognitive flow page and remove the message step from book-ride
.
From inside the steps
array start typing stq
and select step-question
. You should get the following code snippet:
{
"type": "question",
"entity": "entity-name",
"entity-type": "",
"messages": [
"How to ask for entity?"
]
}
Set the following fields to:
entity
to address-from
—the chatbot will store the response in hereentity-type
to Text
—we tell the chatbot that we expect address-from
to be a free textmessages
to Where do you need the taxi from?
—this is the prompt message the chatbot will display to the userSave the code.
Code
The book-ride
conversation should look like this now:
"book-ride": {
"type": "goal",
"steps": [
{
"type": "question",
"entity": "address-from",
"entity-type": "Text",
"messages": [
"Where do you need the taxi from?"
]
}
]
},
How To—Video
Here is how I did it step by step:
Test
Now when you test the updated conversation, the chatbot should ask you the address-from
question, but it won't say anything once it receives the address. Like this:
Now we need to add another question step to ask for the drop-off location, and we should remember it in an entity called address-to
.
To do that, go to the closing curly bracket from the first step, add a comma, and start typing stq
and select step-question
.
Then set the following properties to:
entity
to address-to
entity-type
to Text
messages
to Where are you going to?
And Save the code.
Code
The book-ride
conversation should look like this now:
"book-ride": {
"type": "goal",
"steps": [
{
"type": "question",
"entity": "address-from",
"entity-type": "Text",
"messages": [
"Where do you need the taxi from?"
]
},
{
"type": "question",
"entity": "address-to",
"entity-type": "Text",
"messages": [
"Where are you going to?"
]
}
]
},
Test
Now, when we test book-ride
, the chatbot will ask you first for the address-from
and then for the address-to
. Like this:
Next, we should ask the user when they would like to get the taxi. In order to arrange a pick-up the chatbot needs to ask for both date and time.
Add a new question step to ask for the date, and remember the response in pick-up-date
, with the following fields:
entity
to pick-up-date
entity-type
to Date
messages
to When do you need the ride for?
Then add another question step to ask for the time, and remember the response in pick-up-time
, using the following fields:
entity
to pick-up-time
entity-type
to Time
messages
to What time?
Note that this time we are using
Date
andTime
as our Entity Types. Which are designed to handle date and time formats in a way that we speak. So you can provide the date by saying "14-July" or "Tomorrow" or even "Next week Friday," and for time you can say "at 3PM" or "midnight."
And Save the code.
Code
The additional two question steps should look like this:
{
"type": "question",
"entity": "pick-up-date",
"entity-type": "Date",
"messages": [
"When do you need the ride for?"
]
},
{
"type": "question",
"entity": "pick-up-time",
"entity-type": "Time",
"messages": [
"What time?"
]
}
The Date/Time Flow
The cool thing about using the Date and Time is that the chatbot can extract their values from the middle of a sentence. So when the user says "Pick me up at quarter past," the chatbot will extract the time and format it to 12:15.
Additionally, using the date and time together means that depending on what the user says, the chatbot can handle ask for the pick-up date/time in one or two steps.
For example, if the user says: "I want a taxi for tomorrow"—then the chatbot needs to ask a follow-up question to get the time.
However, when the user says something like: "This Friday at 3pm" or "In half an hour"—then there is no need for the follow-up question, as the chatbot can extract both pick-up-date
and pick-up-time
in one step.
Test
Now, you should be able to test the updated conversation, and the chatbot should ask you about the date and time for the booking. Like this:
User Time Zone
Whenever we need to ask the user for time, we should configure our chatbot to use our user's time zone.
This can be done by adding the "use-user-timezone": true
to settings
.
You can find the settings
at the bottom of the Cognitive Flow json.
Update the settings
to look like this:
"settings": {
"invalid-replies": [
"I am not sure I understood what you said."
],
"general-failure": [
"We are experiencing technical difficulties at this moment."
],
"previous-conversation-messages": [
"I am going back to the {{ conversationDisplayName }} now."
],
"use-user-timezone": true
},
Now, that we have a working chatbot with four questions, you are probably wondering how to make sure that we get the right data, and that the chatbot understands what we think it should.
There are two ways we could check what is going on:
Test Chatbot Debugging
The built-in NativeChat test window has a Debug tab. It allows you to see what the user said and what the chatbot understood.
For example, if you say: "Order a taxi tomorrow at 7am," then switch to the Debug tab and expand on Underestanding—you should see something like this:
From here we can see:
(1)—the chatbot recognized:
(2)—the Conversation is book-ride with 66% confidence
(3)—the Time is 07:00
(4)—the Date is 2020.06.17
The Debug tab gives a lot of information, which helps us understand what the chatbot understands, and what entities get updated. You should check this page whenever you work with new types of entities.
Video
Here is a short recording of me using the chatbot and checking the chatbot's understanding for each step.
Temporary Message Step
We could also display the entity values in a message step.
In the Cognitive Flow, when you start typing stme
and choose step-message
, you should get the following code snippet:
{
"type": "message",
"messages": [
"Your message"
]
}
You can provide your own message in the messages
property. So, the above step would say "Your message," each time the chatbot would get to this stage.
If we want to display a value of any entity, we need to use {{}}
interpolation. To display pick-up-time
, we need to something like this:
{
"type": "message",
"messages": [
"Pick up Time: {{pick-up-time}}"
]
}
Note that
messages
is an array, which allows us to provide multiple ways the chatbot can respond. How the chatbot uses each string might surprise you. For example, if we have a messages like:"messages": [ "One", "Two", "Three" ]
You might expect that it would say: (One) (Two) (Three). While the chatbot will pick randomly one of the strings and display it to the user. For example you might get: (Two)
In order to make the chatbot display each string, we need to use an array of arrays, like this:"messages": [ [ "One", "Two", "Three" ] ]
This way the chatbot will understand that it has to display all of the strings.
Go to the end of the book-ride
conversation, add a new message step (you can use stme
=> stem-message
code snippet), and update the messages
to look like this:
{
"type": "message",
"messages": [
[
"Address From: {{address-from}}",
"Address To: {{address-to}}",
"Pick up Date: {{pick-up-date}}",
"Pick up Time: {{pick-up-time}}"
]
]
}
Save the code.
Note that the message step will be displayed every time the chatbot will reach/go past this step. So, if we have another 2-3 steps in this conversation, the chatbot would display the same message each time the user provides new input.
You can learn more about the conversation flow and how to work around it from the tutorial.
Test
Let's test the updated conversation.
Once you reach the end of the conversation you should see something like this:
Before we create the next two question steps, we should talk about Entity Types.
Out of the box, NativeChat can handle the following entity-types: Text, Date, Time, Number, File, Location and Confirmation. This means that when a chatbot sees something that looks like a number—for example when the user says: "I need 3 seats"—it can automatically assign it to a Number entity.
To help our chatbot understand our users better, we can create our own Entity Types—that are relevant to our chatbot.
Payment Method
For example, our chatbot should be able to understand that when our users say "Cash" or "Card," they are providing it with the payment method.
To create a new Entity Type:
PaymentMethod
Now, we need to provide the entity values.
Cash
Card
Credit
And just like that you've created a new type (PaymentMethod
), which the chatbot should be able to recognize—when the user says "Cash" or "Card."
Synonyms allow us to provide other ways to recognise the same entity value.
In our example, saying Card or Credit will both match to Card value.
Test
You can test the new type from the built-in NativeChat test window.
Just switch to the Understanding tab, and type "I have a card and some cash," which should highlight Card
and Cast
with PaymentMethod
next to each of them.
Video
Here is how you can do the whole thing in one go:
Service Type
Next, we should add an Entity Type to let the user select a type of service they want.
However, this time instead of typing all the values manually, we will pull all the values from https://demoapis.com/sample/taxi/service-types, which returns the following values:
[
{
"name": "Standard",
"alt": "Regular",
"rate": 1.5
},
{
"name": "TaxiXL",
"alt": "Minivan",
"rate": 3.2
},
{
"name": "VIP",
"alt": "Limo",
"rate": 9.9
}
]
To do that:
ServiceType
https://demoapis.com/sample/taxi/service-types
{{name}}
—this is how we tell NativeChat that it should use the name property for the training{{alt}}
—this is how we tell NativeChat that it should use the alt property for the synonyms trainingThe Request configuration should look like this:
The ServiceType should display Entity values—Standard, TaxiXL, and VIP—and the Metadata for each item, like this:
Test
Now, you should be able to test ServiceType
with Understanding by saying: I am interested in Minivan or VIP.
As a result Minivan, and VIP should be matched, while Minivan should be linked to TaxiXL. Like this:
Great!!! We are only two questions away from booking a taxi for our customers.
Let's start with the easy one, and ask our users how they would like to pay.
Just like in the previous steps, we need to add a new question step, but this time we will use a custom entity type PaymentMethod, and then instruct the chatbot to display the available options.
Create a new question step at the end of the conversation, and set the following properties:
entity
to payment-method
entity-type
to PaymentMethod
messages
to How would you like to pay?
Display Available Payment Methods
Now, to instruct our chatbot to automatically display available payment methods, we need to add the display
property with type
set to quick-reply
.
Go to the closing ]
from messages
, add a ,
and start typing di
and choose display
.
Then start typing ty
and select type
.
Finally, start typing qu
and choose quick-reply
.
Code
The Payment Method question step should look like this:
{
"type": "question",
"entity": "payment-method",
"entity-type": "PaymentMethod",
"messages": [
"How would you like to pay?"
],
"display": {
"type": "quick-reply"
}
}
Test
Now, when we test the chatbot again, the chatbot asks the user for the preferred payment method and also displays the available values—Card and Cash. Like this:
For the final question, we should ask our customers to pick the type of service they need.
In order for the customer to make an informed decision, the chatbot should request quotes from the server, and use the carousel
display type, to show each available service with the price.
Quotes Service
To get the quotes, we can call demoapis.com/sample/taxi/quotes service, provide from and to query params: https://demoapis.com/sample/taxi/quotes?from=home&to=office, and we should get a response like this:
// https://demoapis.com/sample/taxi/quotes?from=home&to=office
[
{
"name": "Standard",
"quote": 6.9
},
{
"name": "TaxiXL",
"quote": 14.72
},
{
"name": "VIP",
"quote": 45.54
}
]
Question Step
First, add a new question step with the following fields set to:
entity
to service-type
entity-type
to ServiceType
messages
to What type of service would you like?
Next, we need to add display
with the configuration for a Carousel with data coming from a web service, like this:
"display": {
"type": "carousel",
"data-source": {
"endpoint": "https://demoapis.com/sample/taxi/quotes?from={{$encodeURI address-from}}&to={{&encodeURI address-to}}"
},
"template": {
"title": "{{name}}",
"subtitle": "{{$currency quote 'EUR'}}"
},
"button-text": "Select",
"title": "Show Services"
}
If you are curious, here is a quick explanation of each property:
data-source
—used to provide the parameters to call our service
address-from
and address-to
template
—used to pinpoint the properties used to display each item
title
—the main text field valuesubtitle
—the supporting text field valuebutton-text
to Select
—this property is used for web-based chatbots to display a select button under each item
title
to Show Quotes
—this property is used for web-based chatbots when carousel cannot be displayed, but a list picker is available
Code
The Service Type question step should look like this:
{
"type": "question",
"entity": "service-type",
"entity-type": "ServiceType",
"messages": [
"What type of service would you like?"
],
"display": {
"type": "carousel",
"data-source": {
"endpoint": "https://demoapis.com/sample/taxi/quotes?from={{$encodeURI address-from}}&to={{&encodeURI address-to}}"
},
"template": {
"title": "{{name}}",
"subtitle": "{{$currency quote 'EUR'}}"
},
"button-text": "Select",
"title": "Show Services"
}
},
Save your code and test.
Test
This time, the chatbot asks the user for the type of service, and presents three quotes for each type. Like this:
Web
If you try the same step in the web client, the chatbot will display the carousel like this:
Now that the chatbot collected all the entities from the user, all we have left is to send the request to the backend, book the service, and respond with a booking confirmation.
Book Service
To do that, we need to make a POST request to https://demoapis.com/sample/taxi/book
with Body properties:
from
—to be provided by address-from
to
—to be provided by address-to
type
—to be provided by service-type
payment
—to be provided by payment-method
date
—to be provided by pick-up-date
time
—to be provided by pick-up-time
In response, the service will return a JSON object like this:
{
"bookingRef": "S01575",
"from": "home",
"to": "office",
"service": "Standard",
"quote": 10.5,
"payment": "Card",
"date": "19-Jun-2020",
"time": "09:16 PM"
}
Webhook Step
To make such a request, we need to use a Webhook step.
At the end of the conversation, start typing stwe
and pick step-webhook
.
You should be presented with the following code snippet:
{
"type": "webhook",
"data-source": {
"endpoint": "https://",
"method": "POST",
"headers": {
"header name": "header value"
},
"payload": {
"key": "value"
}
}
}
First, let's configure the data-source
, to call the book service.
Update the following properties:
set endpoint
to https://demoapis.com/sample/taxi/book
remove headers
update payload
to include all the entities the chatbot collected from the user:
"payload": {
"from": "{{address-from}}",
"to": "{{address-to}}",
"type": "{{service-type}}",
"payment": "{{payment-method}}",
"date": "{{pick-up-date}}",
"time": "{{pick-up-time}}"
}
Next, we need to provide a response to the user. To do that we need to:
capture the result in an entity
—after the line with "type": "webhook",
add a new line with:
"entity": "book-response",
this instructs the chatbot to save the result of the POST request in book-response
.
display a confirmation message
— after the closing }
for data-source
, add a ,
and then a messages
property like this:
"messages": [
[
"OK, the {{service-type}} service is booked for you. Your reference number is {{book-response.bookingRef}}",
"The estimated price of {{$currency book-response.quote 'EUR'}} to be paid directly to the driver by {{payment-method}}.",
"Your driver will pick you up on {{$date pick-up-date pick-up-time 'DD-MMM [at] h:mm A'}}"
]
]
Code
The Webhook step should look like this:
{
"type": "webhook",
"entity": "book-response",
"data-source": {
"endpoint": "https://demoapis.com/sample/taxi/book",
"method": "POST",
"payload": {
"from": "{{address-from}}",
"to": "{{address-to}}",
"type": "{{service-type}}",
"payment": "{{payment-method}}",
"date": "{{pick-up-date}}",
"time": "{{pick-up-time}}"
}
},
"messages": [
[
"OK, the {{service-type}} service is booked for you. Your reference number is {{book-response.bookingRef}}",
"The estimated price of {{$currency book-response.quote 'EUR'}} to be paid directly to the driver by {{payment-method}}.",
"Your driver will pick you up on {{$date book-response.date book-response.time 'DD-MMM [at] h:mm A'}}"
]
]
}
Save your code and test.
Test
Finally, when the user provides the chatbot with all the necessary information, the chatbot should book the taxi, and display a confirmation message. Like this:
And just like that, we were able to build an SMS chatbot.
The chatbot is capable of handling a couple of FAQs and also guide a user through a taxi booking service.
Next Steps
There is a lot more that we could do with this service, like make use of user location to provide a pick-up location, respond with acknowledgements to user input, or implement input validation.
You can learn more about building chatbots from our comprehensive NativeChat Tutorial.
As reward for making it all the way to the end of this tutorial, I will show you how to make use of the user location to find a nearby address.
This can be done in two steps, which should be added to the beginning of the whole conversation.
Step 1
First, I use the following Question step:
{
"type": "question",
"entity": "location",
"entity-type": "Location",
"conditions": [
"{{$has location}}"
]
},
Note the following:
entity-type
is set to Location
—this means that when chatbot receives a location object, it will save it in the location
entitymessages
property, as this question step is not meant to be displayed to the user—I mean, we could actively ask the user to provide the location, but we don't have toconditions
property that makes sure that this step is never shown to the userStep 2
The second step is a Webhook step—which will only be triggered when the chatbot receives a location—which uses Google Maps Geolocation service.
{
"type": "webhook",
"entity": "address-from",
"data-source": {
"endpoint": "https://maps.googleapis.com/maps/api/geocode/json?latlng={{location.latitude}},{{location.longitude}}&key=YOUR_API_KEY",
"selector": "$.results[:1].formatted_address"
},
"conditions": [
"{{$has location}}"
],
"messages": [
"We can send a taxi to {{address-from}}"
]
},
Note the following:
location.latitude
and location.longitude
received in the previous stepkey
is not provided. If you want to make this step work, you will need to sign up to Google Maps Geolocation serviceselector
is used to drill down to the first formatted_address
returned from the geolocation serviceconditions
property ensures that this webhook step will only be triggered when we receive a location"entity": "address-from"
tells the chatbot to save the formatted_address
in the address-from
entity.
It is important that this whole step is placed before the question step that asks the user for the pick-up location. Because if the chatbot already has the address-from
then this webhook will not be executedHere is the whole code for this chatbot:
{
"conversations": {
"book-ride": {
"type": "goal",
"steps": [
{
"type": "question",
"entity": "address-from",
"entity-type": "Text",
"messages": [
"Where do you need the taxi from?"
]
},
{
"type": "question",
"entity": "address-to",
"entity-type": "Text",
"messages": [
"Where are you going to?"
]
},
{
"type": "question",
"entity": "pick-up-date",
"entity-type": "Date",
"messages": [
"When do you need the ride for?"
],
"reactions": {
"acknowledgements": [
"Sure, we can arrange something for {{#if ($has pick-up-time)}} {{$date pick-up-date pick-up-time 'DD-MMM [at] h:mm A'}} {{else}} {{$date pick-up-date 'DD-MMM'}} {{/if~}}"
]
}
},
{
"type": "question",
"entity": "pick-up-time",
"entity-type": "Time",
"messages": [
"What time?"
]
},
{
"type": "question",
"entity": "payment-method",
"entity-type": "PaymentMethod",
"messages": [
"How would you like to pay?"
],
"display": {
"type": "quick-reply"
}
},
{
"type": "question",
"entity": "service-type",
"entity-type": "ServiceType",
"messages": [
"What type of service would you like?"
],
"display": {
"type": "carousel",
"data-source": {
"endpoint": "https://demoapis.com/sample/taxi/quotes?from={{$encodeURI address-from}}&to={{&encodeURI address-to}}"
},
"template": {
"title": "{{name}}",
"subtitle": "{{$currency quote 'EUR'}}"
},
"button-text": "Select",
"title": "Show Services"
}
},
{
"type": "webhook",
"entity": "book-response",
"data-source": {
"endpoint": "https://demoapis.com/sample/taxi/book",
"method": "POST",
"payload": {
"from": "{{address-from}}",
"to": "{{address-to}}",
"type": "{{service-type}}",
"payment": "{{payment-method}}",
"date": "{{pick-up-date}}",
"time": "{{pick-up-time}}"
}
},
"messages": [
[
"OK, the {{service-type}} service is booked for you. Your reference number is {{book-response.bookingRef}}",
"The estimated price of {{$currency book-response.quote 'EUR'}} to be paid directly to the driver by {{payment-method}}.",
"Your driver will pick you up on {{$date pick-up-date pick-up-time 'DD-MMM [at] h:mm A'}}"
]
]
}
]
},
"welcome": {
"type": "support",
"steps": [
{
"type": "message",
"messages": [
"This is a welcome conversation for your chatbot."
]
},
{
"type": "conversation",
"conversation": "help",
"conditions": [
"{{$not ($has conversation) }}"
]
}
]
},
"help": {
"type": "support",
"steps": [
{
"type": "message",
"messages": [
[
"If you get stuck, you can always restart our conversation by typing 'restart'"
]
]
}
]
},
"restart": {
"type": "support",
"steps": [
{
"type": "message",
"messages": [
"Your conversation is restarted."
]
},
{
"type": "conversation",
"conversation": "welcome"
}
]
}
},
"settings": {
"invalid-replies": [
"I am not sure I understood what you said."
],
"general-failure": [
"We are experiencing technical difficulties at this moment."
],
"previous-conversation-messages": [
"I am going back to the {{ conversationDisplayName }} now."
],
"use-user-timezone": true
},
"commands": {
"NEXT-PAGE": [
"Next 5"
],
"RESTART": [
"restart"
]
}
}
Sebastian Witalec is a Senior Developer Advocate for Progress who specializes in Angular and NativeScript. He loves working on both serious and fun projects and one day he will use his robot army to conquer the world.
Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.
Learn MoreSubscribe to get all the news, info and tutorials you need to build better business apps and sites