S
Sebastian Witalec
Guest
A good chatbot can elegantly handle much of the communication with your users. In this tutorial, we'll build a Viber chatbot with NativeChat.
Over the last decade, the paradigm of communications has changed. We used 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 Viber chatbot with NativeChat.
First, we will 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.
Configuration
Overview
To start working with NativeChat and Viber we need to set our development environment in the following steps:
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
Step 2: NativeChat—Get Proxy Command
After the project gets created, you will arrive to the Dashboard.
On the right hand side you will find the Test Window, which is where you can test your chatbot as you go.
One of the first things that you will see is a Proxy Command, which we can use to test our chatbot outside of NativeChat, like with Viber, Facebook Messenger and Amazon Alexa.
Take a note of the Proxy Command, you are going to use it in a moment.
Step 3: Viber—Add NativeChat Proxy Channel
Now, you need to add the NativeChat Proxy Channel in the Viber app. The Proxy Channel takes care of communication between your NativeChat chatbot and Viber.
On your mobile device open the Viber app, navigate to More (1) and start the QR Code Scanner (2).
Then scan the following QR Code.
Tap the Open now button.
Tap the Message.
Step 4: Viber—Connect to your Project
Now, that you have the Viber Proxy Channel, you need to connect it to your NativeChat project.
This is done with the Proxy Command that you saw in the step 2.
Copy the Proxy Command and run it in the Viber Proxy Channel.
Go to Viber and say "Hi." In response you should get something like this:
And just like that we managed to configure NativeChat with Viber to let the user communicate with our chatbot via Viber.
The Scenario—Taxi Service
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.
Add Q&A example
Every chatbot should be capable of answering useful questions. Such as:
These are always two step interactions:
Training a chatbot to answer questions is fairly straight forward. 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
Now, we can add our questions and answer in the
Press the + Add a question button and set the following fields to:
Then Save changes.
Like this:
Then you can add then second question, with the following fields to:
And Save changes.
Test in Viber
Finally, we can test our questions.
In Viber, ask:
Test with NativeChat
You can also test your chatbot in the NativeChat portal, with the built-in test window.
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.
What Can We Send/Receive via Viber
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 Viber based chatbot.
The user can send via Viber:
The chatbot in return can send:
Viber 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.
Create and Configure a New Conversation
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 whole JSON structure is divided into three settings:
Let's add a new conversation to
Then we need to add the code for our new conversation. Start typing
Now just change
Next we need to add a message step that will say "Hello from book-ride." Go inside the steps array and start typing
How To—Video
Here is how I do that:
Conversation Trigger
Next, we need to instruct the chatbot when to trigger the
The conversation trigger should look like this:
Test
Now we can test the chatbot with expressions like:
Improve Chatbot Understanding
At this point, the chatbot should be able to react to the above expressions and start the
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
Ask for Pick-Up Location (address-from)
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
Go back to the Cognitive flow page and remove the message step from
From inside the
Set the following fields to:
Save the code.
Code
The
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
Ask for Drop-Off Location (address-to)
Now we need to add another question step to ask for the drop-off location, and we should remember it in an entity called
To do that, go to the closing curly bracket from the first step, add a comma, and start typing
Then set the following properties to:
And Save the code.
Code
The
Test
Now, when we test
Ask for the Date and Time for the Pick-Up
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
Then add another question step to ask for the time, and remember the response in
And Save the code.
Code
The additional two question steps should look like this:
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
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
Update the
Debugging the Flow
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 chatbot's understanding for of each step.
Temporary Message Step
We could also display the entity values in a message step.
In the Cognitive Flow, when you start typing
You can provide your own message in the
If we want to display a value of any entity, we need to use
Go to the end of the
Save the code.
Test
Let's test the updated conversation.
Once you reach the end of the conversation you should see something like this:
Entities
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:
Now, we need to provide the entity values.
And just like that you've created a new type (
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
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:
To do that:
The 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
How to Pay
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:
Display Available Payment Methods
Now, to instruct our chatbot to automatically display available payment methods, we need to add the
Go to the closing
Code
The Payment Method question step should look like this:
Test
Now, when we test the chatbot again, the chatbot asks the user for the preferred payment method and also displays a button for each available value. Like this:
Get Quotes + What Type of Service
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
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:
Question Step
First, add a new question step with the following fields set to:
Next, we need to add
If you are curious, here is a quick explanation of each property
Code
The Service Type question step should look like this:
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:
And when you tap on the Show Services button, you will be presented with options like this:
Web
If you try the same step in the web client, the chatbot will display the carousel like this:
Send Booking Request to the Server
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
In response, the service will return a JSON object like this:
Webhook Step
To make such request, we need to use a Webhook step.
At the end of the conversation, start typing
First, let's configure the
Next, we need to provide a response to the user. To do that we need to:
Code
The Webhook step should look like this:
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:
Final Word
And just like that, we were able to build a Viber 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.
(Bonus)—Geolocation
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:
Note, the following:
Step 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.
Note, the following:
Here is the whole code for this chatbot:
Continue reading...
Over the last decade, the paradigm of communications has changed. We used 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 Viber chatbot with NativeChat.
First, we will 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.
Configuration
Overview
To start working with NativeChat and Viber we need to set our development environment in the following steps:
- Create a new NativeChat Project
- Get Proxy Command
- Add NativeChat Proxy Channel to Viber
- Run the Proxy Command
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.Step 2: NativeChat—Get Proxy Command
After the project gets created, you will arrive to the Dashboard.
On the right hand side you will find the Test Window, which is where you can test your chatbot as you go.
One of the first things that you will see is a Proxy Command, which we can use to test our chatbot outside of NativeChat, like with Viber, Facebook Messenger and Amazon Alexa.
Take a note of the Proxy Command, you are going to use it in a moment.
Step 3: Viber—Add NativeChat Proxy Channel
Now, you need to add the NativeChat Proxy Channel in the Viber app. The Proxy Channel takes care of communication between your NativeChat chatbot and Viber.
On your mobile device open the Viber app, navigate to More (1) and start the QR Code Scanner (2).
Then scan the following QR Code.
Note, you can find the QR code at the NativeChat channel for Viber page.
Tap the Open now button.
Tap the Message.
Step 4: Viber—Connect to your Project
Now, that you have the Viber Proxy Channel, you need to connect it to your NativeChat project.
This is done with the Proxy Command that you saw in the step 2.
Copy the Proxy Command and run it in the Viber Proxy Channel.
Note #1, you might need to email yourself the proxy command, so that you could access it on your mobile phone, or you could use Viber for Desktop.
First TestNote #2, you can only have one active project connected with the Proxy Channel, if you run a Proxy Command from another project, then the Proxy Channel will disconnect from the current project and connect with the new one.
Go to Viber and say "Hi." In response you should get something like this:
And just like that we managed to configure NativeChat with Viber to let the user communicate with our chatbot via Viber.
The Scenario—Taxi Service
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.
Add Q&A example
Every chatbot should be capable of answering useful questions. Such as:
Code:
Q: Do you have electric cars?
A: Our company is environmentally conscious. All our cars are either electric or hybrid.
Code:
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:
- (1) The user asks a question
- (2) The chatbot responds with an answer
- (-) No follow up required
Training a chatbot to answer questions is fairly straight forward. It is all done from the Question answering page.
You can find the Question answering page in two ways:
- From the Dashboard navigate to Question answering
- Select the Training tab, then select Question answering
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:
- Question: Do you have electric cars?
- Group name: electric-cars
- Answer: Our company is environmentally conscious. All our cars are either electric or hybrid.
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:
- Question #1: What services do you offer?
- Question #2: What cars do you offer?
- Group name: service-types
- Answer: We offer: Regular (4 passengers, 2 suitcases) TaxiXL (6 passengers, 4 suitcases) VIP (3 passengers, 3 suitcases, high comfort)
And Save changes.
Test in Viber
Finally, we can test our questions.
In Viber, ask:
- do you use electric cars?
- what type of services do you offer?
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.
Let's give it a go. Go to the test window which is located on the right-hand side, and send messages like:
- What types of cars do you have?
- Do you have electric cars?
And the chatbot should respond with a relevant answer.
What Can We Send/Receive via Viber
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 Viber based chatbot.
The user can send via Viber:
- Text—that one is rather obvious
- Dates and Time—chatbot can extract date/time from the user input, it can handle many formats like:
20-June-2020
,Tomorrow
, orin 30 minutes
- Files—any documents or images, the chatbot can even validate the contents of a picture (i.e. it could check if the picture looks like a receipt)
- Current Location—the user can send their current location, however this won't work with the live location
The chatbot in return can send:
- Text
- Images—as images/as links
- Files—as links
- Buttons
- List Pickers
Viber cannot display conversational UI elements, like:
- Carousels—instead it display a list picker
- Date Picker
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:
- pick-up and drop-off locations
- day and time of the pick-up
- a type of car they want
- how they intend to pay: cash or card—the assumption is that the payment should be made with the driver, and the driver should have a working card terminal for card payments.
And finally, the chatbot should send the booking to the server, and provide the user with a confirmation number.
Create and Configure a New Conversation
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 typingconv
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:
- conversations—this is where we define step-by-step conversations
- settings—global settings for the chatbot
- commands—used to define the expressions users need to say to move to the next page or restart the conversation
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:
Code:
"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:
Code:
"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:
Code:
{
"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 tobook-ride
Add Trigger expressions:
- Book ride
- Book taxi
- Order taxi
- Need ride
Save changes
The conversation trigger should look like this:
Test
Now we can test the chatbot with expressions like:
- Book a ride
- I want to order a taxi
- I need a ride
Improve Chatbot Understanding
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:
- What is Natural Language Processing (NLP)?
- 5 Handy Tricks for Improving Your Chatbot Understanding with NativeChat
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.Ask for Pick-Up Location (address-from)
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:
Code:
{
"type": "question",
"entity": "entity-name",
"entity-type": "",
"messages": [
"How to ask for entity?"
]
}
Set the following fields to:
entity
toaddress-from
—the chatbot will store the response in hereentity-type
toText
—we tell the chatbot that we expectaddress-from
to be a free textmessages
toWhere do you need the taxi from?
—this it the prompt message the chatbot will display to the user
Save the code.
Code
The
book-ride
conversation should look like this now:
Code:
"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:Ask for Drop-Off Location (address-to)
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
toaddress-to
entity-type
toText
messages
toWhere are you going to?
And Save the code.
Code
The
book-ride
conversation should look like this now:
Code:
"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:Ask for the Date and Time for the Pick-Up
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
topick-up-date
entity-type
toDate
messages
toWhen 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
topick-up-time
entity-type
toTime
messages
toWhat time?
Note, that this time we are usingDate
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:
Code:
{
"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:
Code:
"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
- Temporary Message Step
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:
- conversation
- pick-up-time — with Time assigned to it
- pick-up-date — with Date assigned to it
(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 chatbot's understanding for of 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:
Code:
{
"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:
Code:
{
"type": "message",
"messages": [
"Pick up Time: {{pick-up-time}}"
]
}
Note, thatmessages
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:
Code:"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:
Code:"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:
Code:
{
"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:
Entities
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:
- go to the Training tab, then select Entities.
- press the + Add new button
- set the name of the entity to
PaymentMethod
- keep the Training data source as Static—since we only have two values that we want to use, we can provide them manually
- press the Create button
Now, we need to provide the entity values.
- press the + Add new button—to add the first value
- set the value to
Cash
- Save changes
- add another value
- set the value to
Card
- set the synonym to
Credit
- Save changes
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:
Code:
[
{
"name": "Standard",
"alt": "Regular",
"rate": 1.5
},
{
"name": "TaxiXL",
"alt": "Minivan",
"rate": 3.2
},
{
"name": "VIP",
"alt": "Limo",
"rate": 9.9
}
]
To do that:
- go to the Entities page
- add new entity
- set the name to
ServiceType
- change the Training data source as Dynamic—as we want to dynamically load all the values
- set Endpoint URL to
https://demoapis.com/sample/taxi/service-types
- set Value template to
{{name}}
—this is how we tell NativeChat that it should use the name property for the training - set Synonym templates to
{{alt}}
—this is how we tell NativeChat that it should use the alt property for the synonyms training - press the Create button
The 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:How to Pay
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
topayment-method
entity-type
toPaymentMethod
messages
toHow 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:
Code:
{
"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 a button for each available value. Like this:
Get Quotes + What Type of Service
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 a list with 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:
Code:
// 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
toservice-type
entity-type
toServiceType
messages
toWhat 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:
Code:
"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
- Note, that we interpolate the value of
address-from
andaddress-to
- Additionally, we use $encodeURI to convert the address text to a URI-safe format
- Note, that we interpolate the value of
template
—used to pinpoint the properties used to display each item
title
—the main text field valuesubtitle
—the supporting text field value
title
toShow Quotes
—the name for a button that will display the list of values
button-text
toSelect
—this name for a button used to confirm the selected option
Code
The Service Type question step should look like this:
Code:
{
"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:
And when you tap on the Show Services button, you will be presented with options like this:
Web
If you try the same step in the web client, the chatbot will display the carousel like this:
Send Booking Request to the Server
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 byaddress-from
to
—to be provided byaddress-to
type
—to be provided byservice-type
payment
—to be provided bypayment-method
date
—to be provided bypick-up-date
time
—to be provided bypick-up-time
In response, the service will return a JSON object like this:
Code:
{
"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 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:
Code:
{
"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:
setendpoint
tohttps://demoapis.com/sample/taxi/book
removeheaders
updatepayload
to include all the entities the chatbot collected from the user:
Code:"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 anentity
—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 inbook-response
.
display a confirmationmessage
— after the closing}
fordata-source
, add a,
and then amessages
property like this:
Code:"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:
Code:
{
"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:
Final Word
And just like that, we were able to build a Viber 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.
(Bonus)—Geolocation
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:
Code:
{
"type": "question",
"entity": "location",
"entity-type": "Location",
"conditions": [
"{{$has location}}"
]
},
Note, the following:
- the
entity-type
is set toLocation
—this means that when chatbot receives a location object, it will save it in thelocation
entity - there is no
messages
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 to - we use a
conditions
property that makes sure that this step is never shown to the user
Step 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.
Code:
{
"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:
- the service uses
location.latitude
andlocation.longitude
received in the previous step - the
key
is not provided. If you want to make this step work, you will need to sign up to Google Maps Geolocation service - the
selector
is used to drill down to the firstformatted_address
returned from the geolocation service - the
conditions
property ensures that this webhook step will only be triggered when we receive a location - the
"entity": "address-from"
tells the chatbot to save theformatted_address
in theaddress-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 theaddress-from
then this webhook will not be executed
Here is the whole code for this chatbot:
Code:
{
"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"
]
}
}
Continue reading...