adhearsion-asterisk 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +4 -0
- data/Rakefile +1 -6
- data/adhearsion-asterisk.gemspec +1 -1
- data/lib/adhearsion/asterisk.rb +2 -0
- data/lib/adhearsion/asterisk/call_controller_methods.rb +380 -0
- data/lib/adhearsion/asterisk/core_ext/adhearsion/call_controller.rb +89 -0
- data/lib/adhearsion/asterisk/plugin.rb +4 -456
- data/lib/adhearsion/asterisk/version.rb +1 -1
- data/spec/adhearsion/asterisk/call_controller_methods_spec.rb +617 -0
- data/spec/adhearsion/asterisk/plugin_spec.rb +10 -609
- metadata +35 -31
@@ -1,462 +1,10 @@
|
|
1
|
+
require 'adhearsion/asterisk/call_controller_methods'
|
2
|
+
|
1
3
|
module Adhearsion
|
2
4
|
module Asterisk
|
3
|
-
PLAYBACK_SUCCESS = 'SUCCESS' unless defined? PLAYBACK_SUCCESS
|
4
|
-
|
5
|
-
|
6
5
|
class Plugin < Adhearsion::Plugin
|
7
|
-
|
8
|
-
|
9
|
-
variable "TRANSFER_CONTEXT" => options[:context] if options && options.has_key?(:context)
|
10
|
-
extend_dynamic_features_with "atxfer"
|
11
|
-
end,
|
12
|
-
:blind_transfer => lambda do |options|
|
13
|
-
variable "TRANSFER_CONTEXT" => options[:context] if options && options.has_key?(:context)
|
14
|
-
extend_dynamic_features_with 'blindxfer'
|
15
|
-
end
|
16
|
-
} unless defined? DYNAMIC_FEATURE_EXTENSIONS
|
17
|
-
|
18
|
-
dialplan :agi do |name, *params|
|
19
|
-
component = Punchblock::Component::Asterisk::AGI::Command.new :name => name, :params => params
|
20
|
-
execute_component_and_await_completion component
|
21
|
-
complete_reason = component.complete_event.reason
|
22
|
-
[:code, :result, :data].map { |p| complete_reason.send p }
|
23
|
-
end
|
24
|
-
|
25
|
-
#
|
26
|
-
# This asterisk dialplan command allows you to instruct Asterisk to start applications
|
27
|
-
# which are typically run from extensions.conf and do not have AGI command equivalents.
|
28
|
-
#
|
29
|
-
# For example, if there are specific asterisk modules you have loaded that will not be
|
30
|
-
# available through the standard commands provided through FAGI - then you can use EXEC.
|
31
|
-
#
|
32
|
-
# @example Using execute in this way will add a header to an existing SIP call.
|
33
|
-
# execute 'SIPAddHeader', "Call-Info: answer-after=0"
|
34
|
-
#
|
35
|
-
# @see http://www.voip-info.org/wiki/view/Asterisk+-+documentation+of+application+commands Asterisk Dialplan Commands
|
36
|
-
#
|
37
|
-
dialplan :execute do |name, *params|
|
38
|
-
agi "EXEC #{name}", *params
|
39
|
-
end
|
40
|
-
|
41
|
-
#
|
42
|
-
# Sends a message to the console via the verbose message system.
|
43
|
-
#
|
44
|
-
# @param [String] message
|
45
|
-
# @param [Integer] level
|
46
|
-
#
|
47
|
-
# @return the result of the command
|
48
|
-
#
|
49
|
-
# @example Use this command to inform someone watching the Asterisk console
|
50
|
-
# of actions happening within Adhearsion.
|
51
|
-
# verbose 'Processing call with Adhearsion' 3
|
52
|
-
#
|
53
|
-
# @see http://www.voip-info.org/wiki/view/verbose
|
54
|
-
#
|
55
|
-
dialplan :verbose do |message, level = nil|
|
56
|
-
agi 'VERBOSE', message, level
|
57
|
-
end
|
58
|
-
|
59
|
-
# A high-level way of enabling features you create/uncomment from features.conf.
|
60
|
-
#
|
61
|
-
# Certain Symbol features you enable (as defined in DYNAMIC_FEATURE_EXTENSIONS) have optional
|
62
|
-
# arguments that you can also specify here. The usage examples show how to do this.
|
63
|
-
#
|
64
|
-
# Usage examples:
|
65
|
-
#
|
66
|
-
# enable_feature :attended_transfer # Enables "atxfer"
|
67
|
-
#
|
68
|
-
# enable_feature :attended_transfer, :context => "my_dial" # Enables "atxfer" and then
|
69
|
-
# # sets "TRANSFER_CONTEXT" to :context's value
|
70
|
-
#
|
71
|
-
# enable_feature :blind_transfer, :context => 'my_dial' # Enables 'blindxfer' and sets TRANSFER_CONTEXT
|
72
|
-
#
|
73
|
-
# enable_feature "foobar" # Enables "foobar"
|
74
|
-
#
|
75
|
-
# enable_feature("dup"); enable_feature("dup") # Enables "dup" only once.
|
76
|
-
#
|
77
|
-
# dialplan :voicemail do |*args|
|
78
|
-
# options_hash = args.last.kind_of?(Hash) ? args.pop : {}
|
79
|
-
# mailbox_number = args.shift
|
80
|
-
# greeting_option = options_hash.delete :greeting
|
81
|
-
#
|
82
|
-
dialplan :enable_feature do |*args|
|
83
|
-
feature_name, optional_options = args.flatten
|
84
|
-
|
85
|
-
if DYNAMIC_FEATURE_EXTENSIONS.has_key? feature_name
|
86
|
-
instance_exec(optional_options, &DYNAMIC_FEATURE_EXTENSIONS[feature_name])
|
87
|
-
else
|
88
|
-
unless optional_options.nil? or optional_options.empty?
|
89
|
-
raise ArgumentError, "You cannot supply optional options when the feature name is " +
|
90
|
-
"not internally recognized!"
|
91
|
-
end
|
92
|
-
extend_dynamic_features_with feature_name
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
# Disables a feature name specified in features.conf. If you're disabling it, it was probably
|
97
|
-
# set by enable_feature().
|
98
|
-
#
|
99
|
-
# @param [String] feature_name
|
100
|
-
dialplan :disable_feature do |feature_name|
|
101
|
-
enabled_features_variable = variable 'DYNAMIC_FEATURES'
|
102
|
-
enabled_features = enabled_features_variable.split('#')
|
103
|
-
if enabled_features.include? feature_name
|
104
|
-
enabled_features.delete feature_name
|
105
|
-
variable 'DYNAMIC_FEATURES' => enabled_features.join('#')
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
# helper method that should probably should private...
|
110
|
-
dialplan :extend_dynamic_features_with do |feature_name|
|
111
|
-
current_variable = variable("DYNAMIC_FEATURES") || ''
|
112
|
-
enabled_features = current_variable.split '#'
|
113
|
-
unless enabled_features.include? feature_name
|
114
|
-
enabled_features << feature_name
|
115
|
-
variable "DYNAMIC_FEATURES" => enabled_features.join('#')
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
#
|
120
|
-
# Issue this command to access a channel variable that exists in the asterisk dialplan (i.e. extensions.conf)
|
121
|
-
# Use get_variable to pass information from other modules or high level configurations from the asterisk dialplan
|
122
|
-
# to the adhearsion dialplan.
|
123
|
-
#
|
124
|
-
# @param [String] variable_name
|
125
|
-
#
|
126
|
-
# @see: http://www.voip-info.org/wiki/view/get+variable Asterisk Get Variable
|
127
|
-
#
|
128
|
-
dialplan :get_variable do |variable_name|
|
129
|
-
code, result, data = agi "GET VARIABLE", variable_name
|
130
|
-
data
|
131
|
-
end
|
132
|
-
|
133
|
-
#
|
134
|
-
# Pass information back to the asterisk dial plan.
|
135
|
-
#
|
136
|
-
# Keep in mind that the variables are not global variables. These variables only exist for the channel
|
137
|
-
# related to the call that is being serviced by the particular instance of your adhearsion application.
|
138
|
-
# You will not be able to pass information back to the asterisk dialplan for other instances of your adhearsion
|
139
|
-
# application to share. Once the channel is "hungup" then the variables are cleared and their information is gone.
|
140
|
-
#
|
141
|
-
# @param [String] variable_name
|
142
|
-
# @param [String] value
|
143
|
-
#
|
144
|
-
# @see http://www.voip-info.org/wiki/view/set+variable Asterisk Set Variable
|
145
|
-
#
|
146
|
-
dialplan :set_variable do |variable_name, value|
|
147
|
-
agi "SET VARIABLE", variable_name, value
|
148
|
-
end
|
149
|
-
|
150
|
-
#
|
151
|
-
# Issue the command to add a custom SIP header to the current call channel
|
152
|
-
# example use: sip_add_header("x-ahn-test", "rubyrox")
|
153
|
-
#
|
154
|
-
# @param[String] the name of the SIP header
|
155
|
-
# @param[String] the value of the SIP header
|
156
|
-
#
|
157
|
-
# @return [String] the Asterisk response
|
158
|
-
#
|
159
|
-
# @see http://www.voip-info.org/wiki/index.php?page=Asterisk+cmd+SIPAddHeader Asterisk SIPAddHeader
|
160
|
-
#
|
161
|
-
dialplan :sip_add_header do |header, value|
|
162
|
-
execute "SIPAddHeader", "#{header}: #{value}"
|
163
|
-
end
|
164
|
-
|
165
|
-
#
|
166
|
-
# Issue the command to fetch a SIP header from the current call channel
|
167
|
-
# example use: sip_get_header("x-ahn-test")
|
168
|
-
#
|
169
|
-
# @param[String] the name of the SIP header to get
|
170
|
-
#
|
171
|
-
# @return [String] the Asterisk response
|
172
|
-
#
|
173
|
-
# @see http://www.voip-info.org/wiki/index.php?page=Asterisk+cmd+SIPGetHeader Asterisk SIPGetHeader
|
174
|
-
#
|
175
|
-
dialplan :sip_get_header do |header|
|
176
|
-
get_variable "SIP_HEADER(#{header})"
|
177
|
-
end
|
178
|
-
|
179
|
-
#
|
180
|
-
# Allows you to either set or get a channel variable from Asterisk.
|
181
|
-
# The method takes a hash key/value pair if you would like to set a variable
|
182
|
-
# Or a single string with the variable to get from Asterisk
|
183
|
-
#
|
184
|
-
dialplan :variable do |*args|
|
185
|
-
if args.last.kind_of? Hash
|
186
|
-
assignments = args.pop
|
187
|
-
raise ArgumentError, "Can't mix variable setting and fetching!" if args.any?
|
188
|
-
assignments.each_pair do |key, value|
|
189
|
-
set_variable key, value
|
190
|
-
end
|
191
|
-
else
|
192
|
-
if args.size == 1
|
193
|
-
get_variable args.first
|
194
|
-
else
|
195
|
-
args.map { |var| get_variable var }
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
#
|
201
|
-
# Used to join a particular conference with the MeetMe application. To use MeetMe, be sure you
|
202
|
-
# have a proper timing device configured on your Asterisk box. MeetMe is Asterisk's built-in
|
203
|
-
# conferencing program.
|
204
|
-
#
|
205
|
-
# @param [String] conference_id
|
206
|
-
# @param [Hash] options
|
207
|
-
#
|
208
|
-
# @see http://www.voip-info.org/wiki-Asterisk+cmd+MeetMe Asterisk Meetme Application Information
|
209
|
-
#
|
210
|
-
dialplan :meetme do |conference_id, options = {}|
|
211
|
-
conference_id = conference_id.to_s.scan(/\w/).join
|
212
|
-
command_flags = options[:options].to_s # This is a passthrough string straight to Asterisk
|
213
|
-
pin = options[:pin]
|
214
|
-
raise ArgumentError, "A conference PIN number must be numerical!" if pin && pin.to_s !~ /^\d+$/
|
215
|
-
|
216
|
-
# To disable dynamic conference creation set :use_static_conf => true
|
217
|
-
use_static_conf = options.has_key?(:use_static_conf) ? options[:use_static_conf] : false
|
218
|
-
|
219
|
-
# The 'd' option of MeetMe creates conferences dynamically.
|
220
|
-
command_flags += 'd' unless command_flags.include?('d') || use_static_conf
|
221
|
-
|
222
|
-
execute "MeetMe", conference_id, command_flags, options[:pin]
|
223
|
-
end
|
224
|
-
|
225
|
-
#
|
226
|
-
# Send a caller to a voicemail box to leave a message.
|
227
|
-
#
|
228
|
-
# The method takes the mailbox_number of the user to leave a message for and a
|
229
|
-
# greeting_option that will determine which message gets played to the caller.
|
230
|
-
#
|
231
|
-
# @see http://www.voip-info.org/tiki-index.php?page=Asterisk+cmd+VoiceMail Asterisk Voicemail
|
232
|
-
#
|
233
|
-
dialplan :voicemail do |*args|
|
234
|
-
options_hash = args.last.kind_of?(Hash) ? args.pop : {}
|
235
|
-
mailbox_number = args.shift
|
236
|
-
greeting_option = options_hash.delete :greeting
|
237
|
-
skip_option = options_hash.delete :skip
|
238
|
-
raise ArgumentError, 'You supplied too many arguments!' if mailbox_number && options_hash.any?
|
239
|
-
|
240
|
-
greeting_option = case greeting_option
|
241
|
-
when :busy then 'b'
|
242
|
-
when :unavailable then 'u'
|
243
|
-
when nil then nil
|
244
|
-
else raise ArgumentError, "Unrecognized greeting #{greeting_option}"
|
245
|
-
end
|
246
|
-
skip_option &&= 's'
|
247
|
-
options = "#{greeting_option}#{skip_option}"
|
248
|
-
|
249
|
-
raise ArgumentError, "Mailbox cannot be blank!" if !mailbox_number.nil? && mailbox_number.blank?
|
250
|
-
number_with_context = if mailbox_number then mailbox_number else
|
251
|
-
raise ArgumentError, "You must supply ONE context name!" unless options_hash.size == 1
|
252
|
-
context_name, mailboxes = options_hash.to_a.first
|
253
|
-
Array(mailboxes).map do |mailbox|
|
254
|
-
raise ArgumentError, "Mailbox numbers must be numerical!" unless mailbox.to_s =~ /^\d+$/
|
255
|
-
[mailbox, context_name].join '@'
|
256
|
-
end.join '&'
|
257
|
-
end
|
258
|
-
|
259
|
-
execute 'voicemail', number_with_context, options
|
260
|
-
case variable('VMSTATUS')
|
261
|
-
when 'SUCCESS' then true
|
262
|
-
when 'USEREXIT' then false
|
263
|
-
else nil
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
#
|
268
|
-
# The voicemail_main method puts a caller into the voicemail system to fetch their voicemail
|
269
|
-
# or set options for their voicemail box.
|
270
|
-
#
|
271
|
-
# @param [Hash] options
|
272
|
-
#
|
273
|
-
# @see http://www.voip-info.org/wiki-Asterisk+cmd+VoiceMailMain Asterisk VoiceMailMain Command
|
274
|
-
#
|
275
|
-
dialplan :voicemail_main do |options = {}|
|
276
|
-
mailbox, context, folder = options.values_at :mailbox, :context, :folder
|
277
|
-
authenticate = options.has_key?(:authenticate) ? options[:authenticate] : true
|
278
|
-
|
279
|
-
folder = if folder
|
280
|
-
if folder.to_s =~ /^[\w_]+$/
|
281
|
-
"a(#{folder})"
|
282
|
-
else
|
283
|
-
raise ArgumentError, "Voicemail folder must be alphanumerical/underscore characters only!"
|
284
|
-
end
|
285
|
-
elsif folder == ''
|
286
|
-
raise ArgumentError, "Folder name cannot be an empty String!"
|
287
|
-
else
|
288
|
-
nil
|
289
|
-
end
|
290
|
-
|
291
|
-
real_mailbox = ""
|
292
|
-
real_mailbox << "#{mailbox}" unless mailbox.blank?
|
293
|
-
real_mailbox << "@#{context}" unless context.blank?
|
294
|
-
|
295
|
-
real_options = ""
|
296
|
-
real_options << "s" if !authenticate
|
297
|
-
real_options << folder unless folder.blank?
|
298
|
-
|
299
|
-
command_args = [real_mailbox]
|
300
|
-
command_args << real_options unless real_options.blank?
|
301
|
-
command_args.clear if command_args == [""]
|
302
|
-
|
303
|
-
execute 'VoiceMailMain', *command_args
|
304
|
-
end
|
305
|
-
|
306
|
-
#
|
307
|
-
# Place a call in a queue to be answered by a registered agent. You must then call #join!
|
308
|
-
#
|
309
|
-
# @param [String] queue_name the queue name to place the caller in
|
310
|
-
# @return [Adhearsion::Asterisk::QueueProxy] a queue proxy object
|
311
|
-
#
|
312
|
-
# @see http://www.voip-info.org/wiki-Asterisk+cmd+Queue Full information on the Asterisk Queue
|
313
|
-
# @see Adhearsion::Asterisk":QueueProxy#join! for further details
|
314
|
-
#
|
315
|
-
dialplan :queue do |queue_name|
|
316
|
-
queue_name = queue_name.to_s
|
317
|
-
|
318
|
-
@queue_proxy_hash_lock ||= Mutex.new
|
319
|
-
@queue_proxy_hash_lock.synchronize do
|
320
|
-
@queue_proxy_hash ||= {}
|
321
|
-
if @queue_proxy_hash.has_key? queue_name
|
322
|
-
return @queue_proxy_hash[queue_name]
|
323
|
-
else
|
324
|
-
proxy = @queue_proxy_hash[queue_name] = QueueProxy.new(queue_name, self)
|
325
|
-
return proxy
|
326
|
-
end
|
327
|
-
end
|
328
|
-
end
|
329
|
-
|
330
|
-
# Plays the specified sound file names. This method will handle Time/DateTime objects (e.g. Time.now),
|
331
|
-
# Fixnums (e.g. 1000), Strings which are valid Fixnums (e.g "123"), and direct sound files. When playing
|
332
|
-
# numbers, Adhearsion assumes you're saying the number, not the digits. For example, play("100")
|
333
|
-
# is pronounced as "one hundred" instead of "one zero zero". To specify how the Date/Time objects are said
|
334
|
-
# pass in as an array with the first parameter as the Date/Time/DateTime object along with a hash with the
|
335
|
-
# additional options. See play_time for more information.
|
336
|
-
#
|
337
|
-
# Note: it is not necessary to supply a sound file extension; Asterisk will try to find a sound
|
338
|
-
# file encoded using the current channel's codec, if one exists. If not, it will transcode from
|
339
|
-
# the default codec (GSM). Asterisk stores its sound files in /var/lib/asterisk/sounds.
|
340
|
-
#
|
341
|
-
# @example Play file hello-world.???
|
342
|
-
# play 'hello-world'
|
343
|
-
# @example Speak current time
|
344
|
-
# play Time.now
|
345
|
-
# @example Speak today's date
|
346
|
-
# play Date.today
|
347
|
-
# @example Speak today's date in a specific format
|
348
|
-
# play [Date.today, {:format => 'BdY'}]
|
349
|
-
# @example Play sound file, speak number, play two more sound files
|
350
|
-
# play %w"a-connect-charge-of 22 cents-per-minute will-apply"
|
351
|
-
# @example Play two sound files
|
352
|
-
# play "you-sound-cute", "what-are-you-wearing"
|
353
|
-
#
|
354
|
-
# @return [Boolean] true is returned if everything was successful. Otherwise, false indicates that
|
355
|
-
# some sound file(s) could not be played.
|
356
|
-
dialplan :play do |*arguments|
|
357
|
-
begin
|
358
|
-
play! arguments
|
359
|
-
rescue Adhearsion::PlaybackError => e
|
360
|
-
return false
|
361
|
-
end
|
362
|
-
true
|
363
|
-
end
|
364
|
-
|
365
|
-
# Same as {#play}, but immediately raises an exception if a sound file cannot be played.
|
366
|
-
#
|
367
|
-
# @return [true]
|
368
|
-
# @raise [Adhearsion::VoIP::PlaybackError] If a sound file cannot be played
|
369
|
-
dialplan :play! do |*arguments|
|
370
|
-
result = true
|
371
|
-
unless play_time(arguments)
|
372
|
-
arguments.flatten.each do |argument|
|
373
|
-
result &= play_numeric(argument) || play_soundfile(argument)
|
374
|
-
end
|
375
|
-
end
|
376
|
-
raise Adhearsion::PlaybackError if !result
|
377
|
-
end
|
378
|
-
|
379
|
-
# Plays the given Date, Time, or Integer (seconds since epoch)
|
380
|
-
# using the given timezone and format.
|
381
|
-
#
|
382
|
-
# @param [Date|Time|DateTime] Time to be said.
|
383
|
-
# @param [Hash] Additional options to specify how exactly to say time specified.
|
384
|
-
#
|
385
|
-
# +:timezone+ - Sends a timezone to asterisk. See /usr/share/zoneinfo for a list. Defaults to the machine timezone.
|
386
|
-
# +:format+ - This is the format the time is to be said in. Defaults to "ABdY 'digits/at' IMp"
|
387
|
-
#
|
388
|
-
# @see http://www.voip-info.org/wiki/view/Asterisk+cmd+SayUnixTime
|
389
|
-
dialplan :play_time do |*args|
|
390
|
-
argument, options = args.flatten
|
391
|
-
options ||= {}
|
392
|
-
|
393
|
-
return false unless options.is_a? Hash
|
394
|
-
|
395
|
-
timezone = options.delete(:timezone) || ''
|
396
|
-
format = options.delete(:format) || ''
|
397
|
-
epoch = case argument
|
398
|
-
when Time || DateTime
|
399
|
-
argument.to_i
|
400
|
-
when Date
|
401
|
-
format = 'BdY' unless format.present?
|
402
|
-
argument.to_time.to_i
|
403
|
-
end
|
404
|
-
|
405
|
-
return false if epoch.nil?
|
406
|
-
|
407
|
-
execute "SayUnixTime", epoch, timezone, format
|
408
|
-
end
|
409
|
-
|
410
|
-
#Executes SayNumber with the passed argument.
|
411
|
-
#
|
412
|
-
# @param [Numeric|String] Numeric argument, or a string contanining numbers.
|
413
|
-
# @return [Boolean] Returns false if the argument could not be played.
|
414
|
-
dialplan :play_numeric do |argument|
|
415
|
-
if argument.kind_of?(Numeric) || argument =~ /^\d+$/
|
416
|
-
execute "SayNumber", argument
|
417
|
-
end
|
418
|
-
end
|
419
|
-
|
420
|
-
# Instruct Asterisk to play a sound file to the channel.
|
421
|
-
#
|
422
|
-
# @param [String] File name to play in the Asterisk convention, without extension.
|
423
|
-
# @return [Boolean] Returns false if the argument could not be played.
|
424
|
-
dialplan :play_soundfile do |argument|
|
425
|
-
execute "Playback", argument
|
426
|
-
get_variable('PLAYBACKSTATUS') == PLAYBACK_SUCCESS
|
427
|
-
end
|
428
|
-
|
429
|
-
#
|
430
|
-
# Plays a single output, not only files, accepting interruption by one of the digits specified
|
431
|
-
# Currently still stops execution, will be fixed soon in Punchblock
|
432
|
-
#
|
433
|
-
# @param [Object] String or Hash specifying output and options
|
434
|
-
# @param [String] String with the digits that are allowed to interrupt output
|
435
|
-
# @return [String|nil] The pressed digit, or nil if nothing was pressed
|
436
|
-
#
|
437
|
-
dialplan :stream_file do |argument, digits = '0123456789#*'|
|
438
|
-
begin
|
439
|
-
output_component = ::Punchblock::Component::Asterisk::AGI::Command.new :name => "STREAM FILE",
|
440
|
-
:params => [
|
441
|
-
argument,
|
442
|
-
digits
|
443
|
-
]
|
444
|
-
execute_component_and_await_completion output_component
|
445
|
-
|
446
|
-
reason = output_component.complete_event.reason
|
447
|
-
|
448
|
-
case reason.result
|
449
|
-
when 0
|
450
|
-
raise Adhearsion::PlaybackError if reason.data == "endpos=0"
|
451
|
-
nil
|
452
|
-
when -1
|
453
|
-
raise Adhearsion::PlaybackError
|
454
|
-
else
|
455
|
-
[reason.result].pack 'U*'
|
456
|
-
end
|
457
|
-
rescue StandardError => e
|
458
|
-
raise Adhearsion::PlaybackError, "Output failed for argument #{argument.inspect}"
|
459
|
-
end
|
6
|
+
init do
|
7
|
+
::Adhearsion::CallController.mixin ::Adhearsion::Asterisk::CallControllerMethods
|
460
8
|
end
|
461
9
|
|
462
10
|
end#class
|