adhearsion 2.0.0.rc5 → 2.0.0

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.
@@ -4,38 +4,44 @@ module Adhearsion
4
4
  class CallController
5
5
  module Dial
6
6
  #
7
- # Dial a third party and join to this call
7
+ # Dial one or more third parties and join one to this call
8
8
  #
9
- # @param [String|Array<String>|Hash] number represents the extension or "number" that asterisk should dial.
10
- # Be careful to not just specify a number like 5001, 9095551001
11
- # You must specify a properly formatted string as Asterisk would expect to use in order to understand
12
- # whether the call should be dialed using SIP, IAX, or some other means.
13
- # You can also specify an array of destinations: each will be called with the same options simultaneously.
14
- # The first call answered is joined, the others are hung up.
15
- # A hash argument has the dial target as each key, and an hash of options as the value, in the form:
16
- # dial({'SIP/100' => {:timeout => 3000}, 'SIP/200' => {:timeout => 4000} })
17
- # The option hash for each target is merged into the global options, overriding them for the single dial.
18
- # Destinations are dialed simultaneously as with an array.
9
+ # @overload dial(to[String], options = {})
10
+ # @param [String] to The target URI to dial.
11
+ # You must specify a properly formatted string that your VoIP platform understands.
12
+ # eg. sip:foo@bar.com, tel:+14044754840, or SIP/foo/1234
13
+ # @param [Hash] options see below
19
14
  #
20
- # @param [Hash] options
15
+ # @overload dial(to[Array], options = {})
16
+ # @param [Array<String>] to Target URIs to dial.
17
+ # Each will be called with the same options simultaneously.
18
+ # The first call answered is joined, the others are hung up.
19
+ # @param [Hash] options see below
21
20
  #
22
- # +:from+ - the caller id to be used when the call is placed. It is advised you properly adhere to the
23
- # policy of VoIP termination providers with respect to caller id values.
21
+ # @overload dial(to[Hash], options = {})
22
+ # @param [Hash<String => Hash>] to Target URIs to dial, mapped to their per-target options overrides.
23
+ # Each will be called with the same options simultaneously.
24
+ # The first call answered is joined, the others are hung up.
25
+ # Each calls options are deep-merged with the global options hash.
26
+ # @param [Hash] options see below
24
27
  #
25
- # +:for+ - this option can be thought of best as a timeout. i.e. timeout after :for if no one answers the call
26
- # For example, dial(%w{SIP/jay-desk-650 SIP/jay-desk-601 SIP/jay-desk-601-2}, :for => 15.seconds, :from => callerid)
27
- # this call will timeout after 15 seconds if 1 of the 3 extensions being dialed do not pick prior to the 15 second time limit
28
+ # @option options [String] :from the caller id to be used when the call is placed. It is advised you properly adhere to the
29
+ # policy of VoIP termination providers with respect to caller id values.
30
+ #
31
+ # @option options [Numeric] :for this option can be thought of best as a timeout.
32
+ # i.e. timeout after :for if no one answers the call
28
33
  #
29
34
  # @example Make a call to the PSTN using my SIP provider for VoIP termination
30
35
  # dial "SIP/19095551001@my.sip.voip.terminator.us"
31
36
  #
32
- # @example Make 3 Simulataneous calls to the SIP extensions, try for 15 seconds and use the callerid
33
- # for this call specified by the variable my_callerid
37
+ # @example Make 3 simulataneous calls to the SIP extensions, try for 15 seconds and use the callerid for this call specified by the variable my_callerid
34
38
  # dial %w{SIP/jay-desk-650 SIP/jay-desk-601 SIP/jay-desk-601-2}, :for => 15.seconds, :from => my_callerid
35
39
  #
36
40
  # @example Make a call using the IAX provider to the PSTN
37
41
  # dial "IAX2/my.id@voipjet/19095551234", :from => "John Doe <9095551234>"
38
42
  #
43
+ # @return [DialStatus] the status of the dial operation
44
+ #
39
45
  def dial(to, options = {}, latch = nil)
40
46
  targets = to.respond_to?(:has_key?) ? to : Array(to)
41
47
 
@@ -111,29 +117,38 @@ module Adhearsion
111
117
  end
112
118
 
113
119
  class DialStatus
120
+ # The collection of calls created during the dial operation
114
121
  attr_accessor :calls
115
122
 
123
+ # @private
116
124
  def initialize
117
125
  @result = nil
118
126
  end
119
127
 
128
+ #
129
+ # The result of the dial operation.
130
+ #
131
+ # @return [Symbol] :no_answer, :answer, :timeout, :error
120
132
  def result
121
133
  @result || :no_answer
122
134
  end
123
135
 
136
+ # @private
124
137
  def answer!
125
138
  @result = :answer
126
139
  end
127
140
 
141
+ # @private
128
142
  def timeout!
129
143
  @result ||= :timeout
130
144
  end
131
145
 
146
+ # @private
132
147
  def error!
133
148
  @result ||= :error
134
149
  end
135
150
  end
136
151
 
137
- end#module Dial
152
+ end
138
153
  end
139
154
  end
@@ -10,6 +10,7 @@ module Adhearsion
10
10
  end
11
11
  end
12
12
 
13
+ #
13
14
  # Prompts for input via DTMF, handling playback of prompts,
14
15
  # timeouts, digit limits and terminator digits.
15
16
  #
@@ -23,7 +24,7 @@ module Adhearsion
23
24
  # :timeout, :terminator and :limit options may then be specified.
24
25
  # A block may be passed which is invoked on each digit being collected. If it returns true, the collection is terminated.
25
26
  #
26
- # @param [Object] A list of outputs to play, as accepted by #play
27
+ # @param [Object, Array<Object>] args A list of outputs to play, as accepted by #play
27
28
  # @param [Hash] options Options to use for the menu
28
29
  # @option options [Boolean] :interruptible If the prompt should be interruptible or not. Defaults to true
29
30
  # @option options [Integer] :limit Digit limit (causes collection to cease after a specified number of digits have been collected)
@@ -32,8 +33,8 @@ module Adhearsion
32
33
  #
33
34
  # @return [Result] a result object from which the #response and #status may be established
34
35
  #
35
- # @see play
36
- # @see pass
36
+ # @see Output#play
37
+ # @see CallController#pass
37
38
  #
38
39
  def ask(*args, &block)
39
40
  options = args.last.kind_of?(Hash) ? args.pop : {}
@@ -51,8 +52,8 @@ module Adhearsion
51
52
  if result_of_menu.is_a?(MenuDSL::Menu::MenuGetAnotherDigit)
52
53
  next_digit = play_sound_files_for_menu menu_instance, sound_files
53
54
  menu_instance << next_digit if next_digit
54
- end # case
55
- end # while
55
+ end
56
+ end
56
57
 
57
58
  Result.new.tap do |result|
58
59
  result.response = menu_instance.result
@@ -103,7 +104,7 @@ module Adhearsion
103
104
  # Execution of the current context resumes after #ask finishes. If you wish to jump to an entirely different controller, use #pass.
104
105
  # Menu will return :failed if failure was reached, or :done if a match was executed.
105
106
  #
106
- # @param [Object] A list of outputs to play, as accepted by #play
107
+ # @param [Object] args A list of outputs to play, as accepted by #play
107
108
  # @param [Hash] options Options to use for the menu
108
109
  # @option options [Integer] :tries Number of tries allowed before failure
109
110
  # @option options [Integer] :timeout Timeout in seconds before the first and between each input digit
@@ -111,8 +112,8 @@ module Adhearsion
111
112
  #
112
113
  # @return [Result] a result object from which the #response and #status may be established
113
114
  #
114
- # @see play
115
- # @see pass
115
+ # @see Output#play
116
+ # @see CallController#pass
116
117
  #
117
118
  def menu(*args, &block)
118
119
  options = args.last.kind_of?(Hash) ? args.pop : {}
@@ -158,8 +159,8 @@ module Adhearsion
158
159
  logger.debug "Menu received valid input (#{result_of_menu.new_extension}). Calling the matching hook."
159
160
  jump_to result_of_menu.match_object, :extension => result_of_menu.new_extension
160
161
  throw :finish
161
- end # case
162
- end # while
162
+ end
163
+ end
163
164
  end
164
165
 
165
166
  Result.new.tap do |result|
@@ -169,7 +170,8 @@ module Adhearsion
169
170
  end
170
171
  end
171
172
 
172
- def play_sound_files_for_menu(menu_instance, sound_files) # :nodoc:
173
+ # @private
174
+ def play_sound_files_for_menu(menu_instance, sound_files)
173
175
  digit = nil
174
176
  if sound_files.any? && menu_instance.digit_buffer_empty?
175
177
  if menu_instance.interruptible
@@ -185,9 +187,11 @@ module Adhearsion
185
187
  # Waits for a single digit and returns it, or returns nil if nothing was pressed
186
188
  #
187
189
  # @param [Integer] the timeout to wait before returning, in seconds. nil or -1 mean no timeout.
188
- # @return [String|nil] the pressed key, or nil if timeout was reached.
190
+ # @return [String, nil] the pressed key, or nil if timeout was reached.
191
+ #
192
+ # @private
189
193
  #
190
- def wait_for_digit(timeout = 1) # :nodoc:
194
+ def wait_for_digit(timeout = 1)
191
195
  timeout = nil if timeout == -1
192
196
  timeout *= 1_000 if timeout
193
197
  input_component = execute_component_and_await_completion ::Punchblock::Component::Input.new :mode => :dtmf,
@@ -202,7 +206,8 @@ module Adhearsion
202
206
  parse_single_dtmf result
203
207
  end
204
208
 
205
- def jump_to(match_object, overrides = nil) # :nodoc:
209
+ # @private
210
+ def jump_to(match_object, overrides = nil)
206
211
  if match_object.block
207
212
  instance_exec overrides[:extension], &match_object.block
208
213
  else
@@ -210,6 +215,6 @@ module Adhearsion
210
215
  end
211
216
  end
212
217
 
213
- end # module
218
+ end
214
219
  end
215
220
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Adhearsion
4
4
  class CallController
5
+ # @private
5
6
  module MenuDSL
6
7
  extend ActiveSupport::Autoload
7
8
 
@@ -5,8 +5,14 @@ module Adhearsion
5
5
  module Output
6
6
  PlaybackError = Class.new Adhearsion::Error # Represents failure to play audio, such as when the sound file cannot be found
7
7
 
8
+ #
9
+ # Speak output using text-to-speech (TTS)
10
+ #
11
+ # @param [String, #to_s] text The text to be rendered
12
+ # @param [Hash] options A set of options for output
13
+ #
8
14
  def say(text, options = {})
9
- play_ssml(text, options) || output(:text, text.to_s, options)
15
+ play_ssml(text, options) || output(ssml_for_text(text.to_s), options)
10
16
  end
11
17
  alias :speak :say
12
18
 
@@ -54,6 +60,8 @@ module Adhearsion
54
60
  # Plays the specified input arguments, raising an exception if any can't be played.
55
61
  # @see play
56
62
  #
63
+ # @private
64
+ #
57
65
  def play!(*arguments)
58
66
  play(*arguments) or raise PlaybackError, "One of the passed outputs is invalid"
59
67
  end
@@ -62,25 +70,22 @@ module Adhearsion
62
70
  # Plays the given Date, Time, or Integer (seconds since epoch)
63
71
  # using the given timezone and format.
64
72
  #
65
- # @param [Date|Time|DateTime] Time to be said.
66
- # @param [Hash] Additional options to specify how exactly to say time specified.
67
- #
68
- # +:format+ - This format is used only to disambiguate times that could be interpreted in different ways.
73
+ # @param [Date, Time, DateTime] time Time to be said.
74
+ # @param [Hash] options Additional options to specify how exactly to say time specified.
75
+ # @option options [String] :format This format is used only to disambiguate times that could be interpreted in different ways.
69
76
  # For example, 01/06/2011 could mean either the 1st of June or the 6th of January.
70
77
  # Please refer to the SSML specification.
71
78
  # @see http://www.w3.org/TR/ssml-sayas/#S3.1
72
- # +:strftime+ - This format is what defines the string that is sent to the Speech Synthesis Engine.
79
+ # @option options [String] :strftime This format is what defines the string that is sent to the Speech Synthesis Engine.
73
80
  # It uses Time::strftime symbols.
74
81
  #
75
82
  # @return [Boolean] true if successful, false if the given argument could not be played.
76
83
  #
77
- def play_time(*args)
78
- argument, options = args.flatten
79
- return false unless [Date, Time, DateTime].include? argument.class
84
+ def play_time(time, options = {})
85
+ return false unless [Date, Time, DateTime].include? time.class
80
86
 
81
- options ||= {}
82
87
  return false unless options.is_a? Hash
83
- play_ssml ssml_for_time(argument, options)
88
+ play_ssml ssml_for_time(time, options)
84
89
  end
85
90
 
86
91
  #
@@ -88,14 +93,13 @@ module Adhearsion
88
93
  # When playing numbers, Adhearsion assumes you're saying the number, not the digits. For example, play("100")
89
94
  # is pronounced as "one hundred" instead of "one zero zero".
90
95
  #
91
- # @param [Numeric|String] Numeric or String containing a valid Numeric, like "321".
96
+ # @param [Numeric, String] Numeric or String containing a valid Numeric, like "321".
92
97
  #
93
98
  # @return [Boolean] true if successful, false if the given argument could not be played.
94
99
  #
95
- def play_numeric(*args)
96
- argument, options = args.flatten
97
- if argument.kind_of?(Numeric) || argument =~ /^\d+$/
98
- play_ssml ssml_for_numeric(argument, options)
100
+ def play_numeric(number, options = nil)
101
+ if number.kind_of?(Numeric) || number =~ /^\d+$/
102
+ play_ssml ssml_for_numeric(number, options)
99
103
  end
100
104
  end
101
105
 
@@ -104,30 +108,26 @@ module Adhearsion
104
108
  # SSML supports http:// paths and full disk paths.
105
109
  # The Punchblock backend will have to handle cases like Asterisk where there is a fixed sounds directory.
106
110
  #
107
- # @param [String] http:// URL or full disk path to the sound file
108
- # @param [Hash] Additional options to specify how exactly to say time specified.
109
- # +:fallback+ - The text to play if the file is not available
111
+ # @param [String] file http:// URL or full disk path to the sound file
112
+ # @param [Hash] options Additional options to specify how exactly to say time specified.
113
+ # @option options [String] :fallback The text to play if the file is not available
110
114
  #
111
115
  # @return [Boolean] true on correct play of the file, false on file missing or not playable
112
116
  #
113
- def play_audio(*args)
114
- argument, options = args.flatten
115
- play_ssml ssml_for_audio(argument, options)
117
+ def play_audio(file, options = nil)
118
+ play_ssml ssml_for_audio(file, options)
116
119
  end
117
120
 
118
- def play_ssml(ssml, options = {}) # :nodoc:
121
+ # @private
122
+ def play_ssml(ssml, options = {})
119
123
  if [RubySpeech::SSML::Speak, Nokogiri::XML::Document].include? ssml.class
120
- output :ssml, ssml.to_s, options
124
+ output ssml.to_s, options
121
125
  end
122
126
  end
123
127
 
124
- def output(type, content, options = {}) # :nodoc:
125
- options.merge! type => content
126
- execute_component_and_await_completion ::Punchblock::Component::Output.new(options)
127
- end
128
-
129
- def output!(type, content, options = {}) # :nodoc:
130
- options.merge! type => content
128
+ # @private
129
+ def output(content, options = {})
130
+ options.merge! :ssml => content
131
131
  execute_component_and_await_completion ::Punchblock::Component::Output.new(options)
132
132
  end
133
133
 
@@ -135,6 +135,8 @@ module Adhearsion
135
135
  # Same as interruptible_play, but throws an error if unable to play the output
136
136
  # @see interruptible_play
137
137
  #
138
+ # @private
139
+ #
138
140
  def interruptible_play!(*outputs)
139
141
  result = nil
140
142
  outputs.each do |output|
@@ -155,10 +157,10 @@ module Adhearsion
155
157
  # input = interruptible_play ssml
156
158
  # play input unless input.nil?
157
159
  #
158
- # @param [String|Numeric|Date|Time|RubySpeech::SSML::Speak|Array|Hash] The argument to play to the user, or an array of arguments.
160
+ # @param [String, Numeric, Date, Time, RubySpeech::SSML::Speak, Array, Hash] The argument to play to the user, or an array of arguments.
159
161
  # @param [Hash] Additional options.
160
162
  #
161
- # @return [String|Nil] The single DTMF character entered by the user, or nil if nothing was entered
163
+ # @return [String, nil] The single DTMF character entered by the user, or nil if nothing was entered
162
164
  #
163
165
  def interruptible_play(*outputs)
164
166
  result = nil
@@ -175,7 +177,8 @@ module Adhearsion
175
177
  result
176
178
  end
177
179
 
178
- def detect_type(output) # :nodoc:
180
+ # @private
181
+ def detect_type(output)
179
182
  result = nil
180
183
  result = :time if [Date, Time, DateTime].include? output.class
181
184
  result = :numeric if output.kind_of?(Numeric) || output =~ /^\d+$/
@@ -183,7 +186,8 @@ module Adhearsion
183
186
  result ||= :text
184
187
  end
185
188
 
186
- def play_ssml_for(*args) # :nodoc:
189
+ # @private
190
+ def play_ssml_for(*args)
187
191
  play_ssml ssml_for(args)
188
192
  end
189
193
 
@@ -191,10 +195,12 @@ module Adhearsion
191
195
  # Generates SSML for the argument and options passed, using automatic detection
192
196
  # Directly returns the argument if it is already an SSML document
193
197
  #
194
- # @param [String|Hash|RubySpeech::SSML::Speak] the argument with options as accepted by the play_ methods, or an SSML document
198
+ # @param [String, Hash, RubySpeech::SSML::Speak] the argument with options as accepted by the play_ methods, or an SSML document
195
199
  # @return [RubySpeech::SSML::Speak] an SSML document
196
200
  #
197
- def ssml_for(*args) # :nodoc:
201
+ # @private
202
+ #
203
+ def ssml_for(*args)
198
204
  return args[0] if args.size == 1 && args[0].is_a?(RubySpeech::SSML::Speak)
199
205
  argument, options = args.flatten
200
206
  options ||= {}
@@ -202,11 +208,13 @@ module Adhearsion
202
208
  send "ssml_for_#{type}", argument, options
203
209
  end
204
210
 
205
- def ssml_for_text(argument, options = {}) # :nodoc:
211
+ # @private
212
+ def ssml_for_text(argument, options = {})
206
213
  RubySpeech::SSML.draw { argument }
207
214
  end
208
215
 
209
- def ssml_for_time(argument, options = {}) # :nodoc:
216
+ # @private
217
+ def ssml_for_time(argument, options = {})
210
218
  interpretation = case argument
211
219
  when Date then 'date'
212
220
  when Time then 'time'
@@ -222,13 +230,15 @@ module Adhearsion
222
230
  end
223
231
  end
224
232
 
225
- def ssml_for_numeric(argument, options = {}) # :nodoc:
233
+ # @private
234
+ def ssml_for_numeric(argument, options = {})
226
235
  RubySpeech::SSML.draw do
227
236
  say_as(:interpret_as => 'cardinal') { argument.to_s }
228
237
  end
229
238
  end
230
239
 
231
- def ssml_for_audio(argument, options = {}) # :nodoc:
240
+ # @private
241
+ def ssml_for_audio(argument, options = {})
232
242
  fallback = (options || {}).delete :fallback
233
243
  RubySpeech::SSML.draw do
234
244
  audio(:src => argument) { fallback }
@@ -241,7 +251,8 @@ module Adhearsion
241
251
  #
242
252
  # @param [Object] String or Hash specifying output and options
243
253
  # @param [String] String with the digits that are allowed to interrupt output
244
- # @return [String|nil] The pressed digit, or nil if nothing was pressed
254
+ #
255
+ # @return [String, nil] The pressed digit, or nil if nothing was pressed
245
256
  #
246
257
  def stream_file(argument, digits = '0123456789#*')
247
258
  result = nil
@@ -9,7 +9,7 @@ module Adhearsion
9
9
  # Start a recording
10
10
  #
11
11
  # @param [Hash] options
12
- # @param [Block] &block to process result of the record method
12
+ # @param [Block] block to process result of the record method
13
13
  # @option options [Boolean, Optional] :async Execute asynchronously. Defaults to false
14
14
  # @option options [Boolean, Optional] :start_beep Indicates whether subsequent record will be preceded with a beep. Default is true.
15
15
  # @option options [Boolean, Optional] :start_paused Whether subsequent record will start in PAUSE mode. Default is false.
@@ -19,8 +19,8 @@ module Adhearsion
19
19
  # @option options [String, Optional] :initial_timeout Controls how long (milliseconds) the recognizer should wait after the end of the prompt for the caller to speak before sending a Recorder event.
20
20
  # @option options [String, Optional] :final_timeout Controls the length (milliseconds) of a period of silence after callers have spoken to conclude they finished.
21
21
  #
22
- # @return recording object
23
-
22
+ # @return Punchblock::Component::Record::Recording
23
+ #
24
24
  def record(options = {})
25
25
  async = options.delete :async
26
26