adhearsion 2.0.0.rc5 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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