adhearsion 2.6.4 → 3.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/.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
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Adhearsion
|
|
4
|
+
module Translator
|
|
5
|
+
class Asterisk
|
|
6
|
+
module Component
|
|
7
|
+
class Component
|
|
8
|
+
attr_reader :id, :call, :call_id
|
|
9
|
+
|
|
10
|
+
def initialize(component_node, call = nil)
|
|
11
|
+
@component_node, @call = component_node, call
|
|
12
|
+
@call_id = call.id if call
|
|
13
|
+
@id = Adhearsion.new_uuid
|
|
14
|
+
@complete = false
|
|
15
|
+
setup
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def setup
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def execute_command(command)
|
|
22
|
+
command.response = Adhearsion::ProtocolError.new.setup 'command-not-acceptable', "Did not understand command for component #{id}", call_id, id
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def send_complete_event(reason, recording = nil)
|
|
26
|
+
return if @complete
|
|
27
|
+
@complete = true
|
|
28
|
+
event = Adhearsion::Event::Complete.new reason: reason, recording: recording
|
|
29
|
+
send_event event
|
|
30
|
+
call.deregister_component id if call
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def send_event(event)
|
|
34
|
+
event.component_id = id
|
|
35
|
+
event.target_call_id = call_id
|
|
36
|
+
event.source_uri = id
|
|
37
|
+
translator.handle_pb_event event
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def logger_id
|
|
41
|
+
"#{self.class}: #{call_id ? "Call ID: #{call_id}, Component ID: #{id}" : id}"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def call_ended
|
|
45
|
+
send_complete_event Adhearsion::Event::Complete::Hangup.new
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def translator
|
|
51
|
+
@translator ||= call.translator
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def ami_client
|
|
55
|
+
translator.ami_client
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def set_node_response(value)
|
|
59
|
+
@component_node.response = value
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def send_ref
|
|
63
|
+
set_node_response Adhearsion::Rayo::Ref.new uri: id
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def with_error(name, text)
|
|
67
|
+
set_node_response Adhearsion::ProtocolError.new.setup(name, text)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def complete_with_error(error)
|
|
71
|
+
send_complete_event Adhearsion::Event::Complete::Error.new(details: error)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
%w{
|
|
80
|
+
asterisk
|
|
81
|
+
composed_prompt
|
|
82
|
+
input
|
|
83
|
+
output
|
|
84
|
+
mrcp_prompt
|
|
85
|
+
mrcp_native_prompt
|
|
86
|
+
record
|
|
87
|
+
stop_by_redirect
|
|
88
|
+
}.each { |component| require "adhearsion/translator/asterisk/component/#{component}" }
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Adhearsion
|
|
4
|
+
module Translator
|
|
5
|
+
class Asterisk
|
|
6
|
+
module Component
|
|
7
|
+
module Asterisk
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
require 'adhearsion/translator/asterisk/component/asterisk/agi_command'
|
|
15
|
+
require 'adhearsion/translator/asterisk/component/asterisk/ami_action'
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Adhearsion
|
|
4
|
+
module Translator
|
|
5
|
+
class Asterisk
|
|
6
|
+
module Component
|
|
7
|
+
module Asterisk
|
|
8
|
+
class AGICommand < Component
|
|
9
|
+
def setup
|
|
10
|
+
@agi = Translator::Asterisk::AGICommand.new id, @call.channel, @component_node.name, *@component_node.params
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def execute
|
|
14
|
+
@agi.execute ami_client
|
|
15
|
+
send_ref
|
|
16
|
+
rescue RubyAMI::Error
|
|
17
|
+
set_node_response false
|
|
18
|
+
rescue ChannelGoneError
|
|
19
|
+
set_node_response Adhearsion::ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{call_id}", call_id)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def handle_ami_event(event)
|
|
23
|
+
if (event.name == 'AsyncAGI' && event['SubEvent'] == 'Exec') || event.name == 'AsyncAGIExec'
|
|
24
|
+
send_complete_event success_reason(event)
|
|
25
|
+
if @component_node.name == 'ASYNCAGI BREAK' && @call.channel_var('ADHEARSION_END_ON_ASYNCAGI_BREAK')
|
|
26
|
+
@call.handle_hangup_event nil, event.best_time
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def success_reason(event)
|
|
34
|
+
result = @agi.parse_result event
|
|
35
|
+
Adhearsion::Rayo::Component::Asterisk::AGI::Command::Complete::Success.new result
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Adhearsion
|
|
4
|
+
module Translator
|
|
5
|
+
class Asterisk
|
|
6
|
+
module Component
|
|
7
|
+
module Asterisk
|
|
8
|
+
class AMIAction < Component
|
|
9
|
+
attr_reader :translator
|
|
10
|
+
|
|
11
|
+
def initialize(component_node, translator, ami_client)
|
|
12
|
+
super component_node, nil
|
|
13
|
+
@translator, @ami_client = translator, ami_client
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def execute
|
|
17
|
+
send_ref
|
|
18
|
+
response = send_action
|
|
19
|
+
final_event = send_events response
|
|
20
|
+
send_complete_event success_reason(response, final_event)
|
|
21
|
+
rescue RubyAMI::Error => e
|
|
22
|
+
send_complete_event error_reason(e)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def send_action
|
|
28
|
+
@ami_client.send_action @component_node.name, action_headers
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def error_reason(response)
|
|
32
|
+
Adhearsion::Event::Complete::Error.new details: response.message
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def success_reason(response, final_event = nil)
|
|
36
|
+
headers = response.headers
|
|
37
|
+
headers.merge! final_event.headers if final_event
|
|
38
|
+
headers.delete 'ActionID'
|
|
39
|
+
Adhearsion::Rayo::Component::Asterisk::AMI::Action::Complete::Success.new message: headers.delete('Message'), text_body: response.text_body, headers: headers
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def send_events(response)
|
|
43
|
+
final_event = response.events.pop
|
|
44
|
+
response.events.each do |e|
|
|
45
|
+
send_event pb_event_from_ami_event(e)
|
|
46
|
+
end
|
|
47
|
+
final_event
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def pb_event_from_ami_event(ami_event)
|
|
51
|
+
headers = ami_event.headers
|
|
52
|
+
headers.delete 'ActionID'
|
|
53
|
+
Adhearsion::Event::Asterisk::AMI.new name: ami_event.name, headers: headers
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def action_headers
|
|
57
|
+
headers = {}
|
|
58
|
+
@component_node.params.each_pair do |key, value|
|
|
59
|
+
headers[key.to_s.capitalize] = value
|
|
60
|
+
end
|
|
61
|
+
headers
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'adhearsion/translator/asterisk/component/input_component'
|
|
4
|
+
require 'adhearsion/translator/asterisk/component/stop_by_redirect'
|
|
5
|
+
|
|
6
|
+
module Adhearsion
|
|
7
|
+
module Translator
|
|
8
|
+
class Asterisk
|
|
9
|
+
module Component
|
|
10
|
+
class ComposedPrompt < Component
|
|
11
|
+
include InputComponent
|
|
12
|
+
include StopByRedirect
|
|
13
|
+
|
|
14
|
+
def execute
|
|
15
|
+
validate
|
|
16
|
+
output_command.request!
|
|
17
|
+
setup_dtmf_recognizer
|
|
18
|
+
|
|
19
|
+
@output_incomplete = true
|
|
20
|
+
|
|
21
|
+
@output_component = Output.new(output_command, @call)
|
|
22
|
+
call.register_component @output_component
|
|
23
|
+
fut = Celluloid::Future.new { @output_component.execute }
|
|
24
|
+
|
|
25
|
+
case @output_command.response
|
|
26
|
+
when Adhearsion::Rayo::Ref
|
|
27
|
+
send_ref
|
|
28
|
+
else
|
|
29
|
+
set_node_response @output_command.response
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
if @component_node.barge_in
|
|
33
|
+
@barged = false
|
|
34
|
+
register_dtmf_event_handler
|
|
35
|
+
fut.value # Block until output is complete before starting timers
|
|
36
|
+
@output_incomplete = false
|
|
37
|
+
start_timers unless @barged
|
|
38
|
+
else
|
|
39
|
+
fut.value # Block until output is complete before allowing input
|
|
40
|
+
register_dtmf_event_handler
|
|
41
|
+
start_timers
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def process_dtmf(digit)
|
|
46
|
+
if @component_node.barge_in && @output_incomplete
|
|
47
|
+
@output_component.stop_by_redirect Adhearsion::Event::Complete::Stop.new
|
|
48
|
+
@barged = true
|
|
49
|
+
end
|
|
50
|
+
super
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def output_command
|
|
54
|
+
@output_command ||= @component_node.output
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def input_node
|
|
60
|
+
@input_node ||= @component_node.input
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def register_dtmf_event_handler
|
|
64
|
+
@dtmf_handler_id = call.register_handler :ami, [{:name => 'DTMF', [:[], 'End'] => 'Yes'}, {:name => 'DTMFEnd'}] do |event|
|
|
65
|
+
process_dtmf event['Digit']
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def unregister_dtmf_event_handler
|
|
70
|
+
call.unregister_handler :ami, @dtmf_handler_id if instance_variable_defined?(:@dtmf_handler_id)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'ruby_speech'
|
|
4
|
+
require 'singleton'
|
|
5
|
+
require 'adhearsion/translator/asterisk/component'
|
|
6
|
+
|
|
7
|
+
module Adhearsion
|
|
8
|
+
module Translator
|
|
9
|
+
class Asterisk
|
|
10
|
+
module Component
|
|
11
|
+
class DTMFRecognizer
|
|
12
|
+
class BuiltinMatcherCache
|
|
13
|
+
include Singleton
|
|
14
|
+
include MonitorMixin
|
|
15
|
+
|
|
16
|
+
def get(uri)
|
|
17
|
+
cache[uri] ||= fetch(uri)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def fetch(uri)
|
|
23
|
+
grammar = RubySpeech::GRXML.from_uri(uri)
|
|
24
|
+
RubySpeech::GRXML::Matcher.new(grammar)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def cache
|
|
28
|
+
@cache ||= {}
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
include Celluloid
|
|
33
|
+
|
|
34
|
+
def initialize(responder, grammar, initial_timeout = nil, inter_digit_timeout = nil, terminator = nil)
|
|
35
|
+
@responder = responder
|
|
36
|
+
self.initial_timeout = initial_timeout || -1
|
|
37
|
+
self.inter_digit_timeout = inter_digit_timeout || -1
|
|
38
|
+
@terminator = terminator
|
|
39
|
+
@finished = false
|
|
40
|
+
|
|
41
|
+
@matcher = if grammar.url
|
|
42
|
+
BuiltinMatcherCache.instance.get(grammar.url)
|
|
43
|
+
else
|
|
44
|
+
RubySpeech::GRXML::Matcher.new RubySpeech::GRXML.import(grammar.value.to_s)
|
|
45
|
+
end
|
|
46
|
+
@buffer = ""
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def <<(digit)
|
|
50
|
+
cancel_initial_timer
|
|
51
|
+
@buffer << digit unless terminating?(digit)
|
|
52
|
+
case (match = get_match)
|
|
53
|
+
when RubySpeech::GRXML::NoMatch
|
|
54
|
+
finalize :nomatch
|
|
55
|
+
when RubySpeech::GRXML::MaxMatch
|
|
56
|
+
finalize :match, match
|
|
57
|
+
when RubySpeech::GRXML::Match
|
|
58
|
+
finalize :match, match if terminating?(digit)
|
|
59
|
+
when RubySpeech::GRXML::PotentialMatch
|
|
60
|
+
finalize :nomatch if terminating?(digit)
|
|
61
|
+
end
|
|
62
|
+
reset_inter_digit_timer unless @finished
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def start_timers
|
|
66
|
+
begin_initial_timer @initial_timeout/1000 unless @initial_timeout == -1
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
def terminating?(digit)
|
|
72
|
+
digit == @terminator
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def get_match
|
|
76
|
+
@matcher.match @buffer.dup
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def initial_timeout=(other)
|
|
80
|
+
raise OptionError, 'An initial timeout value that is negative (and not -1) is invalid.' if other < -1
|
|
81
|
+
@initial_timeout = other
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def inter_digit_timeout=(other)
|
|
85
|
+
raise OptionError, 'An inter-digit timeout value that is negative (and not -1) is invalid.' if other < -1
|
|
86
|
+
@inter_digit_timeout = other
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def begin_initial_timer(timeout)
|
|
90
|
+
@initial_timer = after timeout do
|
|
91
|
+
finalize :noinput
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def cancel_initial_timer
|
|
96
|
+
return unless instance_variable_defined?(:@initial_timer) && @initial_timer
|
|
97
|
+
@initial_timer.cancel
|
|
98
|
+
@initial_timer = nil
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def reset_inter_digit_timer
|
|
102
|
+
return if @inter_digit_timeout == -1
|
|
103
|
+
@inter_digit_timer ||= begin
|
|
104
|
+
after @inter_digit_timeout/1000 do
|
|
105
|
+
case (match = get_match)
|
|
106
|
+
when RubySpeech::GRXML::Match
|
|
107
|
+
finalize :match, match
|
|
108
|
+
else
|
|
109
|
+
finalize :nomatch
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
@inter_digit_timer.reset
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def cancel_inter_digit_timer
|
|
117
|
+
return unless instance_variable_defined?(:@inter_digit_timer) && @inter_digit_timer
|
|
118
|
+
@inter_digit_timer.cancel
|
|
119
|
+
@inter_digit_timer = nil
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def finalize(match_type, match = nil)
|
|
123
|
+
cancel_initial_timer
|
|
124
|
+
cancel_inter_digit_timer
|
|
125
|
+
if match
|
|
126
|
+
@responder.send match_type, match
|
|
127
|
+
else
|
|
128
|
+
@responder.send match_type
|
|
129
|
+
end
|
|
130
|
+
@finished = true
|
|
131
|
+
terminate
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'adhearsion/translator/asterisk/component/input_component'
|
|
4
|
+
|
|
5
|
+
module Adhearsion
|
|
6
|
+
module Translator
|
|
7
|
+
class Asterisk
|
|
8
|
+
module Component
|
|
9
|
+
class Input < Component
|
|
10
|
+
|
|
11
|
+
include InputComponent
|
|
12
|
+
|
|
13
|
+
def execute
|
|
14
|
+
@call.send_progress
|
|
15
|
+
super
|
|
16
|
+
@dtmf_handler_id = register_dtmf_event_handler
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def register_dtmf_event_handler
|
|
22
|
+
call.register_handler :ami, [{:name => 'DTMF', [:[], 'End'] => 'Yes'}, {:name => 'DTMFEnd'}] do |event|
|
|
23
|
+
process_dtmf event['Digit']
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def unregister_dtmf_event_handler
|
|
28
|
+
call.unregister_handler :ami, @dtmf_handler_id if instance_variable_defined?(:@dtmf_handler_id)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|