adhearsion 2.6.4 → 3.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +6 -9
- data/CHANGELOG.md +22 -7
- data/Gemfile +2 -0
- data/README.markdown +4 -5
- data/Rakefile +1 -2
- data/adhearsion.gemspec +19 -8
- data/features/cli_create.feature +19 -3
- data/features/step_definitions/cli_steps.rb +0 -11
- data/features/support/env.rb +3 -4
- data/lib/adhearsion.rb +48 -27
- data/lib/adhearsion/call.rb +34 -50
- data/lib/adhearsion/call_controller.rb +6 -12
- data/lib/adhearsion/call_controller/dial.rb +15 -53
- data/lib/adhearsion/call_controller/input.rb +39 -162
- data/lib/adhearsion/call_controller/input/ask_grammar_builder.rb +44 -0
- data/lib/adhearsion/call_controller/input/menu_builder.rb +136 -0
- data/lib/adhearsion/call_controller/input/prompt_builder.rb +78 -0
- data/lib/adhearsion/call_controller/input/result.rb +46 -0
- data/lib/adhearsion/call_controller/output.rb +48 -67
- data/lib/adhearsion/call_controller/output/abstract_player.rb +3 -3
- data/lib/adhearsion/call_controller/output/async_player.rb +3 -3
- data/lib/adhearsion/call_controller/output/player.rb +1 -1
- data/lib/adhearsion/call_controller/record.rb +23 -8
- data/lib/adhearsion/calls.rb +1 -1
- data/lib/adhearsion/cli_commands/ahn_command.rb +2 -65
- data/lib/adhearsion/cli_commands/thor_errors.rb +0 -6
- data/lib/adhearsion/configuration.rb +91 -39
- data/lib/adhearsion/core_ext/blather/stanza.rb +41 -0
- data/lib/adhearsion/core_ext/blather/stanza/presence.rb +13 -0
- data/lib/adhearsion/error.rb +5 -0
- data/lib/adhearsion/event.rb +21 -0
- data/lib/adhearsion/event/active_speaker.rb +11 -0
- data/lib/adhearsion/event/answered.rb +11 -0
- data/lib/adhearsion/event/asterisk.rb +10 -0
- data/lib/adhearsion/event/asterisk/ami.rb +34 -0
- data/lib/adhearsion/event/complete.rb +75 -0
- data/lib/adhearsion/event/dtmf.rb +11 -0
- data/lib/adhearsion/event/end.rb +22 -0
- data/lib/adhearsion/event/input_timers_started.rb +9 -0
- data/lib/adhearsion/event/joined.rb +17 -0
- data/lib/adhearsion/event/offer.rb +14 -0
- data/lib/adhearsion/event/ringing.rb +11 -0
- data/lib/adhearsion/event/started_speaking.rb +13 -0
- data/lib/adhearsion/event/stopped_speaking.rb +13 -0
- data/lib/adhearsion/event/unjoined.rb +17 -0
- data/lib/adhearsion/events.rb +47 -66
- data/lib/adhearsion/foundation.rb +0 -1
- data/lib/adhearsion/foundation/object.rb +0 -5
- data/lib/adhearsion/generators/app/app_generator.rb +4 -1
- data/lib/adhearsion/generators/app/templates/Gemfile.erb +2 -10
- data/lib/adhearsion/generators/app/templates/adhearsion.erb +9 -9
- data/lib/adhearsion/generators/app/templates/config.ru +7 -0
- data/lib/adhearsion/generators/app/templates/en.yml +4 -0
- data/lib/adhearsion/generators/app/templates/events.erb +2 -2
- data/lib/adhearsion/generators/app/templates/hello_world.wav +0 -0
- data/lib/adhearsion/generators/app/templates/simon_game.rb +2 -1
- data/lib/adhearsion/generators/app/templates/simon_game_spec.rb +2 -2
- data/lib/adhearsion/has_headers.rb +34 -0
- data/lib/adhearsion/http_server.rb +37 -0
- data/lib/adhearsion/initializer.rb +19 -153
- data/lib/adhearsion/logging.rb +6 -25
- data/lib/adhearsion/outbound_call.rb +5 -5
- data/lib/adhearsion/plugin.rb +1 -0
- data/lib/adhearsion/protocol_error.rb +26 -0
- data/lib/adhearsion/rayo.rb +30 -0
- data/lib/adhearsion/rayo/client.rb +62 -0
- data/lib/adhearsion/rayo/client/component_registry.rb +33 -0
- data/lib/adhearsion/rayo/command.rb +21 -0
- data/lib/adhearsion/rayo/command/accept.rb +16 -0
- data/lib/adhearsion/rayo/command/answer.rb +16 -0
- data/lib/adhearsion/rayo/command/dial.rb +57 -0
- data/lib/adhearsion/rayo/command/hangup.rb +16 -0
- data/lib/adhearsion/rayo/command/join.rb +43 -0
- data/lib/adhearsion/rayo/command/mute.rb +13 -0
- data/lib/adhearsion/rayo/command/redirect.rb +23 -0
- data/lib/adhearsion/rayo/command/reject.rb +40 -0
- data/lib/adhearsion/rayo/command/unjoin.rb +24 -0
- data/lib/adhearsion/rayo/command/unmute.rb +13 -0
- data/lib/adhearsion/rayo/command_node.rb +47 -0
- data/lib/adhearsion/rayo/component.rb +21 -0
- data/lib/adhearsion/rayo/component/asterisk.rb +13 -0
- data/lib/adhearsion/rayo/component/asterisk/agi.rb +14 -0
- data/lib/adhearsion/rayo/component/asterisk/agi/command.rb +46 -0
- data/lib/adhearsion/rayo/component/asterisk/ami.rb +14 -0
- data/lib/adhearsion/rayo/component/asterisk/ami/action.rb +61 -0
- data/lib/adhearsion/rayo/component/component_node.rb +90 -0
- data/lib/adhearsion/rayo/component/input.rb +186 -0
- data/lib/adhearsion/rayo/component/output.rb +471 -0
- data/lib/adhearsion/rayo/component/prompt.rb +53 -0
- data/lib/adhearsion/rayo/component/receive_fax.rb +26 -0
- data/lib/adhearsion/rayo/component/record.rb +165 -0
- data/lib/adhearsion/rayo/component/send_fax.rb +64 -0
- data/lib/adhearsion/rayo/component/stop.rb +11 -0
- data/lib/adhearsion/rayo/connection.rb +12 -0
- data/lib/adhearsion/rayo/connection/asterisk.rb +74 -0
- data/lib/adhearsion/rayo/connection/connected.rb +22 -0
- data/lib/adhearsion/rayo/connection/generic_connection.rb +22 -0
- data/lib/adhearsion/rayo/connection/xmpp.rb +198 -0
- data/lib/adhearsion/rayo/disconnected_error.rb +22 -0
- data/lib/adhearsion/{punchblock_plugin → rayo}/initializer.rb +19 -19
- data/lib/adhearsion/rayo/rayo_node.rb +127 -0
- data/lib/adhearsion/rayo/ref.rb +57 -0
- data/lib/adhearsion/statistics.rb +1 -1
- data/lib/adhearsion/tasks.rb +1 -2
- data/lib/adhearsion/tasks/configuration.rb +1 -1
- data/lib/adhearsion/tasks/environment.rb +0 -2
- data/lib/adhearsion/tasks/i18n.rb +49 -0
- data/lib/adhearsion/translator.rb +11 -0
- data/lib/adhearsion/translator/asterisk.rb +234 -0
- data/lib/adhearsion/translator/asterisk/agi_app.rb +17 -0
- data/lib/adhearsion/translator/asterisk/agi_command.rb +45 -0
- data/lib/adhearsion/translator/asterisk/ami_error_converter.rb +20 -0
- data/lib/adhearsion/translator/asterisk/call.rb +416 -0
- data/lib/adhearsion/translator/asterisk/channel.rb +43 -0
- data/lib/adhearsion/translator/asterisk/component.rb +88 -0
- data/lib/adhearsion/translator/asterisk/component/asterisk.rb +15 -0
- data/lib/adhearsion/translator/asterisk/component/asterisk/agi_command.rb +42 -0
- data/lib/adhearsion/translator/asterisk/component/asterisk/ami_action.rb +68 -0
- data/lib/adhearsion/translator/asterisk/component/composed_prompt.rb +76 -0
- data/lib/adhearsion/translator/asterisk/component/dtmf_recognizer.rb +137 -0
- data/lib/adhearsion/translator/asterisk/component/input.rb +34 -0
- data/lib/adhearsion/translator/asterisk/component/input_component.rb +90 -0
- data/lib/adhearsion/translator/asterisk/component/mrcp_native_prompt.rb +71 -0
- data/lib/adhearsion/translator/asterisk/component/mrcp_prompt.rb +55 -0
- data/lib/adhearsion/translator/asterisk/component/mrcp_recog_prompt.rb +165 -0
- data/lib/adhearsion/translator/asterisk/component/output.rb +233 -0
- data/lib/adhearsion/translator/asterisk/component/record.rb +101 -0
- data/lib/adhearsion/translator/asterisk/component/stop_by_redirect.rb +30 -0
- data/lib/adhearsion/translator/asterisk/unimrcp_app.rb +28 -0
- data/lib/adhearsion/uri_list.rb +21 -0
- data/lib/adhearsion/version.rb +1 -1
- data/spec/adhearsion/call_controller/dial_spec.rb +79 -1420
- data/spec/adhearsion/call_controller/input_spec.rb +1141 -237
- data/spec/adhearsion/call_controller/output/async_player_spec.rb +10 -10
- data/spec/adhearsion/call_controller/output/player_spec.rb +8 -8
- data/spec/adhearsion/call_controller/output_spec.rb +162 -215
- data/spec/adhearsion/call_controller/record_spec.rb +15 -16
- data/spec/adhearsion/call_controller_spec.rb +23 -40
- data/spec/adhearsion/call_spec.rb +123 -129
- data/spec/adhearsion/calls_spec.rb +3 -3
- data/spec/adhearsion/configuration_spec.rb +94 -108
- data/spec/adhearsion/event/answered_spec.rb +50 -0
- data/spec/adhearsion/event/asterisk/Find Results +402 -0
- data/spec/adhearsion/event/asterisk/ami_spec.rb +81 -0
- data/spec/adhearsion/event/complete_spec.rb +176 -0
- data/spec/adhearsion/event/dtmf_spec.rb +35 -0
- data/spec/adhearsion/event/end_spec.rb +85 -0
- data/spec/adhearsion/event/input_timers_started_spec.rb +19 -0
- data/spec/adhearsion/event/joined_spec.rb +53 -0
- data/spec/adhearsion/event/offer_spec.rb +106 -0
- data/spec/adhearsion/event/ringing_spec.rb +50 -0
- data/spec/adhearsion/event/started_speaking_spec.rb +37 -0
- data/spec/adhearsion/event/stopped_speaking_spec.rb +37 -0
- data/spec/adhearsion/event/unjoined_spec.rb +48 -0
- data/spec/adhearsion/event/untitled +0 -0
- data/spec/adhearsion/events_spec.rb +19 -45
- data/spec/adhearsion/initializer_spec.rb +12 -184
- data/spec/adhearsion/logging_spec.rb +5 -20
- data/spec/adhearsion/outbound_call_spec.rb +13 -13
- data/spec/adhearsion/plugin_spec.rb +3 -4
- data/spec/adhearsion/protocol_error_spec.rb +91 -0
- data/spec/adhearsion/rayo/client/component_registry_spec.rb +26 -0
- data/spec/adhearsion/rayo/client_spec.rb +134 -0
- data/spec/adhearsion/rayo/command/accept_spec.rb +63 -0
- data/spec/adhearsion/rayo/command/answer_spec.rb +73 -0
- data/spec/adhearsion/rayo/command/dial_spec.rb +156 -0
- data/spec/adhearsion/rayo/command/hangup_spec.rb +63 -0
- data/spec/adhearsion/rayo/command/join_spec.rb +158 -0
- data/spec/adhearsion/rayo/command/mute_spec.rb +32 -0
- data/spec/adhearsion/rayo/command/redirect_spec.rb +89 -0
- data/spec/adhearsion/rayo/command/reject_spec.rb +117 -0
- data/spec/adhearsion/rayo/command/unjoin_spec.rb +82 -0
- data/spec/adhearsion/rayo/command/unmute_spec.rb +32 -0
- data/spec/adhearsion/rayo/command_node_spec.rb +101 -0
- data/spec/adhearsion/rayo/component/asterisk/agi/command_spec.rb +111 -0
- data/spec/adhearsion/rayo/component/asterisk/ami/action_spec.rb +173 -0
- data/spec/adhearsion/rayo/component/component_node_spec.rb +110 -0
- data/spec/adhearsion/rayo/component/input_spec.rb +715 -0
- data/spec/adhearsion/rayo/component/output_spec.rb +1030 -0
- data/spec/adhearsion/rayo/component/prompt_spec.rb +171 -0
- data/spec/adhearsion/rayo/component/receive_fax_spec.rb +136 -0
- data/spec/adhearsion/rayo/component/record_spec.rb +497 -0
- data/spec/adhearsion/rayo/component/send_fax_spec.rb +144 -0
- data/spec/adhearsion/rayo/connection/asterisk_spec.rb +118 -0
- data/spec/adhearsion/rayo/connection/xmpp_spec.rb +449 -0
- data/spec/adhearsion/rayo/initializer_spec.rb +353 -0
- data/spec/adhearsion/rayo/ref_spec.rb +168 -0
- data/spec/adhearsion/rayo_spec.rb +7 -0
- data/spec/adhearsion/router/route_spec.rb +1 -1
- data/spec/adhearsion/statistics_spec.rb +2 -5
- data/spec/adhearsion/translator/asterisk/call_spec.rb +2047 -0
- data/spec/adhearsion/translator/asterisk/component/asterisk/agi_command_spec.rb +256 -0
- data/spec/adhearsion/translator/asterisk/component/asterisk/ami_action_spec.rb +151 -0
- data/spec/adhearsion/translator/asterisk/component/composed_prompt_spec.rb +257 -0
- data/spec/adhearsion/translator/asterisk/component/input_spec.rb +571 -0
- data/spec/adhearsion/translator/asterisk/component/mrcp_native_prompt_spec.rb +774 -0
- data/spec/adhearsion/translator/asterisk/component/mrcp_prompt_spec.rb +1244 -0
- data/spec/adhearsion/translator/asterisk/component/output_spec.rb +1850 -0
- data/spec/adhearsion/translator/asterisk/component/record_spec.rb +426 -0
- data/spec/adhearsion/translator/asterisk/component/stop_by_redirect_spec.rb +62 -0
- data/spec/adhearsion/translator/asterisk/component_spec.rb +83 -0
- data/spec/adhearsion/translator/asterisk_spec.rb +685 -0
- data/spec/adhearsion/uri_list_spec.rb +88 -0
- data/spec/adhearsion_spec.rb +89 -14
- data/spec/fixtures/locale/en.yml +13 -0
- data/spec/fixtures/locale/it.yml +13 -0
- data/spec/spec_helper.rb +18 -5
- data/spec/support/call_controller_test_helpers.rb +3 -2
- data/spec/support/initializer_stubs.rb +3 -1
- data/spec/support/punchblock_examples.rb +65 -0
- data/spec/support/punchblock_mocks.rb +12 -0
- metadata +412 -70
- data/features/cli_daemon.feature +0 -20
- data/features/cli_restart.feature +0 -52
- data/features/cli_stop.feature +0 -50
- data/lib/adhearsion/call_controller/menu_dsl.rb +0 -21
- data/lib/adhearsion/call_controller/menu_dsl/array_match_calculator.rb +0 -26
- data/lib/adhearsion/call_controller/menu_dsl/calculated_match.rb +0 -43
- data/lib/adhearsion/call_controller/menu_dsl/calculated_match_collection.rb +0 -45
- data/lib/adhearsion/call_controller/menu_dsl/fixnum_match_calculator.rb +0 -11
- data/lib/adhearsion/call_controller/menu_dsl/match_calculator.rb +0 -40
- data/lib/adhearsion/call_controller/menu_dsl/menu.rb +0 -207
- data/lib/adhearsion/call_controller/menu_dsl/menu_builder.rb +0 -92
- data/lib/adhearsion/call_controller/menu_dsl/range_match_calculator.rb +0 -60
- data/lib/adhearsion/call_controller/menu_dsl/string_match_calculator.rb +0 -25
- data/lib/adhearsion/call_controller/utility.rb +0 -77
- data/lib/adhearsion/foundation/custom_daemonizer.rb +0 -52
- data/lib/adhearsion/punchblock_plugin.rb +0 -63
- data/scripts/cloc-1.64.pl +0 -10483
- data/spec/adhearsion/call_controller/menu_dsl/array_match_calculator_spec.rb +0 -76
- data/spec/adhearsion/call_controller/menu_dsl/calculated_match_collection_spec.rb +0 -60
- data/spec/adhearsion/call_controller/menu_dsl/calculated_match_spec.rb +0 -61
- data/spec/adhearsion/call_controller/menu_dsl/fixnum_match_calculator_spec.rb +0 -39
- data/spec/adhearsion/call_controller/menu_dsl/match_calculator_spec.rb +0 -17
- data/spec/adhearsion/call_controller/menu_dsl/menu_builder_spec.rb +0 -165
- data/spec/adhearsion/call_controller/menu_dsl/menu_spec.rb +0 -420
- data/spec/adhearsion/call_controller/menu_dsl/range_match_calculator_spec.rb +0 -32
- data/spec/adhearsion/call_controller/menu_dsl/string_match_calculator_spec.rb +0 -40
- data/spec/adhearsion/call_controller/utility_spec.rb +0 -90
- data/spec/adhearsion/punchblock_plugin/initializer_spec.rb +0 -356
- data/spec/adhearsion/punchblock_plugin_spec.rb +0 -59
data/lib/adhearsion/call.rb
CHANGED
@@ -17,7 +17,7 @@ module Adhearsion
|
|
17
17
|
ExpiredError = Class.new Celluloid::DeadActorError
|
18
18
|
|
19
19
|
# @private
|
20
|
-
class ActorProxy < Celluloid::
|
20
|
+
class ActorProxy < Celluloid::CellProxy
|
21
21
|
def method_missing(meth, *args, &block)
|
22
22
|
super(meth, *args, &block)
|
23
23
|
rescue ::Celluloid::DeadActorError
|
@@ -89,7 +89,6 @@ module Adhearsion
|
|
89
89
|
@duration = nil
|
90
90
|
@auto_hangup = true
|
91
91
|
@after_hangup_lifetime = nil
|
92
|
-
@call_terminating = false
|
93
92
|
|
94
93
|
self << offer if offer
|
95
94
|
end
|
@@ -161,14 +160,18 @@ module Adhearsion
|
|
161
160
|
|
162
161
|
#
|
163
162
|
# Wait for the call to end. Returns immediately if the call has already ended, else blocks until it does so.
|
163
|
+
# @param [Integer, nil] timeout a timeout after which to unblock, returning `:timeout`
|
164
164
|
# @return [Symbol] the reason for the call ending
|
165
|
+
# @raises [Celluloid::ConditionError] in case of a specified timeout expiring
|
165
166
|
#
|
166
|
-
def wait_for_end
|
167
|
+
def wait_for_end(timeout = nil)
|
167
168
|
if end_reason
|
168
169
|
end_reason
|
169
170
|
else
|
170
|
-
@end_blocker.wait
|
171
|
+
@end_blocker.wait(timeout)
|
171
172
|
end
|
173
|
+
rescue Celluloid::ConditionError => e
|
174
|
+
abort e
|
172
175
|
end
|
173
176
|
|
174
177
|
#
|
@@ -200,22 +203,16 @@ module Adhearsion
|
|
200
203
|
|
201
204
|
# @private
|
202
205
|
def register_initial_handlers
|
203
|
-
register_event_handler
|
206
|
+
register_event_handler Adhearsion::Event::Offer do |offer|
|
204
207
|
@offer = offer
|
205
208
|
@client = offer.client
|
206
209
|
@start_time = offer.timestamp.to_time
|
207
210
|
end
|
208
211
|
|
209
|
-
register_event_handler
|
212
|
+
register_event_handler Adhearsion::HasHeaders do |event|
|
210
213
|
merge_headers event.headers
|
211
214
|
end
|
212
215
|
|
213
|
-
register_event_handler Punchblock::Event::Complete do |event|
|
214
|
-
if event.reason.is_a? Punchblock::Event::Complete::Hangup
|
215
|
-
terminating! unless terminating?
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
216
|
on_joined do |event|
|
220
217
|
if event.call_uri
|
221
218
|
target = event.call_uri
|
@@ -245,7 +242,6 @@ module Adhearsion
|
|
245
242
|
|
246
243
|
on_end do |event|
|
247
244
|
logger.info "Call #{from} -> #{to} ended due to #{event.reason}#{" (code #{event.platform_code})" if event.platform_code}"
|
248
|
-
terminating! unless terminating?
|
249
245
|
@end_time = event.timestamp.to_time
|
250
246
|
@duration = @end_time - @start_time if @start_time
|
251
247
|
clear_from_active_calls
|
@@ -253,7 +249,7 @@ module Adhearsion
|
|
253
249
|
@end_code = event.platform_code
|
254
250
|
@end_blocker.broadcast event.reason
|
255
251
|
@commands.terminate
|
256
|
-
after(@after_hangup_lifetime || Adhearsion.config.
|
252
|
+
after(@after_hangup_lifetime || Adhearsion.config.core.after_hangup_lifetime) { terminate }
|
257
253
|
end
|
258
254
|
end
|
259
255
|
|
@@ -276,7 +272,7 @@ module Adhearsion
|
|
276
272
|
# @option target [String] mixer_name The mixer name to guard on
|
277
273
|
#
|
278
274
|
def on_joined(target = nil, &block)
|
279
|
-
register_event_handler
|
275
|
+
register_event_handler Adhearsion::Event::Joined, *guards_for_target(target) do |event|
|
280
276
|
block.call event
|
281
277
|
end
|
282
278
|
end
|
@@ -289,7 +285,7 @@ module Adhearsion
|
|
289
285
|
# @option target [String] mixer_name The mixer name to guard on
|
290
286
|
#
|
291
287
|
def on_unjoined(target = nil, &block)
|
292
|
-
register_event_handler
|
288
|
+
register_event_handler Adhearsion::Event::Unjoined, *guards_for_target(target), &block
|
293
289
|
end
|
294
290
|
|
295
291
|
# @private
|
@@ -298,19 +294,7 @@ module Adhearsion
|
|
298
294
|
end
|
299
295
|
|
300
296
|
def on_end(&block)
|
301
|
-
register_event_handler
|
302
|
-
end
|
303
|
-
|
304
|
-
def terminating!
|
305
|
-
logger.debug "Call is terminating"
|
306
|
-
@call_terminating = true
|
307
|
-
end
|
308
|
-
|
309
|
-
#
|
310
|
-
# @return [Boolean] if the call is currently terminating/terminated
|
311
|
-
#
|
312
|
-
def terminating?
|
313
|
-
!active? || @call_terminating
|
297
|
+
register_event_handler Adhearsion::Event::End, &block
|
314
298
|
end
|
315
299
|
|
316
300
|
#
|
@@ -321,21 +305,21 @@ module Adhearsion
|
|
321
305
|
end
|
322
306
|
|
323
307
|
def accept(headers = nil)
|
324
|
-
@accept_command ||= write_and_await_response
|
325
|
-
rescue
|
308
|
+
@accept_command ||= write_and_await_response Adhearsion::Rayo::Command::Accept.new(:headers => headers)
|
309
|
+
rescue Adhearsion::ProtocolError => e
|
326
310
|
abort e
|
327
311
|
end
|
328
312
|
|
329
313
|
def answer(headers = nil)
|
330
|
-
write_and_await_response
|
331
|
-
rescue
|
314
|
+
write_and_await_response Adhearsion::Rayo::Command::Answer.new(:headers => headers)
|
315
|
+
rescue Adhearsion::ProtocolError => e
|
332
316
|
abort e
|
333
317
|
end
|
334
318
|
|
335
319
|
def reject(reason = :busy, headers = nil)
|
336
|
-
write_and_await_response
|
320
|
+
write_and_await_response Adhearsion::Rayo::Command::Reject.new(:reason => reason, :headers => headers)
|
337
321
|
Adhearsion::Events.trigger_immediately :call_rejected, call: current_actor, reason: reason
|
338
|
-
rescue
|
322
|
+
rescue Adhearsion::ProtocolError => e
|
339
323
|
abort e
|
340
324
|
end
|
341
325
|
|
@@ -354,8 +338,8 @@ module Adhearsion
|
|
354
338
|
# @param [String] to the target to redirect to, eg a SIP URI
|
355
339
|
# @param [Hash, optional] headers a set of headers to send along with the redirect instruction
|
356
340
|
def redirect(to, headers = nil)
|
357
|
-
write_and_await_response
|
358
|
-
rescue
|
341
|
+
write_and_await_response Adhearsion::Rayo::Command::Redirect.new(to: to, headers: headers)
|
342
|
+
rescue Adhearsion::ProtocolError => e
|
359
343
|
abort e
|
360
344
|
end
|
361
345
|
|
@@ -363,8 +347,8 @@ module Adhearsion
|
|
363
347
|
return false unless active?
|
364
348
|
logger.info "Hanging up"
|
365
349
|
@end_reason = true
|
366
|
-
write_and_await_response
|
367
|
-
rescue
|
350
|
+
write_and_await_response Adhearsion::Rayo::Command::Hangup.new(:headers => headers)
|
351
|
+
rescue Adhearsion::ProtocolError => e
|
368
352
|
abort e
|
369
353
|
end
|
370
354
|
|
@@ -401,10 +385,10 @@ module Adhearsion
|
|
401
385
|
unjoined_condition.countdown!
|
402
386
|
end
|
403
387
|
|
404
|
-
command =
|
388
|
+
command = Adhearsion::Rayo::Command::Join.new options.merge(join_options_with_target(target))
|
405
389
|
write_and_await_response command
|
406
390
|
{command: command, joined_condition: joined_condition, unjoined_condition: unjoined_condition}
|
407
|
-
rescue
|
391
|
+
rescue Adhearsion::ProtocolError => e
|
408
392
|
abort e
|
409
393
|
end
|
410
394
|
|
@@ -417,9 +401,9 @@ module Adhearsion
|
|
417
401
|
#
|
418
402
|
def unjoin(target = nil)
|
419
403
|
logger.info "Unjoining from #{target}"
|
420
|
-
command =
|
404
|
+
command = Adhearsion::Rayo::Command::Unjoin.new join_options_with_target(target)
|
421
405
|
write_and_await_response command
|
422
|
-
rescue
|
406
|
+
rescue Adhearsion::ProtocolError => e
|
423
407
|
abort e
|
424
408
|
end
|
425
409
|
|
@@ -462,14 +446,14 @@ module Adhearsion
|
|
462
446
|
end
|
463
447
|
|
464
448
|
def mute
|
465
|
-
write_and_await_response
|
466
|
-
rescue
|
449
|
+
write_and_await_response Adhearsion::Rayo::Command::Mute.new
|
450
|
+
rescue Adhearsion::ProtocolError => e
|
467
451
|
abort e
|
468
452
|
end
|
469
453
|
|
470
454
|
def unmute
|
471
|
-
write_and_await_response
|
472
|
-
rescue
|
455
|
+
write_and_await_response Adhearsion::Rayo::Command::Unmute.new
|
456
|
+
rescue Adhearsion::ProtocolError => e
|
473
457
|
abort e
|
474
458
|
end
|
475
459
|
|
@@ -482,7 +466,7 @@ module Adhearsion
|
|
482
466
|
|
483
467
|
response = defer { command.response timeout }
|
484
468
|
case response
|
485
|
-
when
|
469
|
+
when Adhearsion::ProtocolError
|
486
470
|
if response.name == :item_not_found
|
487
471
|
error_handler[Hangup.new(@end_reason)]
|
488
472
|
else
|
@@ -501,10 +485,10 @@ module Adhearsion
|
|
501
485
|
|
502
486
|
# @private
|
503
487
|
def write_command(command)
|
504
|
-
abort Hangup.new(@end_reason) unless active? || command.is_a?(
|
488
|
+
abort Hangup.new(@end_reason) unless active? || command.is_a?(Adhearsion::Rayo::Command::Hangup)
|
505
489
|
merge_headers command.headers if command.respond_to? :headers
|
506
490
|
logger.debug "Executing command #{command.inspect}"
|
507
|
-
unless command.is_a?(
|
491
|
+
unless command.is_a?(Adhearsion::Rayo::Command::Dial)
|
508
492
|
command.target_call_id = id
|
509
493
|
command.domain = domain
|
510
494
|
end
|
@@ -1,13 +1,12 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require 'countdownlatch'
|
4
|
+
|
4
5
|
%w(
|
5
6
|
dial
|
6
7
|
input
|
7
|
-
menu_dsl
|
8
8
|
output
|
9
9
|
record
|
10
|
-
utility
|
11
10
|
).each { |r| require "adhearsion/call_controller/#{r}" }
|
12
11
|
|
13
12
|
module Adhearsion
|
@@ -16,7 +15,6 @@ module Adhearsion
|
|
16
15
|
include Input
|
17
16
|
include Output
|
18
17
|
include Record
|
19
|
-
include Utility
|
20
18
|
|
21
19
|
class_attribute :callbacks
|
22
20
|
|
@@ -99,7 +97,7 @@ module Adhearsion
|
|
99
97
|
end
|
100
98
|
|
101
99
|
def bg_exec(completion_callback = nil)
|
102
|
-
Celluloid::ThreadHandle.new do
|
100
|
+
Celluloid::ThreadHandle.new(Celluloid.actor_system) do
|
103
101
|
catching_standard_errors do
|
104
102
|
exec_with_callback completion_callback
|
105
103
|
end
|
@@ -164,7 +162,7 @@ module Adhearsion
|
|
164
162
|
@active_components.each do |component|
|
165
163
|
begin
|
166
164
|
component.stop!
|
167
|
-
rescue
|
165
|
+
rescue Adhearsion::Rayo::Component::InvalidActionError
|
168
166
|
end
|
169
167
|
end
|
170
168
|
end
|
@@ -205,8 +203,8 @@ module Adhearsion
|
|
205
203
|
def write_and_await_response(command)
|
206
204
|
block_until_resumed
|
207
205
|
call.write_and_await_response command
|
208
|
-
if command.is_a?(
|
209
|
-
command.register_event_handler
|
206
|
+
if command.is_a?(Adhearsion::Rayo::Component::ComponentNode)
|
207
|
+
command.register_event_handler Adhearsion::Event::Complete do |event|
|
210
208
|
@active_components.delete command
|
211
209
|
throw :pass
|
212
210
|
end
|
@@ -221,11 +219,7 @@ module Adhearsion
|
|
221
219
|
yield component if block_given?
|
222
220
|
|
223
221
|
complete_event = component.complete_event
|
224
|
-
raise Adhearsion::Error, [complete_event.reason.details, component.inspect].join(": ") if complete_event.reason.is_a?
|
225
|
-
if complete_event.reason.is_a? Punchblock::Event::Complete::Hangup
|
226
|
-
call.terminating! unless call.terminating?
|
227
|
-
raise Call::Hangup
|
228
|
-
end
|
222
|
+
raise Adhearsion::Error, [complete_event.reason.details, component.inspect].join(": ") if complete_event.reason.is_a? Adhearsion::Event::Complete::Error
|
229
223
|
component
|
230
224
|
end
|
231
225
|
|
@@ -33,9 +33,11 @@ module Adhearsion
|
|
33
33
|
# @option options [Numeric] :for this option can be thought of best as a timeout.
|
34
34
|
# i.e. timeout after :for if no one answers the call
|
35
35
|
#
|
36
|
-
# @option options [CallController] :confirm
|
36
|
+
# @option options [CallController] :confirm Confirmation controller to execute. Confirmation will be attempted on all answered calls, and calls will be allowed to progress through confirmation in parallel. The first to complete confirmation will be joined to the A-leg, with the others being hung up.
|
37
37
|
# @option options [Hash] :confirm_metadata Metadata to set on the confirmation controller before executing it. This is shared between all calls if dialing multiple endpoints; if you care about it being mutated, you should provide an immutable value (using eg https://github.com/harukizaemon/hamster).
|
38
38
|
#
|
39
|
+
# @option options [CallController] :apology controller to execute on calls which lose the race to complete confirmation before they are hung up
|
40
|
+
#
|
39
41
|
# @option options [CallController] :cleanup The controller to execute on each call being cleaned up. This can be used, for instance, to notify that the call is being terminated. Calls are terminated right after this controller completes execution. If this is not specified, calls are silently terminated during cleanup.
|
40
42
|
# @option options [Hash] :cleanup_metadata Metadata to set on the cleanup controller before executing it. Defaults to :confirm_metadata if not specified.
|
41
43
|
#
|
@@ -68,23 +70,6 @@ module Adhearsion
|
|
68
70
|
catching_standard_errors { dial.delete_logger if dial }
|
69
71
|
end
|
70
72
|
|
71
|
-
# Dial one or more third parties and join one to this call after execution of a confirmation controller.
|
72
|
-
# Confirmation will be attempted on all answered calls, and calls will be allowed to progress through confirmation in parallel. The first to complete confirmation will be joined to the A-leg, with the others being hung up.
|
73
|
-
#
|
74
|
-
# @option options [CallController] :apology controller to execute on calls which lose the race to complete confirmation before they are hung up
|
75
|
-
#
|
76
|
-
# @see #dial
|
77
|
-
def dial_and_confirm(to, options = {})
|
78
|
-
dial = ParallelConfirmationDial.new to, options, call
|
79
|
-
dial.run(self)
|
80
|
-
dial.await_completion
|
81
|
-
dial.terminate_ringback
|
82
|
-
dial.cleanup_calls
|
83
|
-
dial.status
|
84
|
-
ensure
|
85
|
-
catching_standard_errors { dial.delete_logger if dial }
|
86
|
-
end
|
87
|
-
|
88
73
|
class Dial
|
89
74
|
attr_accessor :status
|
90
75
|
|
@@ -163,8 +148,6 @@ module Adhearsion
|
|
163
148
|
end
|
164
149
|
|
165
150
|
new_call.on_answer do |event|
|
166
|
-
pre_confirmation_tasks new_call
|
167
|
-
|
168
151
|
new_call.on_joined @call do |joined|
|
169
152
|
join_status.started joined.timestamp.to_time
|
170
153
|
end
|
@@ -377,6 +360,8 @@ module Adhearsion
|
|
377
360
|
@confirmation_controller = @options.delete :confirm
|
378
361
|
@confirmation_metadata = @options.delete :confirm_metadata
|
379
362
|
|
363
|
+
@apology_controller = @options.delete :apology
|
364
|
+
|
380
365
|
@pre_join = @options.delete :pre_join
|
381
366
|
@ringback = @options.delete :ringback
|
382
367
|
|
@@ -388,16 +373,18 @@ module Adhearsion
|
|
388
373
|
@skip_cleanup = false
|
389
374
|
end
|
390
375
|
|
391
|
-
def pre_confirmation_tasks(call)
|
392
|
-
on_all_except call do |target_call|
|
393
|
-
logger.info "#dial hanging up call #{target_call.id} because this call has been answered by another channel"
|
394
|
-
target_call.hangup
|
395
|
-
end
|
396
|
-
end
|
397
|
-
|
398
376
|
def pre_join_tasks(call)
|
399
377
|
@pre_join.call(call) if @pre_join
|
400
378
|
terminate_ringback
|
379
|
+
on_all_except call do |target_call|
|
380
|
+
if @apology_controller
|
381
|
+
logger.info "#dial executing apology controller #{@apology_controller} on call #{target_call.id} because this call has been confirmed by another channel"
|
382
|
+
target_call.async.execute_controller @apology_controller.new(target_call, @confirmation_metadata), ->(call) { call.hangup }
|
383
|
+
else
|
384
|
+
logger.info "#dial hanging up call #{target_call.id} because this call has been confirmed by another channel"
|
385
|
+
target_call.hangup
|
386
|
+
end
|
387
|
+
end
|
401
388
|
end
|
402
389
|
|
403
390
|
def on_all_except(call)
|
@@ -411,7 +398,7 @@ module Adhearsion
|
|
411
398
|
|
412
399
|
def ignoring_missing_joins
|
413
400
|
yield
|
414
|
-
rescue
|
401
|
+
rescue Adhearsion::ProtocolError => e
|
415
402
|
raise unless e.name == :service_unavailable
|
416
403
|
end
|
417
404
|
|
@@ -422,31 +409,6 @@ module Adhearsion
|
|
422
409
|
end
|
423
410
|
end
|
424
411
|
|
425
|
-
class ParallelConfirmationDial < Dial
|
426
|
-
private
|
427
|
-
|
428
|
-
def set_defaults
|
429
|
-
super
|
430
|
-
@apology_controller = @options.delete :apology
|
431
|
-
end
|
432
|
-
|
433
|
-
def pre_confirmation_tasks(call)
|
434
|
-
end
|
435
|
-
|
436
|
-
def pre_join_tasks(call)
|
437
|
-
super
|
438
|
-
on_all_except call do |target_call|
|
439
|
-
if @apology_controller
|
440
|
-
logger.info "#dial executing apology controller #{@apology_controller} on call #{target_call.id} because this call has been confirmed by another channel"
|
441
|
-
target_call.async.execute_controller @apology_controller.new(target_call, @confirmation_metadata), ->(call) { call.hangup }
|
442
|
-
else
|
443
|
-
logger.info "#dial hanging up call #{target_call.id} because this call has been confirmed by another channel"
|
444
|
-
target_call.hangup
|
445
|
-
end
|
446
|
-
end
|
447
|
-
end
|
448
|
-
end
|
449
|
-
|
450
412
|
class DialStatus
|
451
413
|
# The collection of calls created during the dial operation
|
452
414
|
attr_accessor :calls
|
@@ -1,90 +1,60 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
+
require 'adhearsion/call_controller/input/ask_grammar_builder'
|
4
|
+
require 'adhearsion/call_controller/input/prompt_builder'
|
5
|
+
require 'adhearsion/call_controller/input/menu_builder'
|
6
|
+
|
3
7
|
module Adhearsion
|
4
8
|
class CallController
|
5
9
|
module Input
|
6
10
|
|
7
|
-
|
8
|
-
def to_s
|
9
|
-
response
|
10
|
-
end
|
11
|
-
|
12
|
-
def inspect
|
13
|
-
"#<Adhearsion::CallController::Input::Result response=#{response.inspect}, status=#{status.inspect}>"
|
14
|
-
end
|
15
|
-
end
|
11
|
+
InputError = Class.new Adhearsion::Error
|
16
12
|
|
17
13
|
#
|
18
|
-
# Prompts for input
|
19
|
-
# timeouts, digit limits and terminator digits.
|
14
|
+
# Prompts for input, handling playback of prompts, DTMF grammar construction, and execution
|
20
15
|
#
|
21
|
-
# @example A basic digit collection:
|
16
|
+
# @example A basic DTMF digit collection:
|
22
17
|
# ask "Welcome, ", "/opt/sounds/menu-prompt.mp3",
|
23
|
-
# :
|
24
|
-
# buffer == "12980"
|
25
|
-
# end
|
18
|
+
# timeout: 10, terminator: '#', limit: 3
|
26
19
|
#
|
27
20
|
# The first arguments will be a list of sounds to play, as accepted by #play, including strings for TTS, Date and Time objects, and file paths.
|
28
|
-
# :timeout, :terminator and :limit options may
|
29
|
-
# A block may be passed which is invoked on each digit being collected. If it returns true, the collection is terminated.
|
21
|
+
# :timeout, :terminator and :limit options may be specified to automatically construct a grammar, or grammars may be manually specified.
|
30
22
|
#
|
31
23
|
# @param [Object, Array<Object>] args A list of outputs to play, as accepted by #play
|
32
|
-
# @param [Hash] options Options to
|
24
|
+
# @param [Hash] options Options to modify the grammar
|
33
25
|
# @option options [Boolean] :interruptible If the prompt should be interruptible or not. Defaults to true
|
34
26
|
# @option options [Integer] :limit Digit limit (causes collection to cease after a specified number of digits have been collected)
|
35
27
|
# @option options [Integer] :timeout Timeout in seconds before the first and between each input digit
|
36
28
|
# @option options [String] :terminator Digit to terminate input
|
29
|
+
# @option options [RubySpeech::GRXML::Grammar, Array<RubySpeech::GRXML::Grammar>] :grammar One of a collection of grammars to execute
|
30
|
+
# @option options [String, Array<String>] :grammar_url One of a collection of URLs for grammars to execute
|
31
|
+
# @option options [Hash] :input_options A hash of options passed directly to the Input constructor
|
32
|
+
# @option options [Hash] :output_options A hash of options passed directly to the Output constructor
|
37
33
|
#
|
38
|
-
# @return [Result] a result object from which the
|
34
|
+
# @return [Result] a result object from which the details of the utterance may be established
|
39
35
|
#
|
40
36
|
# @see Output#play
|
41
|
-
# @see
|
37
|
+
# @see Adhearsion::Rayo::Component::Input.new
|
38
|
+
# @see Adhearsion::Rayo::Component::Output.new
|
42
39
|
#
|
43
|
-
def ask(*args
|
44
|
-
|
40
|
+
def ask(*args)
|
41
|
+
options = args.last.kind_of?(Hash) ? args.pop : {}
|
42
|
+
prompts = args.flatten.compact
|
45
43
|
|
46
|
-
|
47
|
-
args << options
|
48
|
-
options = {}
|
49
|
-
end
|
50
|
-
sound_files = args.flatten
|
44
|
+
options[:grammar] || options[:grammar_url] || options[:limit] || options[:terminator] || raise(ArgumentError, "You must specify at least one of limit, terminator or grammar")
|
51
45
|
|
52
|
-
|
53
|
-
validator(&block) if block
|
54
|
-
end
|
55
|
-
menu_instance.validate :basic
|
56
|
-
result_of_menu = nil
|
46
|
+
grammars = AskGrammarBuilder.new(options).grammars
|
57
47
|
|
58
|
-
|
59
|
-
until MenuDSL::Menu::MenuResultDone === result_of_menu
|
60
|
-
raise unless menu_instance.should_continue?
|
48
|
+
output_document = prompts.empty? ? nil : output_formatter.ssml_for_collection(prompts)
|
61
49
|
|
62
|
-
|
63
|
-
|
64
|
-
if result_of_menu.is_a?(MenuDSL::Menu::MenuGetAnotherDigit)
|
65
|
-
next_digit = play_sound_files_for_menu menu_instance, sound_files
|
66
|
-
if next_digit
|
67
|
-
menu_instance << next_digit
|
68
|
-
else
|
69
|
-
menu_instance.timeout!
|
70
|
-
throw :finish
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
Result.new.tap do |result|
|
77
|
-
result.response = menu_instance.result
|
78
|
-
result.status = menu_instance.status
|
79
|
-
result.menu = menu_instance
|
80
|
-
end
|
50
|
+
PromptBuilder.new(output_document, grammars, options).execute self
|
81
51
|
end
|
82
52
|
|
83
53
|
# Creates and manages a multiple choice menu driven by DTMF, handling playback of prompts,
|
84
54
|
# invalid input, retries and timeouts, and final failures.
|
85
55
|
#
|
86
56
|
# @example A complete example of the method is as follows:
|
87
|
-
# menu "Welcome, ", "/opt/sounds/menu-prompt.mp3", :
|
57
|
+
# menu "Welcome, ", "/opt/sounds/menu-prompt.mp3", tries: 2, timeout: 10 do
|
88
58
|
# match 1, OperatorController
|
89
59
|
#
|
90
60
|
# match 10..19 do
|
@@ -92,7 +62,7 @@ module Adhearsion
|
|
92
62
|
# end
|
93
63
|
#
|
94
64
|
# match 5, 6, 9 do |exten|
|
95
|
-
#
|
65
|
+
# play "The #{exten} extension is currently not active"
|
96
66
|
# end
|
97
67
|
#
|
98
68
|
# match '7', OfficeController
|
@@ -111,14 +81,12 @@ module Adhearsion
|
|
111
81
|
# Input is matched against patterns, and the first exact match has it's payload executed.
|
112
82
|
# Matched input is passed in to the associated block, or to the controller through #options.
|
113
83
|
#
|
114
|
-
# Allowed payloads are the name of a controller class, in which case it is executed through its #run method, or a block.
|
84
|
+
# Allowed payloads are the name of a controller class, in which case it is executed through its #run method, or a block, which is executed in the context of the current controller.
|
115
85
|
#
|
116
86
|
# #invalid has its associated block executed when the input does not possibly match any pattern.
|
117
|
-
# #timeout's block is run when
|
87
|
+
# #timeout's block is run when timeout expires before receiving any input
|
118
88
|
# #failure runs its block when the maximum number of tries is reached without an input match.
|
119
89
|
#
|
120
|
-
# #validator runs its block on each digit being collected. If it returns true, the collection is terminated.
|
121
|
-
#
|
122
90
|
# Execution of the current context resumes after #menu finishes. If you wish to jump to an entirely different controller, use #pass.
|
123
91
|
# Menu will return :failed if failure was reached, or :done if a match was executed.
|
124
92
|
#
|
@@ -127,117 +95,26 @@ module Adhearsion
|
|
127
95
|
# @option options [Integer] :tries Number of tries allowed before failure
|
128
96
|
# @option options [Integer] :timeout Timeout in seconds before the first and between each input digit
|
129
97
|
# @option options [Boolean] :interruptible If the prompt should be interruptible or not. Defaults to true
|
98
|
+
# @option options [String, Symbol] :mode Input mode to accept. May be :voice or :dtmf.
|
99
|
+
# @option options [Hash] :input_options A hash of options passed directly to the Input constructor
|
100
|
+
# @option options [Hash] :output_options A hash of options passed directly to the Output constructor
|
130
101
|
#
|
131
|
-
# @return [Result] a result object from which the
|
102
|
+
# @return [Result] a result object from which the details of the utterance may be established
|
132
103
|
#
|
133
104
|
# @see Output#play
|
134
105
|
# @see CallController#pass
|
135
106
|
#
|
136
|
-
def menu(*args,
|
137
|
-
|
107
|
+
def menu(*args, &block)
|
108
|
+
raise ArgumentError, "You must specify a block to build the menu" unless block
|
109
|
+
options = args.last.kind_of?(Hash) ? args.pop : {}
|
110
|
+
prompts = args.flatten.compact
|
138
111
|
|
139
|
-
|
140
|
-
args << options
|
141
|
-
options = {}
|
142
|
-
end
|
143
|
-
sound_files = args.flatten
|
112
|
+
menu_builder = MenuBuilder.new(options, &block)
|
144
113
|
|
145
|
-
|
146
|
-
menu_instance.validate
|
147
|
-
result_of_menu = nil
|
114
|
+
output_document = prompts.empty? ? nil : output_formatter.ssml_for_collection(prompts)
|
148
115
|
|
149
|
-
|
150
|
-
until MenuDSL::Menu::MenuResultDone === result_of_menu
|
151
|
-
if menu_instance.should_continue?
|
152
|
-
result_of_menu = menu_instance.continue
|
153
|
-
else
|
154
|
-
logger.debug "Menu failed to get valid input. Calling \"failure\" hook."
|
155
|
-
menu_instance.execute_failure_hook
|
156
|
-
throw :finish
|
157
|
-
end
|
158
|
-
|
159
|
-
case result_of_menu
|
160
|
-
when MenuDSL::Menu::MenuResultInvalid
|
161
|
-
logger.debug "Menu received invalid input. Calling \"invalid\" hook and restarting."
|
162
|
-
menu_instance.execute_invalid_hook
|
163
|
-
menu_instance.restart!
|
164
|
-
result_of_menu = nil
|
165
|
-
when MenuDSL::Menu::MenuGetAnotherDigit
|
166
|
-
next_digit = play_sound_files_for_menu menu_instance, sound_files
|
167
|
-
if next_digit
|
168
|
-
menu_instance << next_digit
|
169
|
-
else
|
170
|
-
case result_of_menu
|
171
|
-
when MenuDSL::Menu::MenuGetAnotherDigitOrFinish
|
172
|
-
jump_to result_of_menu.match_object, :extension => result_of_menu.new_extension
|
173
|
-
throw :finish
|
174
|
-
when MenuDSL::Menu::MenuGetAnotherDigitOrTimeout
|
175
|
-
logger.debug "Menu timed out. Calling \"timeout\" hook and restarting."
|
176
|
-
menu_instance.execute_timeout_hook
|
177
|
-
menu_instance.restart!
|
178
|
-
result_of_menu = nil
|
179
|
-
end
|
180
|
-
end
|
181
|
-
when MenuDSL::Menu::MenuResultFound
|
182
|
-
logger.debug "Menu received valid input (#{result_of_menu.new_extension}). Calling the matching hook."
|
183
|
-
jump_to result_of_menu.match_object, :extension => result_of_menu.new_extension
|
184
|
-
throw :finish
|
185
|
-
end
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
Result.new.tap do |result|
|
190
|
-
result.response = menu_instance.result
|
191
|
-
result.status = menu_instance.status
|
192
|
-
result.menu = menu_instance
|
193
|
-
end
|
116
|
+
menu_builder.execute output_document, self
|
194
117
|
end
|
195
|
-
|
196
|
-
# @private
|
197
|
-
def play_sound_files_for_menu(menu_instance, sound_files)
|
198
|
-
digit = nil
|
199
|
-
if sound_files.any? && menu_instance.digit_buffer_empty?
|
200
|
-
if menu_instance.interruptible
|
201
|
-
digit = interruptible_play(*sound_files, renderer: menu_instance.renderer)
|
202
|
-
else
|
203
|
-
play(*sound_files, renderer: menu_instance.renderer)
|
204
|
-
end
|
205
|
-
end
|
206
|
-
digit || wait_for_digit(menu_instance.timeout)
|
207
|
-
end
|
208
|
-
|
209
|
-
#
|
210
|
-
# Waits for a single digit and returns it, or returns nil if nothing was pressed
|
211
|
-
#
|
212
|
-
# @param [Integer] timeout the timeout to wait before returning, in seconds. nil or -1 mean no timeout.
|
213
|
-
# @return [String, nil] the pressed key, or nil if timeout was reached.
|
214
|
-
#
|
215
|
-
# @private
|
216
|
-
#
|
217
|
-
def wait_for_digit(timeout = 1)
|
218
|
-
timeout = nil if timeout == -1
|
219
|
-
timeout *= 1_000 if timeout
|
220
|
-
input_component = execute_component_and_await_completion Punchblock::Component::Input.new :mode => :dtmf,
|
221
|
-
:initial_timeout => timeout,
|
222
|
-
:inter_digit_timeout => timeout,
|
223
|
-
:grammar => {
|
224
|
-
:value => grammar_accept.to_s
|
225
|
-
}
|
226
|
-
|
227
|
-
reason = input_component.complete_event.reason
|
228
|
-
result = reason.respond_to?(:utterance) ? reason.utterance : nil
|
229
|
-
parse_dtmf result
|
230
|
-
end
|
231
|
-
|
232
|
-
# @private
|
233
|
-
def jump_to(match_object, overrides = nil)
|
234
|
-
if match_object.block
|
235
|
-
instance_exec overrides[:extension], &match_object.block
|
236
|
-
else
|
237
|
-
invoke match_object.match_payload, overrides
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
118
|
end
|
242
119
|
end
|
243
120
|
end
|