stealth 1.1.2 → 2.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.circleci/config.yml +18 -8
- data/CHANGELOG.md +100 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +49 -43
- data/LICENSE +4 -17
- data/README.md +9 -17
- data/VERSION +1 -1
- data/lib/stealth/base.rb +62 -13
- data/lib/stealth/cli.rb +1 -2
- data/lib/stealth/commands/console.rb +1 -1
- data/lib/stealth/configuration.rb +0 -3
- data/lib/stealth/controller/callbacks.rb +1 -1
- data/lib/stealth/controller/catch_all.rb +27 -4
- data/lib/stealth/controller/controller.rb +168 -49
- data/lib/stealth/controller/dev_jumps.rb +41 -0
- data/lib/stealth/controller/dynamic_delay.rb +4 -6
- data/lib/stealth/controller/interrupt_detect.rb +100 -0
- data/lib/stealth/controller/messages.rb +283 -0
- data/lib/stealth/controller/nlp.rb +50 -0
- data/lib/stealth/controller/replies.rb +179 -41
- data/lib/stealth/controller/unrecognized_message.rb +62 -0
- data/lib/stealth/core_ext.rb +5 -0
- data/lib/stealth/{flow/core_ext.rb → core_ext/numeric.rb} +0 -1
- data/lib/stealth/core_ext/string.rb +18 -0
- data/lib/stealth/dispatcher.rb +21 -0
- data/lib/stealth/errors.rb +12 -0
- data/lib/stealth/flow/base.rb +1 -2
- data/lib/stealth/flow/specification.rb +3 -2
- data/lib/stealth/flow/state.rb +3 -3
- data/lib/stealth/generators/builder/Gemfile +4 -3
- data/lib/stealth/generators/builder/bot/controllers/bot_controller.rb +42 -0
- data/lib/stealth/generators/builder/bot/controllers/catch_alls_controller.rb +2 -0
- data/lib/stealth/generators/builder/bot/controllers/goodbyes_controller.rb +2 -0
- data/lib/stealth/generators/builder/bot/controllers/hellos_controller.rb +2 -0
- data/lib/stealth/generators/builder/bot/controllers/interrupts_controller.rb +9 -0
- data/lib/stealth/generators/builder/bot/controllers/unrecognized_messages_controller.rb +9 -0
- data/lib/stealth/generators/builder/config/flow_map.rb +8 -0
- data/lib/stealth/generators/builder/config/initializers/autoload.rb +8 -0
- data/lib/stealth/generators/builder/config/initializers/inflections.rb +16 -0
- data/lib/stealth/generators/builder/config/puma.rb +15 -0
- data/lib/stealth/helpers/redis.rb +40 -0
- data/lib/stealth/lock.rb +83 -0
- data/lib/stealth/logger.rb +27 -18
- data/lib/stealth/nlp/client.rb +22 -0
- data/lib/stealth/nlp/result.rb +57 -0
- data/lib/stealth/reloader.rb +90 -0
- data/lib/stealth/reply.rb +17 -0
- data/lib/stealth/scheduled_reply.rb +3 -3
- data/lib/stealth/server.rb +4 -4
- data/lib/stealth/service_message.rb +3 -2
- data/lib/stealth/service_reply.rb +5 -1
- data/lib/stealth/services/base_reply_handler.rb +2 -2
- data/lib/stealth/session.rb +106 -53
- data/spec/configuration_spec.rb +9 -2
- data/spec/controller/callbacks_spec.rb +23 -28
- data/spec/controller/catch_all_spec.rb +81 -29
- data/spec/controller/controller_spec.rb +444 -43
- data/spec/controller/dynamic_delay_spec.rb +16 -18
- data/spec/controller/helpers_spec.rb +1 -2
- data/spec/controller/interrupt_detect_spec.rb +171 -0
- data/spec/controller/messages_spec.rb +744 -0
- data/spec/controller/nlp_spec.rb +93 -0
- data/spec/controller/replies_spec.rb +446 -11
- data/spec/controller/unrecognized_message_spec.rb +168 -0
- data/spec/dispatcher_spec.rb +79 -0
- data/spec/flow/flow_spec.rb +1 -2
- data/spec/flow/state_spec.rb +14 -3
- data/spec/helpers/redis_spec.rb +77 -0
- data/spec/lock_spec.rb +100 -0
- data/spec/nlp/client_spec.rb +23 -0
- data/spec/nlp/result_spec.rb +57 -0
- data/spec/replies/messages/say_msgs_without_breaks.yml +4 -0
- data/spec/replies/messages/say_randomize_speech.yml +10 -0
- data/spec/replies/messages/say_randomize_text.yml +10 -0
- data/spec/replies/messages/sub1/sub2/say_nested.yml +10 -0
- data/spec/reply_spec.rb +61 -0
- data/spec/scheduled_reply_spec.rb +23 -0
- data/spec/service_reply_spec.rb +1 -2
- data/spec/session_spec.rb +251 -12
- data/spec/spec_helper.rb +21 -0
- data/spec/support/controllers/vaders_controller.rb +24 -0
- data/spec/support/nlp_clients/dialogflow.rb +9 -0
- data/spec/support/nlp_clients/luis.rb +9 -0
- data/spec/support/nlp_results/luis_result.rb +163 -0
- data/spec/version_spec.rb +1 -2
- data/stealth.gemspec +6 -6
- metadata +83 -39
- data/docs/00-introduction.md +0 -37
- data/docs/01-getting-started.md +0 -21
- data/docs/02-local-development.md +0 -40
- data/docs/03-basics.md +0 -171
- data/docs/04-sessions.md +0 -29
- data/docs/05-controllers.md +0 -179
- data/docs/06-models.md +0 -39
- data/docs/07-replies.md +0 -114
- data/docs/08-catchalls.md +0 -49
- data/docs/09-messaging-integrations.md +0 -80
- data/docs/10-nlp-integrations.md +0 -13
- data/docs/11-analytics.md +0 -13
- data/docs/12-commands.md +0 -62
- data/docs/13-deployment.md +0 -50
- data/lib/stealth/generators/builder/config/initializers/.keep +0 -0
data/lib/stealth/cli.rb
CHANGED
@@ -80,7 +80,6 @@ module Stealth
|
|
80
80
|
|
81
81
|
$ > stealth console --engine=pry
|
82
82
|
EOS
|
83
|
-
method_option :environment, desc: 'Path to environment configuration (config/environment.rb)'
|
84
83
|
method_option :engine, desc: "Choose a specific console engine: (#{Stealth::Commands::Console::ENGINES.keys.join('/')})"
|
85
84
|
method_option :help, desc: 'Displays the usage method'
|
86
85
|
def console
|
@@ -114,7 +113,7 @@ module Stealth
|
|
114
113
|
EOS
|
115
114
|
define_method 'sessions:clear' do
|
116
115
|
Stealth.load_environment
|
117
|
-
$redis.flushdb if Stealth.env
|
116
|
+
$redis.flushdb if Stealth.env.development?
|
118
117
|
end
|
119
118
|
|
120
119
|
|
@@ -1,8 +1,6 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require 'thread'
|
5
|
-
|
6
4
|
module Stealth
|
7
5
|
class Configuration < Hash
|
8
6
|
|
@@ -20,7 +18,6 @@ module Stealth
|
|
20
18
|
if setter?(method)
|
21
19
|
self[key] = args.first
|
22
20
|
else
|
23
|
-
super(method, args) && return unless key?(key)
|
24
21
|
self[key]
|
25
22
|
end
|
26
23
|
end
|
@@ -13,7 +13,7 @@ module Stealth
|
|
13
13
|
define_callbacks :action, skip_after_callbacks_if_terminated: true
|
14
14
|
end
|
15
15
|
|
16
|
-
|
16
|
+
class_methods do
|
17
17
|
def _normalize_callback_options(options)
|
18
18
|
_normalize_callback_option(options, :only, :if)
|
19
19
|
_normalize_callback_option(options, :except, :unless)
|
@@ -9,18 +9,41 @@ module Stealth
|
|
9
9
|
|
10
10
|
included do
|
11
11
|
|
12
|
-
def run_catch_all(
|
12
|
+
def run_catch_all(err:)
|
13
13
|
error_level = fetch_error_level
|
14
|
-
|
14
|
+
|
15
|
+
if err.class == Stealth::Errors::UnrecognizedMessage
|
16
|
+
Stealth::Logger.l(
|
17
|
+
topic: 'catch_all',
|
18
|
+
message: "[Level #{error_level}] for user #{current_session_id} #{err.message}"
|
19
|
+
)
|
20
|
+
else
|
21
|
+
Stealth::Logger.l(
|
22
|
+
topic: 'catch_all',
|
23
|
+
message: "[Level #{error_level}] for user #{current_session_id} #{[err.class, err.message, err.backtrace.join("\n")].join("\n")}"
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Store the reason so it can be accessed by the CatchAllsController
|
28
|
+
current_message.catch_all_reason = {
|
29
|
+
err: err.class,
|
30
|
+
err_msg: err.message
|
31
|
+
}
|
32
|
+
|
33
|
+
# Don't run catch_all from the catch_all controller
|
34
|
+
if current_session.flow_string == 'catch_all'
|
35
|
+
Stealth::Logger.l(topic: 'catch_all', message: "CatchAll triggered for user #{current_session_id} from within CatchAll; ignoring.")
|
36
|
+
return false
|
37
|
+
end
|
15
38
|
|
16
39
|
if defined?(CatchAllsController) && FlowMap.flow_spec[:catch_all].present?
|
17
40
|
catch_all_state = calculate_catch_all_state(error_level)
|
18
41
|
|
19
42
|
if FlowMap.flow_spec[:catch_all].states.keys.include?(catch_all_state.to_sym)
|
20
|
-
step_to flow:
|
43
|
+
step_to flow: :catch_all, state: catch_all_state
|
21
44
|
else
|
22
45
|
# We are out of bounds, do nothing to prevent an infinite loop
|
23
|
-
Stealth::Logger.l(topic:
|
46
|
+
Stealth::Logger.l(topic: 'catch_all', message: "Stopping; we\'ve exceeded the number of defined catch_all states for user #{current_session_id}.")
|
24
47
|
return false
|
25
48
|
end
|
26
49
|
end
|
@@ -7,18 +7,24 @@ module Stealth
|
|
7
7
|
include Stealth::Controller::Callbacks
|
8
8
|
include Stealth::Controller::DynamicDelay
|
9
9
|
include Stealth::Controller::Replies
|
10
|
+
include Stealth::Controller::Messages
|
11
|
+
include Stealth::Controller::UnrecognizedMessage
|
10
12
|
include Stealth::Controller::CatchAll
|
11
13
|
include Stealth::Controller::Helpers
|
14
|
+
include Stealth::Controller::InterruptDetect
|
15
|
+
include Stealth::Controller::DevJumps
|
16
|
+
include Stealth::Controller::Nlp
|
12
17
|
|
13
|
-
attr_reader :current_message, :
|
14
|
-
:
|
15
|
-
|
18
|
+
attr_reader :current_message, :current_service, :flow_controller,
|
19
|
+
:action_name, :current_session_id
|
20
|
+
attr_accessor :nlp_result, :pos
|
16
21
|
|
17
|
-
def initialize(service_message:,
|
22
|
+
def initialize(service_message:, pos: nil)
|
18
23
|
@current_message = service_message
|
19
24
|
@current_service = service_message.service
|
20
|
-
@
|
21
|
-
@
|
25
|
+
@current_session_id = service_message.sender_id
|
26
|
+
@nlp_result = service_message.nlp_result
|
27
|
+
@pos = pos
|
22
28
|
@progressed = false
|
23
29
|
end
|
24
30
|
|
@@ -31,7 +37,7 @@ module Stealth
|
|
31
37
|
end
|
32
38
|
|
33
39
|
def progressed?
|
34
|
-
@progressed
|
40
|
+
@progressed
|
35
41
|
end
|
36
42
|
|
37
43
|
def route
|
@@ -41,104 +47,217 @@ module Stealth
|
|
41
47
|
def flow_controller
|
42
48
|
@flow_controller ||= begin
|
43
49
|
flow_controller = [current_session.flow_string.pluralize, 'controller'].join('_').classify.constantize
|
44
|
-
flow_controller.new(
|
45
|
-
service_message: @current_message,
|
46
|
-
current_flow: current_flow
|
47
|
-
)
|
50
|
+
flow_controller.new(service_message: @current_message, pos: @pos)
|
48
51
|
end
|
49
52
|
end
|
50
53
|
|
51
54
|
def current_session
|
52
|
-
@current_session ||= Stealth::Session.new(
|
55
|
+
@current_session ||= Stealth::Session.new(id: current_session_id)
|
53
56
|
end
|
54
57
|
|
55
58
|
def previous_session
|
56
|
-
@previous_session ||= Stealth::Session.new(
|
59
|
+
@previous_session ||= Stealth::Session.new(
|
60
|
+
id: current_session_id,
|
61
|
+
type: :previous
|
62
|
+
)
|
57
63
|
end
|
58
64
|
|
59
65
|
def action(action: nil)
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
message: "From #{current_session.session} to #{current_session.flow.current_state.redirects_to.session}"
|
66
|
+
begin
|
67
|
+
# Grab a mutual exclusion lock on the session
|
68
|
+
lock_session!(
|
69
|
+
session_slug: Session.slugify(
|
70
|
+
flow: current_session.flow_string,
|
71
|
+
state: current_session.state_string
|
72
|
+
)
|
68
73
|
)
|
69
|
-
step_to(session: current_session.flow.current_state.redirects_to)
|
70
|
-
return
|
71
|
-
end
|
72
74
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
Stealth::Logger.l(
|
79
|
-
|
75
|
+
@action_name = action
|
76
|
+
@action_name ||= current_session.state_string
|
77
|
+
|
78
|
+
# Check if the user needs to be redirected
|
79
|
+
if current_session.flow.current_state.redirects_to.present?
|
80
|
+
Stealth::Logger.l(
|
81
|
+
topic: "redirect",
|
82
|
+
message: "From #{current_session.session} to #{current_session.flow.current_state.redirects_to.session}"
|
83
|
+
)
|
84
|
+
step_to(session: current_session.flow.current_state.redirects_to, pos: @pos)
|
85
|
+
return
|
86
|
+
end
|
87
|
+
|
88
|
+
run_callbacks :action do
|
89
|
+
begin
|
90
|
+
flow_controller.send(@action_name)
|
91
|
+
unless flow_controller.progressed?
|
92
|
+
run_catch_all(reason: 'Did not send replies, update session, or step')
|
93
|
+
end
|
94
|
+
rescue StandardError => e
|
95
|
+
if e.class == Stealth::Errors::UnrecognizedMessage
|
96
|
+
run_unrecognized_message(err: e)
|
97
|
+
else
|
98
|
+
run_catch_all(err: e)
|
99
|
+
end
|
100
|
+
end
|
80
101
|
end
|
102
|
+
ensure
|
103
|
+
# Release mutual exclusion lock on the session
|
104
|
+
release_lock!
|
81
105
|
end
|
82
106
|
end
|
83
107
|
|
84
|
-
def step_to_in(delay, session: nil, flow: nil, state: nil)
|
85
|
-
|
108
|
+
def step_to_in(delay, session: nil, flow: nil, state: nil, slug: nil)
|
109
|
+
if interrupt_detected?
|
110
|
+
run_interrupt_action
|
111
|
+
return :interrupted
|
112
|
+
end
|
113
|
+
|
114
|
+
flow, state = get_flow_and_state(
|
115
|
+
session: session,
|
116
|
+
flow: flow,
|
117
|
+
state: state,
|
118
|
+
slug: slug
|
119
|
+
)
|
86
120
|
|
87
121
|
unless delay.is_a?(ActiveSupport::Duration)
|
88
122
|
raise ArgumentError, "Please specify your step_to_in `delay` parameter using ActiveSupport::Duration, e.g. `1.day` or `5.hours`"
|
89
123
|
end
|
90
124
|
|
91
|
-
Stealth::ScheduledReplyJob.perform_in(delay, current_service, current_session_id, flow, state)
|
125
|
+
Stealth::ScheduledReplyJob.perform_in(delay, current_service, current_session_id, flow, state, current_message.target_id)
|
92
126
|
Stealth::Logger.l(topic: "session", message: "User #{current_session_id}: scheduled session step to #{flow}->#{state} in #{delay} seconds")
|
93
127
|
end
|
94
128
|
|
95
|
-
def step_to_at(timestamp, session: nil, flow: nil, state: nil)
|
96
|
-
|
129
|
+
def step_to_at(timestamp, session: nil, flow: nil, state: nil, slug: nil)
|
130
|
+
if interrupt_detected?
|
131
|
+
run_interrupt_action
|
132
|
+
return :interrupted
|
133
|
+
end
|
134
|
+
|
135
|
+
flow, state = get_flow_and_state(
|
136
|
+
session: session,
|
137
|
+
flow: flow,
|
138
|
+
state: state,
|
139
|
+
slug: slug
|
140
|
+
)
|
97
141
|
|
98
142
|
unless timestamp.is_a?(DateTime)
|
99
143
|
raise ArgumentError, "Please specify your step_to_at `timestamp` parameter as a DateTime"
|
100
144
|
end
|
101
145
|
|
102
|
-
Stealth::ScheduledReplyJob.perform_at(timestamp, current_service, current_session_id, flow, state)
|
146
|
+
Stealth::ScheduledReplyJob.perform_at(timestamp, current_service, current_session_id, flow, state, current_message.target_id)
|
103
147
|
Stealth::Logger.l(topic: "session", message: "User #{current_session_id}: scheduled session step to #{flow}->#{state} at #{timestamp.iso8601}")
|
104
148
|
end
|
105
149
|
|
106
|
-
def step_to(session: nil, flow: nil, state: nil)
|
107
|
-
|
108
|
-
|
150
|
+
def step_to(session: nil, flow: nil, state: nil, slug: nil, pos: nil)
|
151
|
+
if interrupt_detected?
|
152
|
+
run_interrupt_action
|
153
|
+
return :interrupted
|
154
|
+
end
|
155
|
+
|
156
|
+
flow, state = get_flow_and_state(
|
157
|
+
session: session,
|
158
|
+
flow: flow,
|
159
|
+
state: state,
|
160
|
+
slug: slug
|
161
|
+
)
|
162
|
+
|
163
|
+
step(flow: flow, state: state, pos: pos)
|
109
164
|
end
|
110
165
|
|
111
|
-
def update_session_to(session: nil, flow: nil, state: nil)
|
112
|
-
|
166
|
+
def update_session_to(session: nil, flow: nil, state: nil, slug: nil)
|
167
|
+
if interrupt_detected?
|
168
|
+
run_interrupt_action
|
169
|
+
return :interrupted
|
170
|
+
end
|
171
|
+
|
172
|
+
flow, state = get_flow_and_state(
|
173
|
+
session: session,
|
174
|
+
flow: flow,
|
175
|
+
state: state,
|
176
|
+
slug: slug
|
177
|
+
)
|
178
|
+
|
113
179
|
update_session(flow: flow, state: state)
|
114
180
|
end
|
115
181
|
|
182
|
+
def set_back_to(session: nil, flow: nil, state: nil, slug: nil)
|
183
|
+
if interrupt_detected?
|
184
|
+
run_interrupt_action
|
185
|
+
return :interrupted
|
186
|
+
end
|
187
|
+
|
188
|
+
flow, state = get_flow_and_state(
|
189
|
+
session: session,
|
190
|
+
flow: flow,
|
191
|
+
state: state,
|
192
|
+
slug: slug
|
193
|
+
)
|
194
|
+
|
195
|
+
store_back_to_session(flow: flow, state: state)
|
196
|
+
end
|
197
|
+
|
198
|
+
def step_back
|
199
|
+
back_to_session = Stealth::Session.new(
|
200
|
+
id: current_session_id,
|
201
|
+
type: :back_to
|
202
|
+
)
|
203
|
+
|
204
|
+
if back_to_session.blank?
|
205
|
+
raise(
|
206
|
+
Stealth::Errors::InvalidStateTransition,
|
207
|
+
'back_to_session not found; make sure set_back_to was called first'
|
208
|
+
)
|
209
|
+
end
|
210
|
+
|
211
|
+
step_to(session: back_to_session)
|
212
|
+
end
|
213
|
+
|
214
|
+
def do_nothing
|
215
|
+
@progressed = :do_nothing
|
216
|
+
end
|
217
|
+
|
116
218
|
private
|
117
219
|
|
118
220
|
def update_session(flow:, state:)
|
119
|
-
@current_session = Stealth::Session.new(user_id: current_session_id)
|
120
221
|
@progressed = :updated_session
|
121
|
-
@current_session.
|
222
|
+
@current_session = Session.new(id: current_session_id)
|
223
|
+
|
224
|
+
unless current_session.flow_string == flow.to_s && current_session.state_string == state.to_s
|
225
|
+
@current_session.set_session(new_flow: flow, new_state: state)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def store_back_to_session(flow:, state:)
|
230
|
+
back_to_session = Session.new(
|
231
|
+
id: current_session_id,
|
232
|
+
type: :back_to
|
233
|
+
)
|
234
|
+
back_to_session.set_session(new_flow: flow, new_state: state)
|
122
235
|
end
|
123
236
|
|
124
|
-
def step(flow:, state:)
|
237
|
+
def step(flow:, state:, pos: nil)
|
125
238
|
update_session(flow: flow, state: state)
|
126
239
|
@progressed = :stepped
|
127
240
|
@flow_controller = nil
|
128
241
|
@current_flow = current_session.flow
|
242
|
+
@pos = pos
|
129
243
|
|
130
|
-
action(action: state)
|
244
|
+
flow_controller.action(action: state)
|
131
245
|
end
|
132
246
|
|
133
|
-
def get_flow_and_state(session: nil, flow: nil, state: nil)
|
134
|
-
if session.nil? && flow.nil? && state.nil?
|
135
|
-
raise(ArgumentError, "A session, flow, or
|
247
|
+
def get_flow_and_state(session: nil, flow: nil, state: nil, slug: nil)
|
248
|
+
if session.nil? && flow.nil? && state.nil? && slug.nil?
|
249
|
+
raise(ArgumentError, "A session, flow, state, or slug must be specified")
|
136
250
|
end
|
137
251
|
|
138
252
|
if session.present?
|
139
253
|
return session.flow_string, session.state_string
|
140
254
|
end
|
141
255
|
|
256
|
+
if slug.present?
|
257
|
+
flow_state = Session.flow_and_state_from_session_slug(slug: slug)
|
258
|
+
return flow_state[:flow], flow_state[:state]
|
259
|
+
end
|
260
|
+
|
142
261
|
if flow.present?
|
143
262
|
if state.blank?
|
144
263
|
state = FlowMap.flow_spec[flow.to_sym].states.keys.first.to_s
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Stealth
|
5
|
+
class Controller
|
6
|
+
module DevJumps
|
7
|
+
|
8
|
+
DEV_JUMP_REGEX = /\A\/(.*)\/(.*)\z|\A\/\/(.*)\z|\A\/(.*)\z/
|
9
|
+
|
10
|
+
extend ActiveSupport::Concern
|
11
|
+
|
12
|
+
included do
|
13
|
+
private
|
14
|
+
|
15
|
+
def dev_jump_detected?
|
16
|
+
if Stealth.env.development?
|
17
|
+
if current_message.message&.match(DEV_JUMP_REGEX)
|
18
|
+
handle_dev_jump
|
19
|
+
return true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
false
|
24
|
+
end
|
25
|
+
|
26
|
+
def handle_dev_jump
|
27
|
+
_, flow, state = current_message.message.split('/')
|
28
|
+
flow = nil if flow.blank?
|
29
|
+
|
30
|
+
Stealth::Logger.l(
|
31
|
+
topic: 'dev_jump',
|
32
|
+
message: "Dev Jump detected: Flow: #{flow.inspect} State: #{state.inspect}"
|
33
|
+
)
|
34
|
+
|
35
|
+
step_to flow: flow, state: state
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -12,17 +12,15 @@ module Stealth
|
|
12
12
|
LONG_DELAY = 7.0
|
13
13
|
|
14
14
|
included do
|
15
|
-
def dynamic_delay(
|
16
|
-
|
17
|
-
calculate_delay(previous_reply: {})
|
18
|
-
else
|
19
|
-
calculate_delay(previous_reply: service_replies[position - 1])
|
20
|
-
end
|
15
|
+
def dynamic_delay(previous_reply:)
|
16
|
+
calculate_delay(previous_reply: previous_reply)
|
21
17
|
end
|
22
18
|
|
23
19
|
private
|
24
20
|
|
25
21
|
def calculate_delay(previous_reply:)
|
22
|
+
return SHORT_DELAY if previous_reply.blank?
|
23
|
+
|
26
24
|
case previous_reply['reply_type']
|
27
25
|
when 'text'
|
28
26
|
calculate_delay_from_text(previous_reply['text'])
|