module Adhearsion::CallController::Input

Constants

Result

Public Instance Methods

ask(*args, options, &block) click to toggle source

Prompts for input via DTMF, handling playback of prompts, timeouts, digit limits and terminator digits.

@example A basic digit collection:

ask "Welcome, ", "/opt/sounds/menu-prompt.mp3",
    :timeout => 10, :terminator => '#', :limit => 3 do |buffer|
  buffer == "12980"
end

The first arguments will be a list of sounds to play, as accepted by play, including strings for TTS, Date and Time objects, and file paths. :timeout, :terminator and :limit options may then be specified. A block may be passed which is invoked on each digit being collected. If it returns true, the collection is terminated.

@param [Object, Array<Object>] args A list of outputs to play, as accepted by play @param [Hash] options Options to use for the menu @option options [Boolean] :interruptible If the prompt should be interruptible or not. Defaults to true @option options [Integer] :limit Digit limit (causes collection to cease after a specified number of digits have been collected) @option options [Integer] :timeout Timeout in seconds before the first and between each input digit @option options [String] :terminator Digit to terminate input

@return [Result] a result object from which the response and status may be established

@see Output#play @see CallController#pass

# File lib/adhearsion/call_controller/input.rb, line 43
def ask(*args, options, &block)
  logger.warn "This implementation of #ask is deprecated due to issues with dropped DTMF. For a solution, see http://adhearsion.com/docs/common_problems#toc_3"

  unless options.is_a?(Hash)
    args << options
    options = {}
  end
  sound_files = args.flatten

  menu_instance = MenuDSL::Menu.new options do
    validator(&block) if block
  end
  menu_instance.validate :basic
  result_of_menu = nil

  catch :finish do
    until MenuDSL::Menu::MenuResultDone === result_of_menu
      raise unless menu_instance.should_continue?

      result_of_menu = menu_instance.continue

      if result_of_menu.is_a?(MenuDSL::Menu::MenuGetAnotherDigit)
        next_digit = play_sound_files_for_menu menu_instance, sound_files
        if next_digit
          menu_instance << next_digit
        else
          menu_instance.timeout!
          throw :finish
        end
      end
    end
  end

  Result.new.tap do |result|
    result.response = menu_instance.result
    result.status   = menu_instance.status
    result.menu     = menu_instance
  end
end
jump_to(match_object, overrides = nil) click to toggle source

@private

# File lib/adhearsion/call_controller/input.rb, line 233
def jump_to(match_object, overrides = nil)
  if match_object.block
    instance_exec overrides[:extension], &match_object.block
  else
    invoke match_object.match_payload, overrides
  end
end
menu(*args, options, &block) click to toggle source

Creates and manages a multiple choice menu driven by DTMF, handling playback of prompts, invalid input, retries and timeouts, and final failures.

@example A complete example of the method is as follows:

menu "Welcome, ", "/opt/sounds/menu-prompt.mp3", :tries => 2, :timeout => 10 do
  match 1, OperatorController

  match 10..19 do
    pass DirectController
  end

  match 5, 6, 9 do |exten|
   play "The #{exten} extension is currently not active"
  end

  match '7', OfficeController

  invalid { play "Please choose a valid extension" }
  timeout { play "Input timed out, try again." }
  failure { pass OperatorController }
end

The first arguments will be a list of sounds to play, as accepted by play, including strings for TTS, Date and Time objects, and file paths. :tries and :timeout options respectively specify the number of tries before going into failure, and the timeout in seconds allowed on each digit input. The most important part is the following block, which specifies how the menu will be constructed and handled.

match handles connecting an input pattern to a payload. The pattern can be one or more of: an integer, a Range, a string, an Array of the possible single types. Input is matched against patterns, and the first exact match has it's payload executed. Matched input is passed in to the associated block, or to the controller through options.

Allowed payloads are the name of a controller class, in which case it is executed through its run method, or a block.

invalid has its associated block executed when the input does not possibly match any pattern. timeout's block is run when time expires before or between input digits. failure runs its block when the maximum number of tries is reached without an input match.

validator runs its block on each digit being collected. If it returns true, the collection is terminated.

Execution of the current context resumes after menu finishes. If you wish to jump to an entirely different controller, use pass. Menu will return :failed if failure was reached, or :done if a match was executed.

@param [Object] args A list of outputs to play, as accepted by play @param [Hash] options Options to use for the menu @option options [Integer] :tries Number of tries allowed before failure @option options [Integer] :timeout Timeout in seconds before the first and between each input digit @option options [Boolean] :interruptible If the prompt should be interruptible or not. Defaults to true

@return [Result] a result object from which the response and status may be established

@see Output#play @see CallController#pass

play_sound_files_for_menu(menu_instance, sound_files) click to toggle source

@private

# File lib/adhearsion/call_controller/input.rb, line 197
def play_sound_files_for_menu(menu_instance, sound_files)
  digit = nil
  if sound_files.any? && menu_instance.digit_buffer_empty?
    if menu_instance.interruptible
      digit = interruptible_play(*sound_files, renderer: menu_instance.renderer)
    else
      play(*sound_files, renderer: menu_instance.renderer)
    end
  end
  digit || wait_for_digit(menu_instance.timeout)
end
wait_for_digit(timeout = 1) click to toggle source

Waits for a single digit and returns it, or returns nil if nothing was pressed

@param [Integer] timeout the timeout to wait before returning, in seconds. nil or -1 mean no timeout. @return [String, nil] the pressed key, or nil if timeout was reached.

@private

# File lib/adhearsion/call_controller/input.rb, line 217
def wait_for_digit(timeout = 1)
  timeout = nil if timeout == -1
  timeout *= 1_000 if timeout
  input_component = execute_component_and_await_completion Punchblock::Component::Input.new :mode => :dtmf,
    :initial_timeout => timeout,
    :inter_digit_timeout => timeout,
      :grammar => {
        :value => grammar_accept.to_s
    }

  reason = input_component.complete_event.reason
  result = reason.respond_to?(:utterance) ? reason.utterance : nil
  parse_dtmf result
end