The dialog is the main building block of conversations. All the code that forms the interaction between the bot and the user takes place inside a dialog.
dialog greeting do say "Hello!" ask "What is your name?" end
Inside a dialog you write statements, like
ask, et cetera,
to create the conversation. See the statement
reference for more detail on those. The
rest of document documents in which ways dialogs can be triggered.
Many dialogs will just have a name. The name you give a dialog is an
"internal" name, it is only used in the code. By using
invoke, you can let the named
dialog be executed, from another place.
dialog greeting do say "Hello!" invoke ask_name end dialog ask_name do ask "What is your name?" end
The platform checks the dialog names that you invoke. Invoke a dialog that does not exist is considered a syntax error, and the bot will refuse to run.
Dialogs can have triggers which are matched against user input to trigger the dialog. Dialogs are evaluated in order, meaning the first dialog that matches wins.
dialog trigger: "string" do end
Match sentences which contain the word "string". The original message
that caused the trigger is accessible in the variable named
message. The part of the string that was matched is stored in the
dialog trigger: "my name is #<name>" do end
Match sentences with "my name is" capturing everything after into variable
dialog trigger: "stop|quit|end" do end
Match sentences with the word "stop" or "quit" or "end"
dialog trigger: "num:#<n:[0-9]+>" do end
Match "num:" followed by a number and capture the number into variable
dialog event: "status_update" do say "We received an event." end
Match on an incoming event with the name "status_update". The event can come from the web client, from a webhook, from another bot or conversation, or even from yourself, when it had been scheduled to be sent in the future.
Other dialog triggers¶
The following dialog triggers are less frequently used.
A location trigger will match any location within a given radius:
dialog location: [lon: 4.893414, lat: 52.364909], radius: 3000 do say "Welcome in Amsterdam!" end
Note that the location has to be sent to the client explicitly, no background location tracking is going on.
Furthermore, an attachment trigger can fire as soon as a user sends a media file to the conversation:
dialog attachment: :image do show image attachment.url end
A powerful way to create variations of dialogs is to define the same dialog multiple times, but add a "guard clause" on it.
Inspired by Elixir's guards, Guard clauses are small expressions which can be added to the dialog definition. These guards decide whether the given dialog is matched or not:
dialog main when user.frontend == "slack" do say "Hello slack user!" end dialog main do say "Hello, other user" end
There can be multiple dialogs with the same name or trigger, but with different guard clauses. When looking up a dialog, the guard clauses get evaluated and the first dialog with a matching guard clause gets executed.
It is important to remember that dialog resolution is always processed in order, from the top to bottom of the files.
The following dialogs are automatically invoked by the platform, based on certain conditions that happen in the lifecycle of the conversation:
__main__ is the entrypoint for any conversation. For historical
purposes, the platform defines a
__main__ dialog, which invokes
dialog __main__ do say "Hello, I am a chatbot." end
dialog __root__ do say "What would you like to do?", expecting: [@get_quote, @reset_password] end
The root dialog is invoked the moment the bot's stack is
empty. Implement a
__root__ dialog to create a "menu"-like
interaction model where the bot keeps returning to a menu of options
when it is done processing its current dialog.
The unknown dialog is invoked when the user sends a message, but there are no dialogs that get triggered because of that message. This is a typical place to respond with something like "Sorry, I dont Understand, I'm just a chatbot".
dialog __unknown__ do say "I don't get what you mean..." end
When an event was sent into the conversation, but there was no event trigger defined for it.
When a user sends a location pin to the chat, but there was no location trigger that caught it.
When a user sends a image/video/audio file to the chat, but there was no attachment trigger that caught it.
This dialog is invoked when the stack is popped.
dialog main do ask "Choose a color", expecting: ["Red"] end dialog __unknown__ do say "That is not right." end dialog __returning__ do say "Back to the subject." end
In this case, the user is asked to type
"Red"; when he types
something else, first
__unknown__ is triggered, and then, just
before the question is repeated,
__returning__ is invoked as well.
Invoked when session timeout is reached. This can be used to clean up things, write information to a database, et cetera.
The standard timeout for a chat session is 15 minutes; it can be
changed setting the
Invoked when the conversation is resumed. After the conversation times
out, the conversation state is saved. Later, when the user returns to
the conversation, the conversation state is looked up again, and just
before the conversation resumes where it left off,
Invoked when an
ask statement has a
timeout: value, but when there
To set a global timeout on all
ask statements, define the
# Skips any question after 1 minute @ask_timeout "1m"
In the runtime, there are several variables exposed that contain information about the dialog stacking system.
dialog.stack- the current stack of dialog names, topmost dialog first. The name of the current dialog is
dialog.history- the list of dialog names that the user has passed through, ordered by most recently visited dialog.
dialog.last_user_utterances- the list of utterances (last messages) sent by the user; maximum 5; most recent first.
dialog.last_bot_utterances- the list of utterances (last messages) sent by the bot; maximum 5; most recent first.