lib/adhearsion/voip/asterisk/commands.rb in adhearsion-0.8.4 vs lib/adhearsion/voip/asterisk/commands.rb in adhearsion-0.8.5
- old
+ new
@@ -41,29 +41,36 @@
extend_dynamic_features_with 'blindxfer'
end
} unless defined? DYNAMIC_FEATURE_EXTENSIONS
# Utility method to write to pbx.
+ # @param [String] message raw message
def write(message)
- to_pbx.print(message)
+ to_pbx.print(message + "\n")
end
# Utility method to read from pbx. Hangup if nil.
def read
returning from_pbx.gets do |message|
+ ahn_log.agi.debug "<<< #{message}"
+ # AGI has many conditions that might indicate a hangup
raise Hangup if message.nil?
raise Hangup if message.match(/^HANGUP\n?$/i)
+ raise Hangup if message.match(/^HANGUP\s?\d{3}/i)
raise Hangup if message.match(/^511 Command Not Permitted on a dead channel/i)
- ahn_log.agi.debug "<<< #{message}"
end
end
- # This method is the underlying method executed by nearly all the command methods in this module.
- # It is used to send the plaintext commands in the proper AGI format over TCP/IP back to an Asterisk server via the
+ # The underlying method executed by nearly all the command methods in this module.
+ # Used to send the plaintext commands in the proper AGI format over TCP/IP back to an Asterisk server via the
# FAGI protocol.
+ #
# It is not recommended that you call this method directly unless you plan to write a new command method
- # in which case use this method you to communicate directly with an Asterisk server via the FAGI protocol.
+ # in which case use this to communicate directly with an Asterisk server via the FAGI protocol.
+ #
+ # @param [String] message
+ #
# @see http://www.voip-info.org/wiki/view/Asterisk+FastAGI More information about FAGI
def raw_response(message = nil)
raise ArgumentError.new("illegal NUL in message #{message.inspect}") if message =~ /\0/
ahn_log.agi.debug ">>> #{message}"
write message if message
@@ -81,31 +88,30 @@
else
raw_response("#{command} " + arguments.map{ |arg| quote_arg.call(arg.to_s) }.join(' '))
end
end
- # The answer command must be called first before any other commands can be issued.
- # In typical adhearsion applications the answer command is called by default as soon
- # as a call is transfered to a valid context in dialplan.rb.
- # If you do not want your adhearsion application to automatically issue an answer command,
+ # This must be called first before any other commands can be issued.
+ # In typical Adhearsion applications this is called by default as soon as a call is
+ # transfered to a valid context in dialplan.rb.
+ # If you do not want your Adhearsion application to automatically issue an answer command,
# then you must edit your startup.rb file and configure this setting.
- # Keep in mind that you should not need to issue another answer command after
- # an answer command has already been issued either explicitly by your code or implicitly
- # by the standard adhearsion configuration.
+ # Keep in mind that you should not need to issue another answer command after one has already
+ # been issued either explicitly by your code or implicitly by the standard adhearsion configuration.
def answer
response "ANSWER"
true
end
# This asterisk dialplan command allows you to instruct Asterisk to start applications
# which are typically run from extensions.conf.
#
# The most common commands are already made available through the FAGI interface provided
- # by this code base. For commands that do not fall into this category, then exec is what you
+ # by this code base. For commands that do not fall into this category, then exec is what you
# should use.
#
- # For example, if there are specific asterisk modules you have loaded that will not
+ # 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 used EXEC.
#
# @example Using execute in this way will add a header to an existing SIP call.
# execute 'SIPAddHeader', '"Call-Info: answer-after=0"
#
@@ -116,10 +122,16 @@
return false if error?(result)
result
end
# Sends a message to the console via the verbose message system.
+ #
+ # @param [String] message
+ # @param [Integer] level
+ #
+ # @return the result of the command
+ #
# @example Use this command to inform someone watching the Asterisk console
# of actions happening within Adhearsion.
# verbose 'Processing call with Adhearsion' 3
#
# @see http://www.voip-info.org/wiki/view/verbose
@@ -139,11 +151,11 @@
# Plays the specified sound file names. This method will handle Time/DateTime objects (e.g. Time.now),
# Fixnums (e.g. 1000), Strings which are valid Fixnums (e.g "123"), and direct sound files. When playing
# numbers, Adhearsion assumes you're saying the number, not the digits. For example, play("100")
# is pronounced as "one hundred" instead of "one zero zero".
#
- # Note: it's not necessary to supply a sound file extension; Asterisk will try to find a sound
+ # Note: it is not necessary to supply a sound file extension; Asterisk will try to find a sound
# file encoded using the current channel's codec, if one exists. If not, it will transcode from
# the default codec (GSM). Asterisk stores its sound files in /var/lib/asterisk/sounds.
#
# @example Play file hello-world.???
# play 'hello-world'
@@ -174,47 +186,61 @@
# @example All options specified
# record 'my-file.gsm', :silence => 5, :maxduration => 120
#
def record(*args)
options = args.last.kind_of?(Hash) ? args.pop : {}
- filename = args.shift || "/tmp/recording_%d.gsm"
+ filename = args.shift || "/tmp/recording_%d"
+
+ if filename.index("%d")
+ if @call.variables.has_key?(:recording_counter)
+ @call.variables[:recording_counter] += 1
+ else
+ @call.variables[:recording_counter] = 0
+ end
+ filename = filename % @call.variables[:recording_counter]
+ end
+
if (!options.has_key?(:format))
format = filename.slice!(/\.[^\.]+$/)
if (format.nil?)
ahn_log.agi.warn "Format not specified and not detected. Defaulting to \"gsm\""
format = gsm
end
format.sub!(/^\./, "")
else
format = options.delete(:format)
end
- silence = options.delete(:silence) || 0
+
+ # maxduration must be in milliseconds when using RECORD FILE
maxduration = options.delete(:maxduration) || -1
+ maxduration = maxduration * 1000 if maxduration > 0
+
escapedigits = options.delete(:escapedigits) || "#"
+ silence = options.delete(:silence) || 0
if (silence > 0)
- response("RECORD FILE", filename, format, escapedigits, maxduration,0, "BEEP", "s=#{silence}")
+ response("RECORD FILE", filename, format, escapedigits, maxduration, 0, "BEEP", "s=#{silence}")
else
response("RECORD FILE", filename, format, escapedigits, maxduration, 0, "BEEP")
end
# If the user hangs up before the recording is entered, -1 is returned and RECORDED_FILE
# will not contain the name of the file, even though it IS in fact recorded.
- filename.index("%d") ? get_variable('RECORDED_FILE') : filename + "." + format
+ filename + "." + format
end
# Simulates pressing the specified digits over the current channel. Can be used to
# traverse a phone menu.
def dtmf(digits)
- execute "SendDTMF", digits.to_s
- end
+ execute "SendDTMF", digits.to_s
+ end
- # The with_next_message method...
- def with_next_message(&block)
- raise LocalJumpError, "Must supply a block" unless block_given?
+ # The with_next_message method...
+ def with_next_message(&block)
+ raise LocalJumpError, "Must supply a block" unless block_given?
block.call(next_message)
- end
+ end
# This command should be used to advance to the next message in the Asterisk Comedian Voicemail application
def next_message
@call.inbox.pop
end
@@ -222,11 +248,11 @@
# This command should be used to check if a message is waiting on the Asterisk Comedian Voicemail application.
def messages_waiting?
not @call.inbox.empty?
end
- # Menu creates an interactive menu for the caller.
+ # Creates an interactive menu for the caller.
#
# The following documentation was derived from a post on Jay Phillips' blog (see below).
#
# The menu() command solves the problem of building enormous input-fetching state machines in Ruby without first-class
# message passing facilities or an external DSL.
@@ -387,11 +413,11 @@
retry
end
end
- # This method is used to receive keypad input from the user. Digits are collected
+ # Used to receive keypad input from the user. Digits are collected
# via DTMF (keypad) input until one of three things happens:
#
# 1. The number of digits you specify as the first argument is collected
# 2. The timeout you specify with the :timeout option elapses.
# 3. The "#" key (or the key you specify with :accept_key) is pressed
@@ -414,12 +440,12 @@
#
# The :timeout option works like a digit timeout, therefore each digit pressed
# causes the timer to reset. This is a much more user-friendly approach than an
# absolute timeout.
#
- # Note that when you don't specify a digit limit, the :accept_key becomes "#"
- # because there'd be no other way to end the collection of digits. You can
+ # Note that when the digit limit is not specified the :accept_key becomes "#".
+ # Otherwise there would be no way to end the collection of digits. You can
# obviously override this by passing in a new key with :accept_key.
def input(*args)
options = args.last.kind_of?(Hash) ? args.pop : {}
number_of_digits = args.shift
@@ -467,12 +493,17 @@
# you can effectively "restart" a call (from the perspective of the jumped-to context). When you override
# variables here, you're effectively blowing away the old variables. If you need them for some reason,
# you should assign the important ones to an instance variable first before calling this method.
def jump_to(context, overrides={})
context = lookup_context_with_name(context) if context.kind_of?(Symbol) || (context.kind_of?(String) && context =~ /^[\w_]+$/)
- raise Adhearsion::VoIP::DSL::Dialplan::ContextNotFoundException unless context.kind_of?(Adhearsion::DialPlan::DialplanContextProc)
+ # JRuby has a bug that prevents us from correctly determining the class name.
+ # See: http://jira.codehaus.org/browse/JRUBY-5026
+ if !(context.kind_of?(Adhearsion::DialPlan::DialplanContextProc) || context.kind_of?(Proc))
+ raise Adhearsion::VoIP::DSL::Dialplan::ContextNotFoundException
+ end
+
if overrides.any?
overrides = overrides.symbolize_keys
if overrides.has_key?(:extension) && !overrides[:extension].kind_of?(Adhearsion::VoIP::DSL::PhoneNumber)
overrides[:extension] = Adhearsion::VoIP::DSL::PhoneNumber.new overrides[:extension]
end
@@ -483,13 +514,17 @@
end
raise Adhearsion::VoIP::DSL::Dialplan::ControlPassingException.new(context)
end
- # The queue method puts a call into a call queue to be answered by an agent registered with that queue.
- # The queue method takes a queue_name as an argument to place the caller in the appropriate queue.
+ # Place a call in a queue to be answered by a registered agent. You must then call join!()
+ #
+ # @param [String] queue_name the queue name to place the caller in
+ # @return [Adhearsion::VoIP::Asterisk::Commands::QueueProxy] a queue proxy object
+ #
# @see http://www.voip-info.org/wiki-Asterisk+cmd+Queue Full information on the Asterisk Queue
+ # @see Adhearsion::VoIP::Asterisk::Commands::QueueProxy#join! join!() for further details
def queue(queue_name)
queue_name = queue_name.to_s
@queue_proxy_hash_lock = Mutex.new unless defined? @queue_proxy_hash_lock
@queue_proxy_hash_lock.synchronize do
@@ -501,23 +536,21 @@
return proxy
end
end
end
- # Returns the status of the last dial(). Possible dial
- # statuses include :answer, :busy, :no_answer, :cancelled,
- # :congested, and :channel_unavailable. If :cancel is
- # returned, the caller hung up before the callee picked
- # up. If :congestion is returned, the dialed extension
- # probably doesn't exist. If :channel_unavailable, the callee
- # phone may not be registered.
+ # Get the status of the last dial(). Possible dial statuses include :answer,
+ # :busy, :no_answer, :cancelled, :congested, and :channel_unavailable.
+ # If :cancel is returned, the caller hung up before the callee picked up.
+ # If :congestion is returned, the dialed extension probably doesn't exist.
+ # If :channel_unavailable, the callee phone may not be registered.
def last_dial_status
DIAL_STATUSES[get_dial_status]
end
- # Returns true if your last call to dial() finished with the ANSWER state, as reported
- # by Asterisk. Returns false otherwise
+ # @return [Boolean] true if your last call to dial() finished with the ANSWER state,
+ # as reported by Asterisk. false otherwise
def last_dial_successful?
last_dial_status == :answered
end
# Opposite of last_dial_successful?()
@@ -529,11 +562,11 @@
def speak(text, engine=:none)
engine = AHN_CONFIG.asterisk.speech_engine || engine
execute SpeechEngines.send(engine, text)
end
- # This method is a high-level way of enabling features you create/uncomment from features.conf.
+ # 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:
@@ -558,59 +591,77 @@
end
end
# Disables a feature name specified in features.conf. If you're disabling it, it was probably
# set by enable_feature().
+ #
+ # @param [String] feature_name
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
- # 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.
+ # 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.
+ #
+ # @param [String] conference_id
+ # @param [Hash] options
+ #
# @see http://www.voip-info.org/wiki-Asterisk+cmd+MeetMe Asterisk Meetme Application Information
def join(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'
+ command_flags += 'd' unless (command_flags.include?('d') or use_static_conf)
execute "MeetMe", conference_id, command_flags, options[:pin]
end
# 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: http://www.voip-info.org/wiki/view/get+variable Asterisk Get Variable
+ #
+ # @param [String] variable_name
+ #
+ # @see: http://www.voip-info.org/wiki/view/get+variable Asterisk Get Variable
def get_variable(variable_name)
result = response("GET VARIABLE", variable_name)
case result
when "200 result=0"
return nil
when /^200 result=1 \((.*)\)$/
return $LAST_PAREN_MATCH
end
end
- # Use set_variable to 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
+ # 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.
+ # application to share. Once the channel is "hungup" then the variables are cleared and their information is gone.
+ #
+ # @param [String] variable_name
+ # @param [String] value
+ #
# @see http://www.voip-info.org/wiki/view/set+variable Asterisk Set Variable
def set_variable(variable_name, value)
response("SET VARIABLE", variable_name, value) == "200 result=1"
end
- # The variable method allows you to either set or get a channel variable from Asterisk
+ # 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
def variable(*args)
if args.last.kind_of? Hash
assignments = args.pop
@@ -625,14 +676,16 @@
args.map { |var| get_variable(var) }
end
end
end
- # Use the voicemail method to send a caller to a voicemail box to leave a message.
- # @see http://www.voip-info.org/tiki-index.php?page=Asterisk+cmd+VoiceMail Asterisk Voicemail
+ # 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.
+ #
+ # @see http://www.voip-info.org/tiki-index.php?page=Asterisk+cmd+VoiceMail Asterisk Voicemail
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)
@@ -663,10 +716,13 @@
end
end
# The voicemail_main method puts a caller into the voicemail system to fetch their voicemail
# or set options for their voicemail box.
+ #
+ # @param [Hash] options
+ #
# @see http://www.voip-info.org/wiki-Asterisk+cmd+VoiceMailMain Asterisk VoiceMailMain Command
def voicemail_main(options={})
mailbox, context, folder = options.values_at :mailbox, :context, :folder
authenticate = options.has_key?(:authenticate) ? options[:authenticate] : true
@@ -700,19 +756,19 @@
def check_voicemail
ahn_log.agi.warn "THE check_voicemail() DIALPLAN METHOD WILL SOON BE DEPRECATED! CHANGE THIS TO voicemail_main() INSTEAD"
voicemail_main
end
- # Use this command to dial an extension or "phone number" in asterisk.
- # This command maps to the Asterisk DIAL command in the asterisk dialplan.
+ # Dial an extension or "phone number" in asterisk.
+ # Maps to the Asterisk DIAL command in the asterisk dialplan.
#
- # The first parameter, number, must be a string that represents the extension or "number" that asterisk should dial.
+ # @param [String] number represents the extension or "number" that asterisk should dial.
# Be careful to not just specify a number like 5001, 9095551001
# You must specify a properly formatted string as Asterisk would expect to use in order to understand
# whether the call should be dialed using SIP, IAX, or some other means.
#
- # Options Parameter:
+ # @param [Hash] options
#
# +:caller_id+ - the caller id number to be used when the call is placed. It is advised you properly adhere to the
# policy of VoIP termination providers with respect to caller id values.
#
# +:name+ - this is the name which should be passed with the caller ID information
@@ -725,22 +781,22 @@
#
# +:options+ - This is a string of options like "Tr" which are supported by the asterisk DIAL application.
# for a complete list of these options and their usage please check the link below.
#
# +:confirm+ - ?
- #
+ #
# @example Make a call to the PSTN using my SIP provider for VoIP termination
# dial("SIP/19095551001@my.sip.voip.terminator.us")
#
# @example Make 3 Simulataneous calls to the SIP extensions separated by & symbols, try for 15 seconds and use the callerid
# for this call specified by the variable my_callerid
# dial "SIP/jay-desk-650&SIP/jay-desk-601&SIP/jay-desk-601-2", :for => 15.seconds, :caller_id => my_callerid
#
# @example Make a call using the IAX provider to the PSTN
# dial("IAX2/my.id@voipjet/19095551234", :name=>"John Doe", :caller_id=>"9095551234")
#
- # @see http://www.voip-info.org/wiki-Asterisk+cmd+Dial Asterisk Dial Command
+ # @see http://www.voip-info.org/wiki-Asterisk+cmd+Dial Asterisk Dial Command
def dial(number, options={})
*recognized_options = :caller_id, :name, :for, :options, :confirm
unrecognized_options = options.keys - recognized_options
raise ArgumentError, "Unknown dial options: #{unrecognized_options.to_sentence}" if unrecognized_options.any?
@@ -772,29 +828,34 @@
# call_attempt_status
# end
# Speaks the digits given as an argument. For example, "123" is spoken as "one two three".
+ #
+ # @param [String] digits
def say_digits(digits)
execute "saydigits", validate_digits(digits)
end
- # Returns the number of seconds the given block takes to execute as a Float. This
+ # Get the number of seconds the given block takes to execute. This
# is particularly useful in dialplans for tracking billable time. Note that
# if the call is hung up during the block, you will need to rescue the
# exception if you have some mission-critical logic after it with which
# you're recording this return-value.
+ #
+ # @return [Float] number of seconds taken for block to execute
def duration_of
start_time = Time.now
yield
Time.now - start_time
end
#
- # This will play a sequence of files, stopping the playback if a digit is pressed. If a digit is pressed, it will be
- # returned as a String. If the files played with no keypad input, nil will be returned.
+ # Play a sequence of files, stopping the playback if a digit is pressed.
#
+ # @return [String, nil] digit pressed, or nil if none
+ #
def interruptible_play(*files)
files.flatten.each do |file|
result = result_digit_from response("STREAM FILE", file, "1234567890*#")
return result if result != 0.chr
end
@@ -816,18 +877,18 @@
def interruptable_play(*files)
ahn_log.deprecation.warn 'Please change your code to use interruptible_play() instead. "interruptable" is a misspelling! interruptable_play() will work for now but will be deprecated in the future!'
interruptible_play(*files)
end
- # set_callier_id_number method allows setting of the callerid number of the call
+ # allows setting of the callerid number of the call
def set_caller_id_number(caller_id)
return unless caller_id
raise ArgumentError, "Caller ID must be numerical" if caller_id.to_s !~ /^\d+$/
response "SET CALLERID", caller_id
end
- # set_caller_id_name method allows the setting of the callerid name of the call
+ # allows the setting of the callerid name of the call
def set_caller_id_name(caller_id_name)
return unless caller_id_name
variable "CALLERID(name)" => caller_id_name
end
@@ -970,11 +1031,11 @@
raise ArgumentError, "Can only be called with valid digits!" unless digits_as_string =~ /^[0-9*#-]+$/
end
end
def error?(result)
- result.to_s[/^#{response_prefix}(?:-\d+|0)/]
+ result.to_s[/^#{response_prefix}(?:-\d+)/]
end
# timeout with pressed digits: 200 result=<digits> (timeout)
# timeout without pressed digits: 200 result= (timeout)
# @see http://www.voip-info.org/wiki/view/get+data AGI Get Data
@@ -1044,68 +1105,108 @@
attr_reader :name, :environment
def initialize(name, environment)
@name, @environment = name, environment
end
- # Makes the current channel join the queue. Below are explanations of the recognized Hash-key
- # arguments supported by this method.
+ # Makes the current channel join the queue.
#
+ # @param [Hash] options
+ #
# :timeout - The number of seconds to wait for an agent to answer
# :play - Can be :ringing or :music.
# :announce - A sound file to play instead of the normal queue announcement.
# :allow_transfer - Can be :caller, :agent, or :everyone. Allow someone to transfer the call.
# :allow_hangup - Can be :caller, :agent, or :everyone. Allow someone to hangup with the * key.
#
- # Usage examples:
- #
- # - queue('sales').join!
- # - queue('sales').join! :timeout => 1.minute
- # - queue('sales').join! :play => :music
- # - queue('sales').join! :play => :ringing
- # - queue('sales').join! :announce => "custom/special-queue-announcement"
- # - queue('sales').join! :allow_transfer => :caller
- # - queue('sales').join! :allow_transfer => :agent
- # - queue('sales').join! :allow_hangup => :caller
- # - queue('sales').join! :allow_hangup => :agent
- # - queue('sales').join! :allow_hangup => :everyone
- # - queue('sales').join! :allow_transfer => :agent, :timeout => 30.seconds,
+ # @example
+ # queue('sales').join!
+ # @example
+ # queue('sales').join! :timeout => 1.minute
+ # @example
+ # queue('sales').join! :play => :music
+ # @example
+ # queue('sales').join! :play => :ringing
+ # @example
+ # queue('sales').join! :announce => "custom/special-queue-announcement"
+ # @example
+ # queue('sales').join! :allow_transfer => :caller
+ # @example
+ # queue('sales').join! :allow_transfer => :agent
+ # @example
+ # queue('sales').join! :allow_hangup => :caller
+ # @example
+ # queue('sales').join! :allow_hangup => :agent
+ # @example
+ # queue('sales').join! :allow_hangup => :everyone
+ # @example
+ # queue('sales').join! :allow_transfer => :agent, :timeout => 30.seconds,
def join!(options={})
environment.execute("queue", name, *self.class.format_join_hash_key_arguments(options))
normalize_queue_status_variable environment.variable("QUEUESTATUS")
end
+ # Get the agents associated with a queue
+ #
+ # @param [Hash] options
+ # @return [QueueAgentsListProxy]
def agents(options={})
cached = options.has_key?(:cache) ? options.delete(:cache) : true
raise ArgumentError, "Unrecognized arguments to agents(): #{options.inspect}" if options.keys.any?
if cached
@cached_proxy ||= QueueAgentsListProxy.new(self, true)
else
@uncached_proxy ||= QueueAgentsListProxy.new(self, false)
end
end
+ # Check how many channels are waiting in the queue
+ # @return [Integer]
+ # @raise QueueDoesNotExistError
def waiting_count
raise QueueDoesNotExistError.new(name) unless exists?
environment.variable("QUEUE_WAITING_COUNT(#{name})").to_i
end
+ # Check whether the waiting count is zero
+ # @return [Boolean]
def empty?
waiting_count == 0
end
+ # Check whether any calls are waiting in the queue
+ # @return [Boolean]
def any?
waiting_count > 0
end
+ # Check whether a queue exists/is defined in Asterisk
+ # @return [Boolean]
def exists?
environment.execute('RemoveQueueMember', name, 'SIP/AdhearsionQueueExistenceCheck')
environment.variable("RQMSTATUS") != 'NOSUCHQUEUE'
end
private
+ # Ensure the queue exists by interpreting the QUEUESTATUS variable
+ #
+ # According to http://www.voip-info.org/wiki/view/Asterisk+cmd+Queue
+ # possible values are:
+ # TIMEOUT (:timeout
+ # FULL (:full)
+ # JOINEMPTY (:joinempty)
+ # LEAVEEMPTY (:leaveempty)
+ # JOINUNAVAIL (:joinunavail)
+ # LEAVEUNAVAIL (:leaveunavail)
+ #
+ # If Adhearsion cannot determine the status then :unknown will be returned.
+ #
+ # @param [String] QUEUESTATUS variable from Asterisk
+ # @return [Symbol] Symbolized version of QUEUESTATUS
+ # @raise QueueDoesNotExistError
def normalize_queue_status_variable(variable)
+ variable = "UNKNOWN" if variable.nil?
returning variable.downcase.to_sym do |queue_status|
raise QueueDoesNotExistError.new(name) if queue_status == :unknown
end
end
@@ -1127,13 +1228,13 @@
end
end
alias size count
alias length count
- # Supported Hash-key arguments are :penalty and :name. The :name value will be viewable in
- # the queue_log. The :penalty is the penalty assigned to this agent for answering calls on
- # this queue
+ # @param [Hash] args
+ # :name value will be viewable in the queue_log
+ # :penalty is the penalty assigned to this agent for answering calls on this queue
def new(*args)
options = args.last.kind_of?(Hash) ? args.pop : {}
interface = args.shift || ''
@@ -1307,11 +1408,11 @@
proxy.environment.variable "AGENT(#{id}:#{data_name})"
end
end
- class QueueDoesNotExistError < Exception
+ class QueueDoesNotExistError < StandardError
def initialize(queue_name)
super "Queue #{queue_name} does not exist!"
end
end
@@ -1323,10 +1424,10 @@
end
end
module SpeechEngines
- class InvalidSpeechEngine < Exception; end
+ class InvalidSpeechEngine < StandardError; end
class << self
def cepstral(text)
puts "in ceptral"
puts escape(text)