Module: Adhearsion::Asterisk::CallControllerMethods

Defined in:
lib/adhearsion/asterisk/call_controller_methods.rb

Constant Summary collapse

DYNAMIC_FEATURE_EXTENSIONS =
{
  :attended_transfer => lambda do |options|
    variable "TRANSFER_CONTEXT" => options[:context] if options && options.has_key?(:context)
    extend_dynamic_features_with "atxfer"
  end,
  :blind_transfer => lambda do |options|
    variable "TRANSFER_CONTEXT" => options[:context] if options && options.has_key?(:context)
    extend_dynamic_features_with 'blindxfer'
  end
}

Instance Method Summary collapse

Instance Method Details

#agi(name, *params) ⇒ Object



17
18
19
20
21
22
# File 'lib/adhearsion/asterisk/call_controller_methods.rb', line 17

def agi(name, *params)
  component = Punchblock::Component::Asterisk::AGI::Command.new :name => name, :params => params
  execute_component_and_await_completion component
  complete_reason = component.complete_event.reason
  [:code, :result, :data].map { |p| complete_reason.send p }
end

#disable_feature(feature_name) ⇒ Object

Disables a feature name specified in features.conf. If you’re disabling it, it was probably set by enable_feature().

Parameters:

  • feature_name (String)


99
100
101
102
103
104
105
106
# File 'lib/adhearsion/asterisk/call_controller_methods.rb', line 99

def disable_feature(feature_name)
  enabled_features_variable = variable 'DYNAMIC_FEATURES'
  enabled_features = enabled_features_variable.split('#')
  if enabled_features.include? feature_name
    enabled_features.delete feature_name
    variable 'DYNAMIC_FEATURES' => enabled_features.join('#')
  end
end

#enable_feature(*args) ⇒ Object

A high-level way of enabling features you create/uncomment from features.conf.

Certain Symbol features you enable (as defined in DYNAMIC_FEATURE_EXTENSIONS) have optional arguments that you can also specify here. The usage examples show how to do this.

Usage examples:

enable_feature :attended_transfer                        # Enables "atxfer"

enable_feature :attended_transfer, :context => "my_dial" # Enables "atxfer" and then
                                                         # sets "TRANSFER_CONTEXT" to :context's value

enable_feature :blind_transfer, :context => 'my_dial'    # Enables 'blindxfer' and sets TRANSFER_CONTEXT

enable_feature "foobar"                                  # Enables "foobar"

enable_feature("dup"); enable_feature("dup")             # Enables "dup" only once.

def voicemail(*args)

options_hash    = args.last.kind_of?(Hash) ? args.pop : {}
mailbox_number  = args.shift
greeting_option = options_hash.delete :greeting


81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/adhearsion/asterisk/call_controller_methods.rb', line 81

def enable_feature(*args)
  feature_name, optional_options = args.flatten

  if DYNAMIC_FEATURE_EXTENSIONS.has_key? feature_name
    instance_exec(optional_options, &DYNAMIC_FEATURE_EXTENSIONS[feature_name])
  else
    unless optional_options.nil? or optional_options.empty?
      raise ArgumentError, "You cannot supply optional options when the feature name is " +
                           "not internally recognized!"
    end
    extend_dynamic_features_with feature_name
  end
end

#execute(name, *params) ⇒ Object

This asterisk dialplan command allows you to instruct Asterisk to start applications which are typically run from extensions.conf and do not have AGI command equivalents.

For example, if there are specific asterisk modules you have loaded that will not be available through the standard commands provided through FAGI - then you can use EXEC.

Examples:

Using execute in this way will add a header to an existing SIP call.

execute 'SIPAddHeader', "Call-Info: answer-after=0"

See Also:



36
37
38
# File 'lib/adhearsion/asterisk/call_controller_methods.rb', line 36

def execute(name, *params)
  agi "EXEC #{name}", *params
end

#extend_dynamic_features_with(feature_name) ⇒ Object

helper method that should probably should private…



109
110
111
112
113
114
115
116
# File 'lib/adhearsion/asterisk/call_controller_methods.rb', line 109

def extend_dynamic_features_with(feature_name)
  current_variable = variable("DYNAMIC_FEATURES") || ''
  enabled_features = current_variable.split '#'
  unless enabled_features.include? feature_name
    enabled_features << feature_name
    variable "DYNAMIC_FEATURES" => enabled_features.join('#')
  end
end

#get_variable(variable_name) ⇒ Object

Issue this command to access a channel variable that exists in the asterisk dialplan (i.e. extensions.conf) Use get_variable to pass information from other modules or high level configurations from the asterisk dialplan to the adhearsion dialplan.

@see: www.voip-info.org/wiki/view/get+variable Asterisk Get Variable

Parameters:

  • variable_name (String)


127
128
129
130
# File 'lib/adhearsion/asterisk/call_controller_methods.rb', line 127

def get_variable(variable_name)
  code, result, data = agi "GET VARIABLE", variable_name
  data
end

#meetme(conference_id, options = {}) ⇒ Object

Used to join a particular conference with the MeetMe application. To use MeetMe, be sure you have a proper timing device configured on your Asterisk box. MeetMe is Asterisk’s built-in conferencing program.

Parameters:

  • conference_id (String)
  • options (Hash) (defaults to: {})

Raises:

  • (ArgumentError)

See Also:



209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/adhearsion/asterisk/call_controller_methods.rb', line 209

def meetme(conference_id, options = {})
  conference_id = conference_id.to_s.scan(/\w/).join
  command_flags = options[:options].to_s # This is a passthrough string straight to Asterisk
  pin = options[:pin]
  raise ArgumentError, "A conference PIN number must be numerical!" if pin && pin.to_s !~ /^\d+$/

  # To disable dynamic conference creation set :use_static_conf => true
  use_static_conf = options.has_key?(:use_static_conf) ? options[:use_static_conf] : false

  # The 'd' option of MeetMe creates conferences dynamically.
  command_flags += 'd' unless command_flags.include?('d') || use_static_conf

  execute "MeetMe", conference_id, command_flags, options[:pin]
end

#play_numeric(argument) ⇒ Boolean

Executes SayNumber with the passed argument.

Parameters:

  • Numeric (Numeric|String)

    argument, or a string contanining numbers.

Returns:

  • (Boolean)

    Returns false if the argument could not be played.



364
365
366
367
368
# File 'lib/adhearsion/asterisk/call_controller_methods.rb', line 364

def play_numeric(argument)
  if argument.kind_of?(Numeric) || argument =~ /^\d+$/
    execute "SayNumber", argument
  end
end

#play_soundfile(argument) ⇒ Boolean

Instruct Asterisk to play a sound file to the channel.

Parameters:

  • File (String)

    name to play in the Asterisk convention, without extension.

Returns:

  • (Boolean)

    Returns false if the argument could not be played.



374
375
376
377
# File 'lib/adhearsion/asterisk/call_controller_methods.rb', line 374

def play_soundfile(argument)
  execute "Playback", argument
  get_variable('PLAYBACKSTATUS') == PLAYBACK_SUCCESS
end

#play_time(*args) ⇒ Object

Plays the given Date, Time, or Integer (seconds since epoch) using the given timezone and format.

:timezone - Sends a timezone to asterisk. See /usr/share/zoneinfo for a list. Defaults to the machine timezone. :format - This is the format the time is to be said in. Defaults to “ABdY ‘digits/at’ IMp”

Parameters:

  • Time (Date|Time|DateTime)

    to be said.

  • Additional (Hash)

    options to specify how exactly to say time specified.

See Also:



339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
# File 'lib/adhearsion/asterisk/call_controller_methods.rb', line 339

def play_time(*args)
  argument, options = args.flatten
  options ||= {}

  return false unless options.is_a? Hash

  timezone = options.delete(:timezone) || ''
  format   = options.delete(:format)   || ''
  epoch    = case argument
             when Time || DateTime
               argument.to_i
             when Date
               format = 'BdY' unless format.present?
               argument.to_time.to_i
             end

  return false if epoch.nil?

  execute "SayUnixTime", epoch, timezone, format
end

#queue(queue_name) ⇒ Adhearsion::Asterisk::QueueProxy

Place a call in a queue to be answered by a registered agent. You must then call #join!

Parameters:

  • queue_name (String)

    the queue name to place the caller in

Returns:

See Also:



314
315
316
317
318
319
320
321
322
323
324
325
326
327
# File 'lib/adhearsion/asterisk/call_controller_methods.rb', line 314

def queue(queue_name)
  queue_name = queue_name.to_s

  @queue_proxy_hash_lock ||= Mutex.new
  @queue_proxy_hash_lock.synchronize do
    @queue_proxy_hash ||= {}
    if @queue_proxy_hash.has_key? queue_name
      return @queue_proxy_hash[queue_name]
    else
      proxy = @queue_proxy_hash[queue_name] = QueueProxy.new(queue_name, self)
      return proxy
    end
  end
end

#set_variable(variable_name, value) ⇒ Object

Pass information back to the asterisk dial plan.

Keep in mind that the variables are not global variables. These variables only exist for the channel related to the call that is being serviced by the particular instance of your adhearsion application. You will not be able to pass information back to the asterisk dialplan for other instances of your adhearsion application to share. Once the channel is “hungup” then the variables are cleared and their information is gone.

Parameters:

  • variable_name (String)
  • value (String)

See Also:



145
146
147
# File 'lib/adhearsion/asterisk/call_controller_methods.rb', line 145

def set_variable(variable_name, value)
  agi "SET VARIABLE", variable_name, value
end

#sip_add_header(header, value) ⇒ String

Issue the command to add a custom SIP header to the current call channel example use: sip_add_header(“x-ahn-test”, “rubyrox”)

@param the name of the SIP header @param the value of the SIP header

Returns:

  • (String)

    the Asterisk response

See Also:



160
161
162
# File 'lib/adhearsion/asterisk/call_controller_methods.rb', line 160

def sip_add_header(header, value)
  execute "SIPAddHeader", "#{header}: #{value}"
end

#sip_get_header(header) ⇒ String

Issue the command to fetch a SIP header from the current call channel example use: sip_get_header(“x-ahn-test”)

@param the name of the SIP header to get

Returns:

  • (String)

    the Asterisk response

See Also:



174
175
176
# File 'lib/adhearsion/asterisk/call_controller_methods.rb', line 174

def sip_get_header(header)
  get_variable "SIP_HEADER(#{header})"
end

#variable(*args) ⇒ Object

Allows you to either set or get a channel variable from Asterisk. The method takes a hash key/value pair if you would like to set a variable Or a single string with the variable to get from Asterisk



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/adhearsion/asterisk/call_controller_methods.rb', line 183

def variable(*args)
  if args.last.kind_of? Hash
    assignments = args.pop
    raise ArgumentError, "Can't mix variable setting and fetching!" if args.any?
    assignments.each_pair do |key, value|
      set_variable key, value
    end
  else
    if args.size == 1
      get_variable args.first
    else
      args.map { |var| get_variable var }
    end
  end
end

#verbose(message, level = nil) ⇒ Object

Sends a message to the console via the verbose message system.

of actions happening within Adhearsion.

verbose 'Processing call with Adhearsion' 3

Examples:

Use this command to inform someone watching the Asterisk console

Parameters:

  • message (String)
  • level (Integer) (defaults to: nil)

Returns:

  • the result of the command

See Also:



54
55
56
# File 'lib/adhearsion/asterisk/call_controller_methods.rb', line 54

def verbose(message, level = nil)
  agi 'VERBOSE', message, level
end

#voicemail(*args) ⇒ Object

Send a caller to a voicemail box to leave a message.

The method takes the mailbox_number of the user to leave a message for and a greeting_option that will determine which message gets played to the caller.

Raises:

  • (ArgumentError)

See Also:



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/adhearsion/asterisk/call_controller_methods.rb', line 232

def voicemail(*args)
  options_hash    = args.last.kind_of?(Hash) ? args.pop : {}
  mailbox_number  = args.shift
  greeting_option = options_hash.delete :greeting
  skip_option     = options_hash.delete :skip
  raise ArgumentError, 'You supplied too many arguments!' if mailbox_number && options_hash.any?

  greeting_option = case greeting_option
  when :busy then 'b'
  when :unavailable then 'u'
  when nil then nil
  else raise ArgumentError, "Unrecognized greeting #{greeting_option}"
  end
  skip_option &&= 's'
  options = "#{greeting_option}#{skip_option}"

  raise ArgumentError, "Mailbox cannot be blank!" if !mailbox_number.nil? && mailbox_number.blank?
  number_with_context = if mailbox_number then mailbox_number else
    raise ArgumentError, "You must supply ONE context name!" unless options_hash.size == 1
    context_name, mailboxes = options_hash.to_a.first
    Array(mailboxes).map do |mailbox|
      raise ArgumentError, "Mailbox numbers must be numerical!" unless mailbox.to_s =~ /^\d+$/
      [mailbox, context_name].join '@'
    end.join '&'
  end

  execute 'voicemail', number_with_context, options
  case variable('VMSTATUS')
  when 'SUCCESS' then true
  when 'USEREXIT' then false
  else nil
  end
end

#voicemail_main(options = {}) ⇒ Object

The voicemail_main method puts a caller into the voicemail system to fetch their voicemail or set options for their voicemail box.

Parameters:

  • options (Hash) (defaults to: {})

See Also:



274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
# File 'lib/adhearsion/asterisk/call_controller_methods.rb', line 274

def voicemail_main(options = {})
  mailbox, context, folder = options.values_at :mailbox, :context, :folder
  authenticate = options.has_key?(:authenticate) ? options[:authenticate] : true

  folder = if folder
    if folder.to_s =~ /^[\w_]+$/
      "a(#{folder})"
    else
      raise ArgumentError, "Voicemail folder must be alphanumerical/underscore characters only!"
    end
  elsif folder == ''
    raise ArgumentError, "Folder name cannot be an empty String!"
  else
    nil
  end

  real_mailbox = ""
  real_mailbox << "#{mailbox}"  unless mailbox.blank?
  real_mailbox << "@#{context}" unless context.blank?

  real_options = ""
  real_options << "s" if !authenticate
  real_options << folder unless folder.blank?

  command_args = [real_mailbox]
  command_args << real_options unless real_options.blank?
  command_args.clear if command_args == [""]

  execute 'VoiceMailMain', *command_args
end