Module: Adhearsion::CallController::Input

Included in:
Adhearsion::CallController
Defined in:
lib/adhearsion/call_controller/input.rb

Defined Under Namespace

Classes: Result

Instance Method Summary collapse

Instance Method Details

#ask(*args, options, &block) ⇒ Result

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

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.

Examples:

A basic digit collection:

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

Parameters:

  • args (Object, Array<Object>)

    A list of outputs to play, as accepted by #play

  • options (Hash)

    Options to use for the menu

Options Hash (options):

  • :interruptible (Boolean)

    If the prompt should be interruptible or not. Defaults to true

  • :limit (Integer)

    Digit limit (causes collection to cease after a specified number of digits have been collected)

  • :timeout (Integer)

    Timeout in seconds before the first and between each input digit

  • :terminator (String)

    Digit to terminate input

Returns:

  • (Result)

    a result object from which the #response and #status may be established

See Also:



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# 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

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

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.

Examples:

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

Parameters:

  • args (Object)

    A list of outputs to play, as accepted by #play

  • options (Hash)

    Options to use for the menu

Options Hash (options):

  • :tries (Integer)

    Number of tries allowed before failure

  • :timeout (Integer)

    Timeout in seconds before the first and between each input digit

  • :interruptible (Boolean)

    If the prompt should be interruptible or not. Defaults to true

Returns:

  • (Result)

    a result object from which the #response and #status may be established

See Also:



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/adhearsion/call_controller/input.rb', line 136

def menu(*args, options, &block)
  logger.warn "This implementation of #menu 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, &block
  menu_instance.validate
  result_of_menu = nil

  catch :finish do
    until MenuDSL::Menu::MenuResultDone === result_of_menu
      if menu_instance.should_continue?
        result_of_menu = menu_instance.continue
      else
        logger.debug "Menu failed to get valid input. Calling \"failure\" hook."
        menu_instance.execute_failure_hook
        throw :finish
      end

      case result_of_menu
      when MenuDSL::Menu::MenuResultInvalid
        logger.debug "Menu received invalid input. Calling \"invalid\" hook and restarting."
        menu_instance.execute_invalid_hook
        menu_instance.restart!
        result_of_menu = nil
      when MenuDSL::Menu::MenuGetAnotherDigit
        next_digit = play_sound_files_for_menu menu_instance, sound_files
        if next_digit
          menu_instance << next_digit
        else
          case result_of_menu
          when MenuDSL::Menu::MenuGetAnotherDigitOrFinish
            jump_to result_of_menu.match_object, :extension => result_of_menu.new_extension
            throw :finish
          when MenuDSL::Menu::MenuGetAnotherDigitOrTimeout
            logger.debug "Menu timed out. Calling \"timeout\" hook and restarting."
            menu_instance.execute_timeout_hook
            menu_instance.restart!
            result_of_menu = nil
          end
        end
      when MenuDSL::Menu::MenuResultFound
        logger.debug "Menu received valid input (#{result_of_menu.new_extension}). Calling the matching hook."
        jump_to result_of_menu.match_object, :extension => result_of_menu.new_extension
        throw :finish
      end
    end
  end

  Result.new.tap do |result|
    result.response = menu_instance.result
    result.status   = menu_instance.status
    result.menu     = menu_instance
  end
end