stealth 1.1.6 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +15 -54
  3. data/CHANGELOG.md +72 -0
  4. data/Gemfile +1 -1
  5. data/Gemfile.lock +49 -44
  6. data/LICENSE +4 -17
  7. data/README.md +9 -17
  8. data/VERSION +1 -1
  9. data/lib/stealth/base.rb +62 -15
  10. data/lib/stealth/cli.rb +1 -2
  11. data/lib/stealth/commands/console.rb +1 -1
  12. data/lib/stealth/configuration.rb +0 -3
  13. data/lib/stealth/controller/callbacks.rb +1 -1
  14. data/lib/stealth/controller/catch_all.rb +27 -4
  15. data/lib/stealth/controller/controller.rb +168 -49
  16. data/lib/stealth/controller/dev_jumps.rb +41 -0
  17. data/lib/stealth/controller/dynamic_delay.rb +4 -6
  18. data/lib/stealth/controller/interrupt_detect.rb +100 -0
  19. data/lib/stealth/controller/messages.rb +283 -0
  20. data/lib/stealth/controller/nlp.rb +50 -0
  21. data/lib/stealth/controller/replies.rb +178 -40
  22. data/lib/stealth/controller/unrecognized_message.rb +62 -0
  23. data/lib/stealth/core_ext.rb +5 -0
  24. data/lib/stealth/{flow/core_ext.rb → core_ext/numeric.rb} +0 -1
  25. data/lib/stealth/core_ext/string.rb +18 -0
  26. data/lib/stealth/dispatcher.rb +21 -0
  27. data/lib/stealth/errors.rb +12 -0
  28. data/lib/stealth/flow/base.rb +1 -2
  29. data/lib/stealth/flow/specification.rb +3 -2
  30. data/lib/stealth/flow/state.rb +3 -3
  31. data/lib/stealth/generators/builder/Gemfile +4 -3
  32. data/lib/stealth/generators/builder/bot/controllers/bot_controller.rb +42 -0
  33. data/lib/stealth/generators/builder/bot/controllers/catch_alls_controller.rb +2 -0
  34. data/lib/stealth/generators/builder/bot/controllers/goodbyes_controller.rb +2 -0
  35. data/lib/stealth/generators/builder/bot/controllers/hellos_controller.rb +2 -0
  36. data/lib/stealth/generators/builder/bot/controllers/interrupts_controller.rb +9 -0
  37. data/lib/stealth/generators/builder/bot/controllers/unrecognized_messages_controller.rb +9 -0
  38. data/lib/stealth/generators/builder/config/flow_map.rb +8 -0
  39. data/lib/stealth/generators/builder/config/initializers/autoload.rb +8 -0
  40. data/lib/stealth/generators/builder/config/initializers/inflections.rb +16 -0
  41. data/lib/stealth/generators/builder/config/puma.rb +15 -0
  42. data/lib/stealth/helpers/redis.rb +40 -0
  43. data/lib/stealth/lock.rb +83 -0
  44. data/lib/stealth/logger.rb +27 -18
  45. data/lib/stealth/nlp/client.rb +22 -0
  46. data/lib/stealth/nlp/result.rb +57 -0
  47. data/lib/stealth/reloader.rb +90 -0
  48. data/lib/stealth/reply.rb +17 -0
  49. data/lib/stealth/scheduled_reply.rb +3 -3
  50. data/lib/stealth/server.rb +3 -3
  51. data/lib/stealth/service_message.rb +3 -2
  52. data/lib/stealth/service_reply.rb +5 -1
  53. data/lib/stealth/services/base_reply_handler.rb +2 -2
  54. data/lib/stealth/session.rb +106 -53
  55. data/spec/configuration_spec.rb +9 -2
  56. data/spec/controller/callbacks_spec.rb +23 -28
  57. data/spec/controller/catch_all_spec.rb +81 -29
  58. data/spec/controller/controller_spec.rb +444 -43
  59. data/spec/controller/dynamic_delay_spec.rb +16 -18
  60. data/spec/controller/helpers_spec.rb +1 -2
  61. data/spec/controller/interrupt_detect_spec.rb +171 -0
  62. data/spec/controller/messages_spec.rb +744 -0
  63. data/spec/controller/nlp_spec.rb +93 -0
  64. data/spec/controller/replies_spec.rb +446 -11
  65. data/spec/controller/unrecognized_message_spec.rb +168 -0
  66. data/spec/dispatcher_spec.rb +79 -0
  67. data/spec/flow/flow_spec.rb +1 -2
  68. data/spec/flow/state_spec.rb +14 -3
  69. data/spec/helpers/redis_spec.rb +77 -0
  70. data/spec/lock_spec.rb +100 -0
  71. data/spec/nlp/client_spec.rb +23 -0
  72. data/spec/nlp/result_spec.rb +57 -0
  73. data/spec/replies/messages/say_msgs_without_breaks.yml +4 -0
  74. data/spec/replies/messages/say_randomize_speech.yml +10 -0
  75. data/spec/replies/messages/say_randomize_text.yml +10 -0
  76. data/spec/replies/messages/sub1/sub2/say_nested.yml +10 -0
  77. data/spec/reply_spec.rb +61 -0
  78. data/spec/scheduled_reply_spec.rb +23 -0
  79. data/spec/service_reply_spec.rb +1 -2
  80. data/spec/session_spec.rb +251 -12
  81. data/spec/spec_helper.rb +21 -0
  82. data/spec/support/controllers/vaders_controller.rb +24 -0
  83. data/spec/support/nlp_clients/dialogflow.rb +9 -0
  84. data/spec/support/nlp_clients/luis.rb +9 -0
  85. data/spec/support/nlp_results/luis_result.rb +163 -0
  86. data/spec/version_spec.rb +1 -2
  87. data/stealth.gemspec +6 -6
  88. metadata +83 -38
  89. data/docs/00-introduction.md +0 -37
  90. data/docs/01-getting-started.md +0 -21
  91. data/docs/02-local-development.md +0 -40
  92. data/docs/03-basics.md +0 -171
  93. data/docs/04-sessions.md +0 -29
  94. data/docs/05-controllers.md +0 -179
  95. data/docs/06-models.md +0 -39
  96. data/docs/07-replies.md +0 -114
  97. data/docs/08-catchalls.md +0 -49
  98. data/docs/09-messaging-integrations.md +0 -80
  99. data/docs/10-nlp-integrations.md +0 -13
  100. data/docs/11-analytics.md +0 -13
  101. data/docs/12-commands.md +0 -62
  102. data/docs/13-deployment.md +0 -50
  103. data/lib/stealth/generators/builder/config/initializers/.keep +0 -0
@@ -1,37 +0,0 @@
1
- ---
2
- title: Introduction
3
- ---
4
- Stealth includes everything you need to build amazing chatbots with tools you know and love.
5
-
6
- ## Assumptions
7
-
8
- These docs are designed for intermediate Ruby developers who want to get started with the Stealth framework.
9
-
10
- If you do not yet have experience with Ruby, we would recommend checking out these guides first:
11
-
12
- - [Official Ruby website](https://www.ruby-lang.org/en/documentation/)
13
- - [List of Free Programming Books](https://github.com/EbookFoundation/free-programming-books/blob/master/free-programming-books.md#ruby)
14
-
15
- ## What is Stealth?
16
-
17
- Stealth is an open source Ruby framework for conversational voice and text chatbots.
18
-
19
- Stealth is inspired by the Model-View-Controller (MVC) pattern. However, instead of calling them *Views* Stealth refers to them as *Replies* to better match the chatbot domain.
20
-
21
- - The [Model](#models) layer represents your data model (such as Account, User, Quote, etc.) and encapsulates the business logic that is specific to your bot. By default, Stealth uses [ActiveRecord](#models.active_record).
22
-
23
- - The [Controller](#controllers) layer is responsible for handling incoming requests from messaging platforms and providing and transmitting the response (reply).
24
-
25
- - The [Reply](#replies) layer is composed of "templates" that are responsible for constructing the respective response.
26
-
27
- In addition to being inspired by Model-View-Controller (MVC) pattern, Stealth as a few other awesome things built in for you.
28
-
29
- - **Plug and play services.** Every service integration in Stealth is a Ruby gem. One bot can support [multiple chat services](#messaging_integrations) (i.e. Facebook Messenger, SMS, Alexa, and more) and multiple NLP/NLU services.
30
-
31
- - **Advanced tooling.** From web servers to continuous integration testing, Stealth is built to take advantage of all the great work done by the web development community.
32
-
33
- - **Hosting you know.** Stealth is a Rack application. That means your bots can be [deployed](#deployment) using familiar services like Docker and Heroku.
34
-
35
- - **Ready for production.** Stealth already powers bots for large, well-known brands including: Humana, TradeStation, Haven Life, and BarkBox.
36
-
37
- - **Open source.** Stealth is MIT licensed to ensure you own your bot. More importantly, we welcome contributors to help make Stealth even better.
@@ -1,21 +0,0 @@
1
- ---
2
- title: Getting Started
3
- ---
4
-
5
- ## Ruby
6
-
7
- Stealth has been tested on Ruby (MRI) `2.4.x` and `2.5.x`. While we don't require any C-based Ruby gems, we haven't yet certified Stealth on other VMs (such as JRuby).
8
-
9
- ## Installation
10
-
11
- You can install Stealth via RubyGems:
12
-
13
- ```
14
- gem install stealth
15
- ```
16
-
17
- Next, you can create a new Stealth bot:
18
-
19
- ```
20
- stealth new <bot_name>
21
- ```
@@ -1,40 +0,0 @@
1
- ---
2
- title: Local Development
3
- ---
4
-
5
- ## Prerequisites
6
-
7
- Stealth bundles [Sidekiq](https://github.com/mperham/sidekiq) in order to process background jobs. Therefore, it is required to run Redis in order to boot up a Stealth server.
8
-
9
- ## Starting the Server
10
-
11
- Once you have made your current working directory your Stealth bot, you can install gems:
12
-
13
- ```
14
- bundle install
15
- ```
16
-
17
- To boot your bot:
18
-
19
- ```
20
- stealth server
21
- ```
22
-
23
- You can also use `stealth s`. This will use the [foreman](https://github.com/ddollar/foreman) gem to start the web server and Sidekiq processes together. Redis will have to be running for the server to start.
24
-
25
- That's it! You are now running Stealth.
26
-
27
- ## Introspectable Tunnels to localhost
28
-
29
- When developing locally, messaging services require access to your server in order to transmit user messages. We recommend downloading and using [ngrok](https://ngrok.com/download) to create a local tunnel to your development machine.
30
-
31
- 1. Download [ngrok](https://ngrok.com/download)
32
- 2. Start your Stealth server as detailed above.
33
- 3. Open up an ngrok tunnel to your Stealth server and port (default 5000) like this: `ngrok http 5000`. ngrok will output a unique ngrok local tunnel URL to your machine.
34
-
35
- When you provide your local ngrok URL to a messaging service, you will have to add `/incoming/<service>`. For example:
36
-
37
- * `https://abc1234.ngrok.io/incoming/facebook`
38
- * `https://abc1234.ngrok.io/incoming/twilio`
39
-
40
- More details on service specific settings can be found on the GitHub page for each service gem.
@@ -1,171 +0,0 @@
1
- ---
2
- title: The Basics
3
- ---
4
-
5
- ## Directory Structure
6
-
7
- When you open up your Stealth bot you will see the following file structure:
8
-
9
- ```
10
- ├── Gemfile
11
- ├── Procfile.dev
12
- ├── README.md
13
- ├── Rakefile
14
- ├── bot
15
- │   ├── controllers
16
- │   │   ├── bot_controller.rb
17
- │   │   ├── catch_alls_controller.rb
18
- │   │   ├── concerns
19
- │   │   ├── goodbyes_controller.rb
20
- │   │   └── hellos_controller.rb
21
- │   ├── helpers
22
- │   │   └── bot_helper.rb
23
- │   ├── models
24
- │   │   ├── bot_record.rb
25
- │   │   └── concerns
26
- │   └── replies
27
- │   ├── catch_alls
28
- │   │   └── level1.yml
29
- │   ├── goodbyes
30
- │   │   └── say_goodbye.yml
31
- │   └── hellos
32
- │   └── say_hello.yml
33
- ├── config
34
- │   ├── boot.rb
35
- │   ├── database.yml
36
- │   ├── environment.rb
37
- │   ├── flow_map.rb
38
- │   ├── initializers
39
- │   ├── puma.rb
40
- │   ├── services.yml
41
- │   └── sidekiq.yml
42
- ├── config.ru
43
- └── db
44
- └── seeds.rb
45
- ```
46
-
47
- ## Flows
48
-
49
- 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.
50
-
51
- 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.
52
-
53
- A flow consists of the following components:
54
-
55
- 1. A controller file, named in the plural form. For example, a `quote` flow would have a corresponding `QuotesController`.
56
- 2. Replies. Each flow will have a directory in the `replies` directory in plural form. Again using the `quote` flow example, the directory would named `quotes`.
57
- 3. An entry in `config/flow_map.rb`. The `FlowMap` file is where each flow and it's respective states are defined for your bot.
58
-
59
- Flows can be generated using a generator:
60
-
61
- ```
62
- stealth generate flow <NAME>
63
- ```
64
-
65
- ## FlowMap
66
-
67
- The `FlowMap` file is where each flow and it's respective states are defined for your bot. Here is an example `flow_map.rb`:
68
-
69
- ```ruby
70
- class FlowMap
71
-
72
- include Stealth::Flow
73
-
74
- flow :hello do
75
- state :say_hello
76
- state :ask_name
77
- state :get_name, fails_to: :ask_name
78
- state :say_wow, redirects_to: :say_hello
79
- state :say_bye, redirects_to: 'goodbye->say_goodbye'
80
- end
81
-
82
- flow :goodbye do
83
- state :say_goodbye
84
- end
85
-
86
- flow :catch_all do
87
- state :level1
88
- state :level2
89
- end
90
-
91
- end
92
- ```
93
-
94
- 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.
95
-
96
- 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.
97
-
98
- ## Default Flows
99
-
100
- 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.
101
-
102
- ## Hello & Goodbye
103
-
104
- 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.
105
-
106
- ## CatchAll
107
-
108
- 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.
109
-
110
- 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.
111
-
112
- See the Catch All (#catchalls) section for more information on how Stealth handles `catch_all` flows.
113
-
114
- ## fails_to
115
-
116
- 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.
117
-
118
- A freshly generated bot will contain sample `CatchAll` code for redirecting a user to a `fails_to` state.
119
-
120
- The `fails_to` option takes a state name (string or symbol) or a session key. See [Redis Backed Sessions](#sessions.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.
121
-
122
- ## redirects_to
123
-
124
- 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.
125
-
126
- Like `fails_to` above, the `redirects_to` option takes a state name (string or symbol) or a session key. See [Redis Backed Sessions](#sessions.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.
127
-
128
- ## Say, Ask, Get
129
-
130
- 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.
131
-
132
- ### SAY
133
-
134
- *SAY* Stealth actions are for _saying_ something to the user.
135
-
136
- For example:
137
-
138
- ```ruby
139
- def say_hello
140
- send_replies
141
- end
142
- ```
143
-
144
- ### ASK
145
-
146
- *ASK* Stealth actions are for _asking_ something from the user.
147
-
148
- For example:
149
-
150
- ```ruby
151
- def ask_weather
152
- send_replies
153
- update_session_to state: 'get_weather_reponse'
154
- end
155
- ```
156
-
157
- ### GET
158
-
159
- *GET* Stealth actions are for _getting_ and parsing a response from the user.
160
-
161
- For example:
162
-
163
- ```ruby
164
- def get_weather_reponse
165
- if current_message.message == 'Sunny'
166
- step_to state: "say_wear_sunglasses"
167
- elsif current_message.message == 'Raining'
168
- step_to state: "say_dont_forget_umbrella"
169
- end
170
- end
171
- ```
@@ -1,29 +0,0 @@
1
- ---
2
- title: Sessions
3
- ---
4
-
5
- A user of your bot can be in any single flow and state at any given moment. They can never be in more than one flow or state. For this reason, Stealth sessions are modeled using [finite state machines](https://en.m.wikipedia.org/wiki/Finite-state_machine).
6
-
7
- ## Finite State Machines
8
-
9
- Technically, each flow is its own state machine with its own states. Stealth, however, does not restrict the movement between states as rigidly. So while we find the state machine model helpful to learn sessions, don't spend too much time on Wikipedia!
10
-
11
- ## Redis Backed Sessions
12
-
13
- User sessions are stored in Redis. Each session is a lightweight key-value pair. The key is the user's ID from the service -- so for Facebook it may be a long integer value: `100023838288224423`. The value is the flow and state for the user separated by a "stabby" operator (`->`).
14
-
15
- So if for example a user with ID `100023838288224423` is currently at the `hello` flow and `ask_name` state, the value for the key would be: `hello->ask_name`.
16
-
17
- You likely won't be interacting with sessions directly since Stealth manages it automatically for you. We just present it here for clarity into how sessions work.
18
-
19
- ## Session Expiration
20
-
21
- By default, Stealth will not expire your user sessions. If you want your sessions to expire, you can set the `session_ttl` option:
22
-
23
- ```ruby
24
- Stealth.config.session_ttl = 2_592_000 # seconds (30 * 24 * 60 * 60)
25
- ```
26
-
27
- The above configuration setting will result in stale keys expiring in 30 days. Sessions that have been accessed reset the TTL (time to live). If you set a value of zero (the default), session expiration will be disabled.
28
-
29
- If a user returns to your bot after their session has expired, they will start again in the `Hello` flow or whatever you have defined to be your first flow.
@@ -1,179 +0,0 @@
1
- ---
2
- title: Controllers
3
- ---
4
-
5
- Controllers are responsible for handling incoming requests and getting a response back to the user (replies).
6
-
7
- ## Naming Conventions
8
-
9
- The controller's methods, also referred to as actions, must be named after the flow's states. So for example, given the flow:
10
-
11
- ```ruby
12
- flow :onboard do
13
- state :say_welcome
14
- state :ask_for_phone
15
- state :get_phone, fails_to: :ask_for_phone
16
- end
17
- ```
18
-
19
- The corresponding controller would be:
20
-
21
- ```ruby
22
- class OnboardsController < BotController
23
- def say_welcome
24
-
25
- end
26
-
27
- def ask_for_phone
28
-
29
- end
30
-
31
- def get_phone
32
-
33
- end
34
- end
35
- ```
36
-
37
- ## `bot_controller.rb`
38
-
39
- Every Stealth project comes with a default `bot_controller.rb`:
40
-
41
- ```ruby
42
- class BotController < Stealth::Controller
43
-
44
- before_action :current_user
45
-
46
- def route
47
- if current_session.present?
48
- step_to session: current_session
49
- else
50
- step_to flow: 'hello', state: 'say_hello'
51
- end
52
- end
53
-
54
- end
55
- ```
56
-
57
- All of your controllers will inherit from `BotController`:
58
-
59
- ```ruby
60
- class QuotesController < BotController
61
-
62
- end
63
- ```
64
-
65
- ## Route Method
66
-
67
- You can implement any method in `BotController`. Typically you will implement methods like `current_user` and methods for handling message payloads. The one method that `BotController` **must** implement is the `route` method.
68
-
69
- The `route` method is called for every incoming message. In its default implementation, the `route` method checks whether the user already has a session, and if so routes them to that controller and action. If the user does not yet have a session, it will route them to the `hello` flow and `say_hello` action.
70
-
71
- ## Stepping and Updating Sessions
72
-
73
- Stealth provides a few built-in methods to help you route a user through your bot.
74
-
75
- ## `step_to`
76
-
77
- The `step_to` method is used to update the session and immediately move the user to the specified flow and/or state. `step_to` can accept a *flow*, a *state*, or both. `step_to` is often used after a `say` action where the next action typically doesn't require user input.
78
-
79
- Some examples of the different parameters:
80
-
81
- `step_to flow: 'hello'` - Sets the session's flow to `hello` and the state will be set to the *first* state in that flow (as defined by the `flow_map.rb` file). The corresponding controller action in the `HellosController` would also be called.
82
-
83
- `step_to state: 'say_hello'` - Sets the session's state to `say_hello` and keeps the flow the same. The `say_hello` controller action would also be called.
84
-
85
- `step_to flow: 'hello', state: 'say_hello'` - Sets the session's flow to `hello` and the state to `say_hello`. The `say_hello` controller action of the `HellosController` controller would also be called.
86
-
87
- ## `update_session_to`
88
-
89
- Similar to `step_to`, `update_session_to` is used to update the user's session to a flow and/or state. It accepts the same parameters. However, `update_session_to` does not immediately call the respective controller action. `update_session_to` is typically used after an `ask` action where the next action is waiting for user input. So by asking a user for input, then updating the session, it ensures the response the user sends back can be handled by the `get` action.
90
-
91
- Some examples of the different parameters:
92
-
93
- `update_session_to flow: 'quote'` - Sets the session's flow to `quote` and the state will be set to the *first* state in that flow (as defined by the `flow_map.rb` file).
94
-
95
- `update_session_to state: 'ask_zip_code'` - Sets the session's state to `ask_zip_code` and keeps the flow the same.
96
-
97
- `step_to flow: 'quote', state: 'ask_zip_code'` - Sets the session's flow to `quote` and the state to `ask_zip_code`.
98
-
99
- ## `send_replies`
100
-
101
- `send_replies` will instruct the `Reply` to construct the reply and transmit them. Not all of your controller actions will send replies. Typically in `get` action, you'll get a user's response, perform some action, and then send a user to a new state without replying.
102
-
103
- The `send_replies` method does not take any parameters:
104
-
105
- ```ruby
106
- class ContactsController < BotController
107
- def say_contact_us
108
- send_replies
109
- end
110
- end
111
- ```
112
-
113
- This would render the reply contained in `replies/contacts/say_contact_us.yml`. See [Reply Variants](#variants) for additional naming options.
114
-
115
- ## `step_to_in`
116
-
117
- The `step_to_in` method is similar to `step_to`. The only difference is that instead of calling the respective controller action immediately, it calls it after a specified duration. It can also take a flow, state, or both.
118
-
119
- For example:
120
-
121
- ```ruby
122
- step_to_in 8.hours, flow: 'hello', state: 'say_hello'
123
- ```
124
-
125
- This will set the user's session to the `hello` flow and `say_hello` state in 8 hours after being called. It will then immediately call that responsible controller action.
126
-
127
- ## `step_to_at`
128
-
129
- The `step_to_at` method is similar to `step_to`. The only difference is that instead of calling the respective controller action immediately, it calls it at a specific date and time. It can also take a flow, state, or both.
130
-
131
- For example:
132
-
133
- ```ruby
134
- step_to_at DateTime.strptime("01/23/23 20:23", "%m/%d/%y %H:%M"), flow: 'hello', state: 'say_hello'
135
- ```
136
-
137
- This will set the user's session to the `hello` flow and `say_hello` state on `Jan 23, 2023 @ 20:23`. It will then immediately call that responsible controller action.
138
-
139
- ## Available Data
140
-
141
- Within each controller action, you have access to a few objects containing information about the session and the message the being processed.
142
-
143
- ### current_session
144
-
145
- The user's session is available to you at anytime using `current_session`. This is a `Stealth::Session` object. It has a few notable methods:
146
-
147
- `flow_string`: Returns the name of the flow.
148
- `state_string`: Returns the name of the state.
149
- `current_session + 2.states`: Returns a new session object 2 states after the current state. If we've passed the last state, the last state is returned.
150
- `current_session - 2.states`: Returns a new session object 2 states before the current state. If we've passed the first state, the first state is returned.
151
-
152
- ### current_message
153
-
154
- The current message being processed is available to you at anytime using `current_message`. This is a `Stealth::ServiceMessage` object. It has a few notable methods:
155
-
156
- `sender_id`: The ID of the user sending the message. This will vary based on the service integration.
157
- `timestamp`: Ruby `DateTime` object of when the message was transmitted.
158
- `service`: String indicating the service from where the message originated (i.e., 'facebook').
159
- `messsage`: String of the message contents.
160
- `payload`: This will vary by service integration.
161
- `location`: This will vary by service integration.
162
- `attachments`: This will vary by service integration.
163
- `referral`: This will vary by service integration.
164
-
165
- ### current_service
166
-
167
- This will be a string indicating the service from where the message originated (i.e., 'facebook' or 'twilio')
168
-
169
- ### has_location?
170
-
171
- Returns `true` or `false` depending on whether or not the `current_message` contains location data.
172
-
173
- ### has_attachments?
174
-
175
- Returns `true` or `false` depending on whether or not the `current_message` contains attachments.
176
-
177
- ### current_session_id (previously current_user_id)
178
-
179
- A convenience method for accessing the session's ID.