-
Notifications
You must be signed in to change notification settings - Fork 57
Basics
When you open up your Stealth bot you will see the following file structure:
├── Gemfile
├── Procfile.dev
├── README.md
├── Rakefile
├── bot
│ ├── controllers
│ │ ├── bot_controller.rb
│ │ ├── catch_alls_controller.rb
│ │ ├── concerns
│ │ ├── goodbyes_controller.rb
│ │ └── hellos_controller.rb
│ ├── helpers
│ │ └── bot_helper.rb
│ ├── models
│ │ ├── bot_record.rb
│ │ └── concerns
│ └── replies
│ ├── catch_alls
│ │ └── level1.yml
│ ├── goodbyes
│ │ └── say_goodbye.yml
│ └── hellos
│ └── say_hello.yml
├── config
│ ├── boot.rb
│ ├── database.yml
│ ├── environment.rb
│ ├── flow_map.rb
│ ├── initializers
│ ├── puma.rb
│ ├── services.yml
│ └── sidekiq.yml
├── config.ru
└── db
└── seeds.rb
A Flow
is a general term to describe a complete interaction between a user and the bot. Flows are comprised of states
, like a finite state machine.
For example, if a user was using your bot to receive an insurance quote, the flow might be named quote
. Note: Stealth requires that flows be named in the singular form, like Rails.
A flow consists of the following components:
- A controller file, named in the plural form. For example, a
quote
flow would have a correspondingQuotesController
. - Replies. Each flow will have a directory in the
replies
directory in plural form. Again using thequote
flow example, the directory would namedquotes
. - An entry in
config/flow_map.rb
. TheFlowMap
file is where each flow and it's respective states are defined for your bot.
Flows can be generated using a generator:
stealth generate flow <NAME>
The FlowMap
file is where each flow and it's respective states are defined for your bot. Here is an example flow_map.rb
:
class FlowMap
include Stealth::Flow
flow :hello do
state :say_hello
state :ask_name
state :get_name, fails_to: :ask_name
state :say_wow, redirects_to: :say_hello
state :say_bye, redirects_to: 'goodbye->say_goodbye'
end
flow :goodbye do
state :say_goodbye
end
flow :catch_all do
state :level1
state :level2
end
end
Here we have defined three flows: hello
, goodbye
, and catch_all
. These are the default flows that are generated for you when you create a new bot. We have made a few changes above to highlight some functionality.
Each flow consists of an arbitrary number of states. These states should each have a corresponding controller action by the same name. States also support two additional options: fails_to
and redirects_to
which we explain below.
When you generate a new Stealth bot, it comes packaged with three default flows. While you will likely add many flows of your own, we recommend keeping these three flows as they encourage good bot building practices.
These two flows make up the entrance and exit of your bot. We include blank examples on how to greet (say hello) and sendoff (say goodbye) your users. You can customize these flows to work with the design of your bot.
Stealth also comes packaged with a catch_all
flow. Stealth CatchAlls are designed to handle scenarios in which the user says something the bot is not expecting or the bot encounters an error.
Error handling is one of the most important parts of building great bots. We recommend that bot designers and developers spend sufficient time building the CatchAll states.
See the Catch All (#catchalls) section for more information on how Stealth handles catch_all
flows.
The fails_to
option allows you to specify a state that a user should be redirected to in case of an error. The CatchAllsController
will still be responsible for determining how to handle the error, but by specifying a fails_to
state here, the CatchAllsController
is able to redirect accordingly.
A freshly generated bot will contain sample CatchAll
code for redirecting a user to a fails_to
state.
The fails_to
option takes a state name (string or symbol) or a session key. See Redis Backed Sessions (or in the FlowMap example above) for more info about session keys. By specifying a session key, you can fail to a completely different flow from the one where the error occurred.
The redirects_to
option allows you specify a state that a user should be redirected to. This is useful if you have deprecated a state where existing users may still have open sessions pointing to the state. When a user returns to your bot, they will be redirected to the flow and state specified by this option.
Like fails_to
above, the redirects_to
option takes a state name (string or symbol) or a session key. See Redis Backed Sessions (or in the FlowMap example above) for more info about session keys. By specifying a session key, you can fail to a completely different flow from the one where the error occurred.
Stealth recommends you use the say
, ask
, and get
prefix for your flow state names. It's not required, but it is a convention we have found helpful to keep state names under control. It also helps other developers on your team follow along more easily.
SAY Stealth actions are for saying something to the user.
For example:
def say_hello
send_replies
end
ASK Stealth actions are for asking something from the user.
For example:
def ask_weather
send_replies
update_session_to state: 'get_weather_reponse'
end
GET Stealth actions are for getting and parsing a response from the user.
For example:
def get_weather_reponse
if current_message.message == 'Sunny'
step_to state: "say_wear_sunglasses"
elsif current_message.message == 'Raining'
step_to state: "say_dont_forget_umbrella"
end
end