Routes
Basically, routes map user inputs to actions which are in fact React Components.
User Inputs
The user input is captured as an object with the following fields:
- Type: the input type, which can be one of the following:
text
,postback
,audio
,image
,video
,document
,location
,referral
- Data: the raw text (or attachment URL if it's a media type).
- Payload: the input caused by the user clicking on a button or quick reply.
- Intent: the intent of the user according to your bot's NLU
Mapping User Inputs Into Actions
Every route, which is an entry in the routes' array can be defined in src/routes.js
:
Conceptually, a route is composed by a matching rule and an action. A matching rule looks like this: {attribute: test}
,
which basically means: "take that attribute from the user input and apply the test" if the test passes, the action defined in that route will be triggered.
There are 5 different ways of passing these tests:
- String: Perfect match
- Regexp: Pass the regular expression
- Function: Passes if the function returns true
- Input: Passes if the input satisfies the condition
- Session: Passes if the condition of the session is met
The rules are tested in such a way that, if the first rule matches, Botonic does not test other routes and executes the first action. If there are several matching rules in the same route, all of them have to pass to consider a match.
In the following example, the first rule matches if and only if we get the text start
and will trigger the action defined in src/actions/start.js
Below, another text rule (perfect match) to trigger the end
action
These rules use a case insensitive regexp to match text messages that contain a certain text. For the example below, will capture 'BUTTONS', 'Buttons', etc.
If you want to use regexp with grouped values, you need to upgrade Node to v.10
or above. This regular expression match age-{NUMBER}
where NUMBER can be any digit.
Then, in your component bye
, you can access this in req.params
Below, a few examples of how to capture different payloads.
It is posible to use a function test to capture any text that starts with bye
You can move to a new action if a condition over the user input is met
Otherwise, you can move forward to new actions depending on session values
Below, we see how to capture different intents
There's an implicit rule that captures any other input and maps it to
the 404
action, it would be the equivalent to:
Dynamic Routes
At times, you might want to render only some routes in function of a certain condition, so you can optionally define them as a function receiving the input and the session object.
Use Case
Sometimes you need to build a bot with deep flows, where users navigate a decision tree using interactive elements like buttons. This is useful when you want to guide the user through a conversation with predefined flows that consist of several steps.
The Childs example comes by default with an example.
This type of bots can include (but are not limited to):
- Surveys
- Pre-qualifiers of leads before human handoff
- On-boarding processes
- FAQs (when you have a very limited set of options)
Example
In the same way you build a website with a deep tree of routes, in botonic you make use of childRoutes
to describe actions that are only accessible if the user is in the parent route.
With the following example you will get an idea of how childRoutes
work.
src/routes.js
When the user starts the conversation the bot will ask whether he wants to eat pizza or pasta. You "force" the user to select either one by prompting two quick replies:
src/actions/hi.js
In the example, we have the option of pizza or pasta. This is where childRoutes
come in. Depending on the choice made, the chatbot will ask different things. When choosing pizza, the chatbot asks if you want sausage or bacon, whilst with pasta the chatbot will ask if you want cheese or tomato.
Because we are using childRoutes
, if you try to access the components of the ingredients directly you will not find them. Since the path to access is hi -> pizza / pasta -> ingredient
, it is guaranteed you can only choose the ingredient if you have chosen the food first.
Alternatives
In certain cases, it could be preferable to keep your 'routes.js' file as clean as possible. Let's take the previous example and replace the text attributes with payloads.
src/routes.js
You can achieve the same flows behavior by preserving the parent of the previous flow and doing the following modifications in the corresponding action files:
src/actions/hiFlow/hi.routes.js
Note that instead of a payload, you can use a path to trigger an action, for example path="pasta"
.
Working with URL Parameters
Since every action is linked in the same way as URLs, you can also pass them additional parameters to have a better control of your responses. So, the following piece of code will fill our params
object:
src/actions/hi.js
Then you can access its parameters in the following way in src/actions/pizza.js
:
src/actions/pizza.js