adhearsion 2.1.3 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +87 -0
- data/Guardfile +1 -1
- data/Rakefile +1 -2
- data/adhearsion.gemspec +1 -1
- data/features/cli_create.feature +1 -0
- data/features/step_definitions/cli_steps.rb +0 -10
- data/lib/adhearsion.rb +11 -0
- data/lib/adhearsion/call.rb +27 -12
- data/lib/adhearsion/call_controller.rb +1 -1
- data/lib/adhearsion/call_controller/dial.rb +3 -1
- data/lib/adhearsion/call_controller/input.rb +4 -4
- data/lib/adhearsion/call_controller/menu_dsl.rb +1 -0
- data/lib/adhearsion/call_controller/menu_dsl/array_match_calculator.rb +26 -0
- data/lib/adhearsion/call_controller/menu_dsl/fixnum_match_calculator.rb +2 -14
- data/lib/adhearsion/call_controller/menu_dsl/string_match_calculator.rb +6 -6
- data/lib/adhearsion/call_controller/output.rb +20 -14
- data/lib/adhearsion/call_controller/output/abstract_player.rb +5 -5
- data/lib/adhearsion/call_controller/output/formatter.rb +68 -68
- data/lib/adhearsion/call_controller/record.rb +91 -28
- data/lib/adhearsion/call_controller/utility.rb +12 -5
- data/lib/adhearsion/calls.rb +1 -1
- data/lib/adhearsion/configuration.rb +4 -0
- data/lib/adhearsion/events.rb +2 -1
- data/lib/adhearsion/generators/app/app_generator.rb +2 -2
- data/lib/adhearsion/generators/app/templates/Gemfile.erb +4 -0
- data/lib/adhearsion/generators/app/templates/Rakefile +5 -0
- data/lib/adhearsion/generators/app/templates/lib/simon_game.rb +3 -0
- data/lib/adhearsion/generators/app/templates/rspec +2 -0
- data/lib/adhearsion/generators/app/templates/spec/call_controllers/simon_game_spec.rb +142 -0
- data/lib/adhearsion/generators/controller/templates/lib/controller.rb +1 -1
- data/lib/adhearsion/generators/controller/templates/spec/controller_spec.rb +2 -0
- data/lib/adhearsion/initializer.rb +3 -2
- data/lib/adhearsion/outbound_call.rb +5 -2
- data/lib/adhearsion/router/route.rb +13 -2
- data/lib/adhearsion/rspec.rb +1 -1
- data/lib/adhearsion/statistics.rb +138 -0
- data/lib/adhearsion/tasks/environment.rb +1 -1
- data/lib/adhearsion/version.rb +1 -1
- data/spec/adhearsion/call_controller/dial_spec.rb +26 -0
- data/spec/adhearsion/call_controller/input_spec.rb +13 -1
- data/spec/adhearsion/call_controller/menu_dsl/array_match_calculator_spec.rb +76 -0
- data/spec/adhearsion/call_controller/menu_dsl/fixnum_match_calculator_spec.rb +8 -6
- data/spec/adhearsion/call_controller/menu_dsl/range_match_calculator_spec.rb +4 -4
- data/spec/adhearsion/call_controller/menu_dsl/string_match_calculator_spec.rb +6 -6
- data/spec/adhearsion/call_controller/output/formatter_spec.rb +3 -5
- data/spec/adhearsion/call_controller/output_spec.rb +59 -25
- data/spec/adhearsion/call_controller/record_spec.rb +123 -2
- data/spec/adhearsion/call_controller/utility_spec.rb +31 -11
- data/spec/adhearsion/call_spec.rb +77 -36
- data/spec/adhearsion/calls_spec.rb +13 -0
- data/spec/adhearsion/initializer_spec.rb +7 -0
- data/spec/adhearsion/outbound_call_spec.rb +14 -0
- data/spec/adhearsion/punchblock_plugin_spec.rb +5 -2
- data/spec/adhearsion/router/openended_route_spec.rb +2 -1
- data/spec/adhearsion/router/route_spec.rb +9 -1
- data/spec/adhearsion/router/unaccepting_route_spec.rb +2 -1
- data/spec/adhearsion/statistics/dump_spec.rb +38 -0
- data/spec/adhearsion/statistics_spec.rb +61 -0
- data/spec/adhearsion_spec.rb +21 -1
- data/spec/spec_helper.rb +2 -0
- metadata +16 -7
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,92 @@
|
|
1
1
|
# [develop](https://github.com/adhearsion/adhearsion)
|
2
2
|
|
3
|
+
# [2.2.0](https://github.com/adhearsion/adhearsion/compare/v2.1.3...v2.2.0) - [2012-12-17](https://rubygems.org/gems/adhearsion/versions/2.2.0)
|
4
|
+
* Feature: Statistics API providing counts of calls dialed, offered, rejected, routed and active
|
5
|
+
|
6
|
+
```ruby
|
7
|
+
Adhearsion.statistics.dump # => #<Adhearsion::Statistics::Dump timestamp=2012-12-17 10:31:05 -0500, call_counts={:dialed=>0, :offered=>18, :routed=>6, :rejected=>0, :active=>0}, calls_by_route={"Sesame Street"=>3, "Mr. Rogers Neighborhood"=>2, "default"=>1}>
|
8
|
+
```
|
9
|
+
* Feature: Accessor for peer calls when bridged
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
call.peers # => {"0f4h382j290k09k" => #<Adhearsion::Call ...>}
|
13
|
+
```
|
14
|
+
* Feature: Allow specifying controller metadata when originating outbound calls
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
Adhearsion::OutboundCall.originate 'foo@bar.com', controller: FooBarController, controller_metadata: {foo: 'bar'}
|
18
|
+
```
|
19
|
+
* Feature: Allow specifying confirmation controller metadata to `CallController#dial`
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
dial 'foo@bar.com', confirm: ConfirmationController, confirm_metadata: {foo: 'bar'}
|
23
|
+
```
|
24
|
+
* Feature: Set default voice on output components when specified in config
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
config.punchblock.default_voice = 'kal'
|
28
|
+
```
|
29
|
+
* Feature: Be more flexible about DTMF utterance parsing
|
30
|
+
* Feature: Added specs for the SimonGame
|
31
|
+
* Feature: Allow configuring the lifetime of a call object after hangup. This makes it possible to control the number of call objects (and therefore threads) in use by Adhearsion, by expiring them earlier or later than the 30 second default (as measured from the point at which the call disconnects).
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
config.platform.after_hangup_lifetime = 10
|
35
|
+
```
|
36
|
+
* Feature: Support collections passed to `CallController#play`
|
37
|
+
```ruby
|
38
|
+
recordings = ['one', 'two', 'three']
|
39
|
+
play recordings
|
40
|
+
````
|
41
|
+
* Feature: Support arrays passed to `#match` in a `CallController#menu`
|
42
|
+
```ruby
|
43
|
+
possible_digits = [1,2,3,4]
|
44
|
+
menu 'foobar' do
|
45
|
+
match possible_digits, FooController
|
46
|
+
end
|
47
|
+
```
|
48
|
+
* Feature: Output document formatter for a call controller is now overridable
|
49
|
+
```ruby
|
50
|
+
# Replacement formatter designed to render all TTS extra slow
|
51
|
+
class MyFormatter < Adhearsion::CallController::Output::Formatter
|
52
|
+
def ssml_for_text(argument, options = {})
|
53
|
+
RubySpeech::SSML.draw do
|
54
|
+
prosody rate: 'x-slow' do
|
55
|
+
argument
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class MyController < Adhearsion::CallController
|
62
|
+
def run
|
63
|
+
speak "This will be sloooooow"
|
64
|
+
end
|
65
|
+
|
66
|
+
def output_formatter
|
67
|
+
MyFormatter.new
|
68
|
+
end
|
69
|
+
end
|
70
|
+
```
|
71
|
+
* Feature: Refactored recording functionality into a Recorder class for easier implementation of specific APIs
|
72
|
+
```ruby
|
73
|
+
# Alternative #record implementation, returning the input component also
|
74
|
+
def record(options = {})
|
75
|
+
recorder = Recorder.new self, options
|
76
|
+
|
77
|
+
recorder.handle_record_completion do |event|
|
78
|
+
catching_standard_errors { yield event if block_given? }
|
79
|
+
end
|
80
|
+
|
81
|
+
recorder.run
|
82
|
+
[recorder.record_component, recorder.stopper_component]
|
83
|
+
end
|
84
|
+
```
|
85
|
+
* Bugfix: Generate sane spec defaults for new apps and controllers
|
86
|
+
* Bugfix: `CallController#record` now allows partial-second timeouts
|
87
|
+
* Bugfix: Ensure calls are removed from the active collection when they terminate cleanly
|
88
|
+
* Bugfix: Plug a big memory leak
|
89
|
+
|
3
90
|
# [2.1.3](https://github.com/adhearsion/adhearsion/compare/v2.1.2...v2.1.3) - [2012-10-11](https://rubygems.org/gems/adhearsion/versions/2.1.3)
|
4
91
|
* Bugfix: Originating call is now answered before joining calls using `CallController#dial`
|
5
92
|
* Bugfix: Output controller methods no longer falsely detect a string with a colon as a URI for an audio file
|
data/Guardfile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
ENV['SKIP_RCOV'] = 'true'
|
2
2
|
|
3
3
|
group 'rspec' do
|
4
|
-
guard 'rspec', :
|
4
|
+
guard 'rspec', :cli => '--format documentation' do
|
5
5
|
watch(%r{^spec/.+_spec\.rb$})
|
6
6
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
7
7
|
watch('spec/spec_helper.rb') { "spec/" }
|
data/Rakefile
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# -*- ruby -*-
|
2
|
-
ENV['RUBY_FLAGS'] = "-I#{%w(lib ext bin spec).join(File::PATH_SEPARATOR)}"
|
3
2
|
|
4
3
|
require 'bundler/gem_tasks'
|
5
4
|
require 'bundler/setup'
|
@@ -9,7 +8,7 @@ task :gem => :build
|
|
9
8
|
|
10
9
|
require 'rspec/core/rake_task'
|
11
10
|
RSpec::Core::RakeTask.new(:spec) do |t|
|
12
|
-
t.ruby_opts = "-w -r./spec/capture_warnings"
|
11
|
+
# t.ruby_opts = "-w -r./spec/capture_warnings"
|
13
12
|
end
|
14
13
|
|
15
14
|
require 'ci/reporter/rake/rspec'
|
data/adhearsion.gemspec
CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
|
|
26
26
|
s.add_runtime_dependency 'ffi', ["~> 1.0"]
|
27
27
|
s.add_runtime_dependency 'future-resource', ["~> 1.0"]
|
28
28
|
s.add_runtime_dependency 'girl_friday'
|
29
|
-
s.add_runtime_dependency 'has-guarded-handlers', ["~> 1.
|
29
|
+
s.add_runtime_dependency 'has-guarded-handlers', ["~> 1.5"]
|
30
30
|
s.add_runtime_dependency 'jruby-openssl' if RUBY_PLATFORM == 'java'
|
31
31
|
s.add_runtime_dependency 'logging', ["~> 1.8"]
|
32
32
|
s.add_runtime_dependency 'pry'
|
data/features/cli_create.feature
CHANGED
@@ -22,16 +22,6 @@ When /^I wait (\d+) seconds?$/ do |arg1|
|
|
22
22
|
sleep arg1.to_i
|
23
23
|
end
|
24
24
|
|
25
|
-
# TODO: Remove after pull request is merged in cucumber.rb from Aruba
|
26
|
-
When /^I wait for (?:output|stdout) to contain "([^"]*)"$/ do |expected|
|
27
|
-
Timeout::timeout(exit_timeout) do
|
28
|
-
loop do
|
29
|
-
break if assert_partial_output_interactive(expected)
|
30
|
-
sleep 0.1
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
25
|
Given /^that I create a valid app under "([^"]*)"$/ do |path|
|
36
26
|
steps %Q{
|
37
27
|
When I run `ahn create #{path}`
|
data/lib/adhearsion.rb
CHANGED
@@ -34,6 +34,7 @@ module Adhearsion
|
|
34
34
|
autoload :OutboundCall
|
35
35
|
autoload :Plugin
|
36
36
|
autoload :Router
|
37
|
+
autoload :Statistics
|
37
38
|
|
38
39
|
class << self
|
39
40
|
|
@@ -105,6 +106,16 @@ module Adhearsion
|
|
105
106
|
end
|
106
107
|
end
|
107
108
|
|
109
|
+
#
|
110
|
+
# @return [Adhearsion::Statistics] a statistics aggregator object capable of producing stats dumps
|
111
|
+
def statistics
|
112
|
+
if instance_variable_defined?(:@statistics) && @statistics.alive?
|
113
|
+
@statistics
|
114
|
+
else
|
115
|
+
@statistics = Statistics.new.tap(&:setup_event_handlers)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
108
119
|
def status
|
109
120
|
Adhearsion::Process.state_name
|
110
121
|
end
|
data/lib/adhearsion/call.rb
CHANGED
@@ -23,17 +23,10 @@ module Adhearsion
|
|
23
23
|
rescue Celluloid::DeadActorError
|
24
24
|
raise ExpiredError, "This call is expired and is no longer accessible"
|
25
25
|
end
|
26
|
-
|
27
|
-
def proxy.join(*args)
|
28
|
-
Actor.call @mailbox, :join, *args
|
29
|
-
end
|
30
26
|
end
|
31
27
|
end
|
32
28
|
|
33
|
-
|
34
|
-
attr_accessor :offer, :client, :end_reason, :commands, :controllers
|
35
|
-
|
36
|
-
attr_accessor :variables
|
29
|
+
attr_reader :end_reason, :commands, :controllers, :variables
|
37
30
|
|
38
31
|
delegate :[], :[]=, :to => :variables
|
39
32
|
delegate :to, :from, :to => :offer, :allow_nil => true
|
@@ -41,11 +34,13 @@ module Adhearsion
|
|
41
34
|
def initialize(offer = nil)
|
42
35
|
register_initial_handlers
|
43
36
|
|
37
|
+
@offer = nil
|
44
38
|
@tags = []
|
45
39
|
@commands = CommandRegistry.new
|
46
40
|
@variables = {}
|
47
41
|
@controllers = []
|
48
42
|
@end_reason = nil
|
43
|
+
@peers = {}
|
49
44
|
|
50
45
|
self << offer if offer
|
51
46
|
end
|
@@ -92,6 +87,14 @@ module Adhearsion
|
|
92
87
|
@tags.include? label
|
93
88
|
end
|
94
89
|
|
90
|
+
#
|
91
|
+
# Hash of joined peers
|
92
|
+
# @return [Hash<String => Adhearsion::Call>]
|
93
|
+
#
|
94
|
+
def peers
|
95
|
+
@peers.clone
|
96
|
+
end
|
97
|
+
|
95
98
|
def register_event_handler(*guards, &block)
|
96
99
|
register_handler :event, *guards, &block
|
97
100
|
end
|
@@ -117,11 +120,13 @@ module Adhearsion
|
|
117
120
|
|
118
121
|
on_joined do |event|
|
119
122
|
target = event.call_id || event.mixer_name
|
123
|
+
@peers[target] = Adhearsion.active_calls[target]
|
120
124
|
signal :joined, target
|
121
125
|
end
|
122
126
|
|
123
127
|
on_unjoined do |event|
|
124
128
|
target = event.call_id || event.mixer_name
|
129
|
+
@peers.delete target
|
125
130
|
signal :unjoined, target
|
126
131
|
end
|
127
132
|
|
@@ -130,14 +135,13 @@ module Adhearsion
|
|
130
135
|
clear_from_active_calls
|
131
136
|
@end_reason = event.reason
|
132
137
|
commands.terminate
|
133
|
-
after(
|
138
|
+
after(Adhearsion.config.platform.after_hangup_lifetime) { current_actor.terminate! }
|
134
139
|
throw :pass
|
135
140
|
end
|
136
141
|
end
|
137
142
|
|
138
|
-
|
139
|
-
|
140
|
-
30
|
143
|
+
def finalize
|
144
|
+
::Logging::Repository.reset
|
141
145
|
end
|
142
146
|
|
143
147
|
##
|
@@ -197,6 +201,7 @@ module Adhearsion
|
|
197
201
|
|
198
202
|
def reject(reason = :busy, headers = nil)
|
199
203
|
write_and_await_response Punchblock::Command::Reject.new(:reason => reason, :headers => headers)
|
204
|
+
Adhearsion::Events.trigger_immediately :call_rejected, call: current_actor, reason: reason
|
200
205
|
end
|
201
206
|
|
202
207
|
def hangup(headers = nil)
|
@@ -342,6 +347,16 @@ module Adhearsion
|
|
342
347
|
controllers.each(&:resume!)
|
343
348
|
end
|
344
349
|
|
350
|
+
private
|
351
|
+
|
352
|
+
def offer
|
353
|
+
@offer
|
354
|
+
end
|
355
|
+
|
356
|
+
def client
|
357
|
+
@client
|
358
|
+
end
|
359
|
+
|
345
360
|
# @private
|
346
361
|
class CommandRegistry < ThreadSafeArray
|
347
362
|
def terminate
|
@@ -32,6 +32,7 @@ module Adhearsion
|
|
32
32
|
# i.e. timeout after :for if no one answers the call
|
33
33
|
#
|
34
34
|
# @option options [CallController] :confirm the controller to execute on answered outbound calls to give an opportunity to screen the call. The calls will be joined if the outbound call is still active after this controller completes.
|
35
|
+
# @option options [Hash] :confirm_metadata Metadata to set on the confirmation controller before executing it.
|
35
36
|
#
|
36
37
|
# @example Make a call to the PSTN using my SIP provider for VoIP termination
|
37
38
|
# dial "SIP/19095551001@my.sip.voip.terminator.us"
|
@@ -73,6 +74,7 @@ module Adhearsion
|
|
73
74
|
@options[:timeout] ||= _for if _for
|
74
75
|
|
75
76
|
@confirmation_controller = @options.delete :confirm
|
77
|
+
@confirmation_metadata = @options.delete :confirm_metadata
|
76
78
|
end
|
77
79
|
|
78
80
|
def run
|
@@ -112,7 +114,7 @@ module Adhearsion
|
|
112
114
|
|
113
115
|
if @confirmation_controller
|
114
116
|
status.unconfirmed!
|
115
|
-
new_call.execute_controller @confirmation_controller.new(new_call), lambda { |call| call.signal :confirmed }
|
117
|
+
new_call.execute_controller @confirmation_controller.new(new_call, @confirmation_metadata), lambda { |call| call.signal :confirmed }
|
116
118
|
new_call.wait :confirmed
|
117
119
|
end
|
118
120
|
|
@@ -79,7 +79,7 @@ module Adhearsion
|
|
79
79
|
# invalid input, retries and timeouts, and final failures.
|
80
80
|
#
|
81
81
|
# @example A complete example of the method is as follows:
|
82
|
-
#
|
82
|
+
# menu "Welcome, ", "/opt/sounds/menu-prompt.mp3", :tries => 2, :timeout => 10 do
|
83
83
|
# match 1, OperatorController
|
84
84
|
#
|
85
85
|
# match 10..19 do
|
@@ -114,7 +114,7 @@ module Adhearsion
|
|
114
114
|
#
|
115
115
|
# #validator runs its block on each digit being collected. If it returns true, the collection is terminated.
|
116
116
|
#
|
117
|
-
# Execution of the current context resumes after #
|
117
|
+
# Execution of the current context resumes after #menu finishes. If you wish to jump to an entirely different controller, use #pass.
|
118
118
|
# Menu will return :failed if failure was reached, or :done if a match was executed.
|
119
119
|
#
|
120
120
|
# @param [Object] args A list of outputs to play, as accepted by #play
|
@@ -215,8 +215,8 @@ module Adhearsion
|
|
215
215
|
}
|
216
216
|
|
217
217
|
reason = input_component.complete_event.reason
|
218
|
-
result = reason.respond_to?(:
|
219
|
-
|
218
|
+
result = reason.respond_to?(:utterance) ? reason.utterance : nil
|
219
|
+
parse_dtmf result
|
220
220
|
end
|
221
221
|
|
222
222
|
# @private
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Adhearsion
|
4
|
+
class CallController
|
5
|
+
module MenuDSL
|
6
|
+
class ArrayMatchCalculator < MatchCalculator
|
7
|
+
def match(query)
|
8
|
+
args = { :query => query, :exact_matches => [], :potential_matches => [] }
|
9
|
+
|
10
|
+
pattern.compact.each do |pat|
|
11
|
+
pattern_string = pat.to_s
|
12
|
+
query_string = query.to_s
|
13
|
+
|
14
|
+
if pattern_string == query_string
|
15
|
+
args[:exact_matches] << pat
|
16
|
+
elsif pattern_string.starts_with? query_string
|
17
|
+
args[:potential_matches] << pat
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
new_calculated_match args
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -3,20 +3,8 @@
|
|
3
3
|
module Adhearsion
|
4
4
|
class CallController
|
5
5
|
module MenuDSL
|
6
|
-
class FixnumMatchCalculator <
|
7
|
-
|
8
|
-
def match(query)
|
9
|
-
numeric_query = coerce_to_numeric query
|
10
|
-
exact_match, potential_match = nil
|
11
|
-
if pattern == numeric_query
|
12
|
-
exact_match = pattern
|
13
|
-
elsif pattern.to_s.starts_with? query.to_s
|
14
|
-
potential_match = pattern
|
15
|
-
end
|
16
|
-
new_calculated_match :query => query, :exact_matches => exact_match, :potential_matches => potential_match
|
17
|
-
end
|
18
|
-
|
19
|
-
end # class FixnumMatchCalculator
|
6
|
+
class FixnumMatchCalculator < StringMatchCalculator
|
7
|
+
end
|
20
8
|
end
|
21
9
|
end
|
22
10
|
end
|
@@ -3,23 +3,23 @@
|
|
3
3
|
module Adhearsion
|
4
4
|
class CallController
|
5
5
|
module MenuDSL
|
6
|
-
|
7
6
|
class StringMatchCalculator < MatchCalculator
|
8
7
|
|
9
8
|
def match(query)
|
10
9
|
args = { :query => query, :exact_matches => nil, :potential_matches => nil }
|
11
10
|
|
12
|
-
|
11
|
+
pattern_string = pattern.to_s
|
12
|
+
query_string = query.to_s
|
13
|
+
|
14
|
+
if pattern_string == query_string
|
13
15
|
args[:exact_matches] = [pattern]
|
14
|
-
elsif
|
16
|
+
elsif pattern_string.starts_with? query_string
|
15
17
|
args[:potential_matches] = [pattern]
|
16
18
|
end
|
17
19
|
|
18
20
|
new_calculated_match args
|
19
21
|
end
|
20
|
-
|
21
|
-
end # class StringMatchCalculator
|
22
|
-
|
22
|
+
end
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -21,7 +21,7 @@ module Adhearsion
|
|
21
21
|
# @raises [PlaybackError] if the given argument could not be played
|
22
22
|
#
|
23
23
|
def say(text, options = {})
|
24
|
-
player.play_ssml(text, options) || player.output(
|
24
|
+
player.play_ssml(text, options) || player.output(output_formatter.ssml_for_text(text.to_s), options)
|
25
25
|
end
|
26
26
|
alias :speak :say
|
27
27
|
|
@@ -34,7 +34,7 @@ module Adhearsion
|
|
34
34
|
# @raises [PlaybackError] if the given argument could not be played
|
35
35
|
#
|
36
36
|
def say!(text, options = {})
|
37
|
-
async_player.play_ssml(text, options) || async_player.output(
|
37
|
+
async_player.play_ssml(text, options) || async_player.output(output_formatter.ssml_for_text(text.to_s), options)
|
38
38
|
end
|
39
39
|
alias :speak! :say!
|
40
40
|
|
@@ -61,7 +61,7 @@ module Adhearsion
|
|
61
61
|
# @raises [PlaybackError] if (one of) the given argument(s) could not be played
|
62
62
|
#
|
63
63
|
def play(*arguments)
|
64
|
-
player.play_ssml
|
64
|
+
player.play_ssml output_formatter.ssml_for_collection(arguments)
|
65
65
|
true
|
66
66
|
end
|
67
67
|
|
@@ -89,7 +89,7 @@ module Adhearsion
|
|
89
89
|
# @returns [Punchblock::Component::Output]
|
90
90
|
#
|
91
91
|
def play!(*arguments)
|
92
|
-
async_player.play_ssml
|
92
|
+
async_player.play_ssml output_formatter.ssml_for_collection(arguments)
|
93
93
|
end
|
94
94
|
|
95
95
|
#
|
@@ -104,7 +104,7 @@ module Adhearsion
|
|
104
104
|
# @raises [PlaybackError] if (one of) the given argument(s) could not be played
|
105
105
|
#
|
106
106
|
def play_audio(file, options = nil)
|
107
|
-
player.play_ssml
|
107
|
+
player.play_ssml output_formatter.ssml_for_audio(file, options)
|
108
108
|
true
|
109
109
|
end
|
110
110
|
|
@@ -121,7 +121,7 @@ module Adhearsion
|
|
121
121
|
# @returns [Punchblock::Component::Output]
|
122
122
|
#
|
123
123
|
def play_audio!(file, options = nil)
|
124
|
-
async_player.play_ssml
|
124
|
+
async_player.play_ssml output_formatter.ssml_for_audio(file, options)
|
125
125
|
end
|
126
126
|
|
127
127
|
#
|
@@ -141,7 +141,7 @@ module Adhearsion
|
|
141
141
|
#
|
142
142
|
def play_time(time, options = {})
|
143
143
|
raise ArgumentError unless [Date, Time, DateTime].include?(time.class) && options.is_a?(Hash)
|
144
|
-
player.play_ssml
|
144
|
+
player.play_ssml output_formatter.ssml_for_time(time, options)
|
145
145
|
true
|
146
146
|
end
|
147
147
|
|
@@ -163,7 +163,7 @@ module Adhearsion
|
|
163
163
|
#
|
164
164
|
def play_time!(time, options = {})
|
165
165
|
raise ArgumentError unless [Date, Time, DateTime].include?(time.class) && options.is_a?(Hash)
|
166
|
-
async_player.play_ssml
|
166
|
+
async_player.play_ssml output_formatter.ssml_for_time(time, options)
|
167
167
|
end
|
168
168
|
|
169
169
|
#
|
@@ -177,7 +177,7 @@ module Adhearsion
|
|
177
177
|
#
|
178
178
|
def play_numeric(number)
|
179
179
|
raise ArgumentError unless number.kind_of?(Numeric) || number =~ /^\d+$/
|
180
|
-
player.play_ssml
|
180
|
+
player.play_ssml output_formatter.ssml_for_numeric(number)
|
181
181
|
true
|
182
182
|
end
|
183
183
|
|
@@ -193,7 +193,7 @@ module Adhearsion
|
|
193
193
|
#
|
194
194
|
def play_numeric!(number)
|
195
195
|
raise ArgumentError unless number.kind_of?(Numeric) || number =~ /^\d+$/
|
196
|
-
async_player.play_ssml
|
196
|
+
async_player.play_ssml output_formatter.ssml_for_numeric(number)
|
197
197
|
end
|
198
198
|
|
199
199
|
#
|
@@ -236,7 +236,7 @@ module Adhearsion
|
|
236
236
|
:value => grammar_accept(digits)
|
237
237
|
}
|
238
238
|
|
239
|
-
player.output
|
239
|
+
player.output output_formatter.ssml_for(argument) do |output_component|
|
240
240
|
stopper.register_event_handler Punchblock::Event::Complete do |event|
|
241
241
|
output_component.stop! unless output_component.complete?
|
242
242
|
end
|
@@ -245,9 +245,8 @@ module Adhearsion
|
|
245
245
|
|
246
246
|
stopper.stop! if stopper.executing?
|
247
247
|
reason = stopper.complete_event.reason
|
248
|
-
result = reason.
|
249
|
-
|
250
|
-
result
|
248
|
+
result = reason.respond_to?(:utterance) ? reason.utterance : nil
|
249
|
+
parse_dtmf result
|
251
250
|
end
|
252
251
|
|
253
252
|
# @private
|
@@ -259,6 +258,13 @@ module Adhearsion
|
|
259
258
|
def async_player
|
260
259
|
@async_player ||= AsyncPlayer.new(self)
|
261
260
|
end
|
261
|
+
|
262
|
+
#
|
263
|
+
# @return [Formatter] an output formatter for the preparation of SSML documents for submission to the engine
|
264
|
+
#
|
265
|
+
def output_formatter
|
266
|
+
Formatter.new
|
267
|
+
end
|
262
268
|
end # Output
|
263
269
|
end # CallController
|
264
270
|
end # Adhearsion
|