This article is part 3 of a series. If you have not already, check out Part 1: In-Call Apps with Adhearsion & Matrioska and Part 2: In-Call Apps: Please Hold
That's all well and good, but a 5 second hold is kind of restrictive, don't you think? Lets add a menu to the in-call app which gives the user the choice of rejoining or hanging up the remote party and continuing to work through InboundController.
require 'matrioska/dial_with_apps'
class InCallAppController < Adhearsion::CallController
  def run
    menu 'Press 1 to return to the call, or 2 to hang up on the other person.' do
      match(1) { main_dial.rejoin }
      match(2) { main_dial.cleanup_calls }
      timeout { say 'Sorry, you took too long' }
      invalid { say 'Sorry, that was an invalid choice' }
      failure { say 'Sorry, you failed to select a valid option' }
    end
  end
  private
  def main_dial
    metadata['current_dial']
  end
end
class InboundController < Adhearsion::CallController
  include Matrioska::DialWithApps
  def run
    dial_with_local_apps 'sip:5201996@localphone.com' do |runner, dial|
      runner.map_app '1' do
        place_on_hold dial
      end
    end
    say "Thanks. It seems we're all done. Goodbye."
  end
  private
  def place_on_hold(dial)
    logger.info "Splitting calls"
    blocker = Celluloid::Condition.new
    dial.split main: InCallAppController, others: HoldMusicController, main_callback: ->(call) { blocker.broadcast }
    blocker.wait # This prevents the Matrioska listener from starting again until the calls are rejoined
  end
end
Here, we make use of Dial#cleanup_calls which will hangup outbound calls created by the dial operation. When these calls are disconnected, the dial operation in InboundController will return, and further logic may be applied to the A leg of the call (here we simply play back a message).
Well, that was easy. Now we have interactive hold, we can start to add some additional features to the app. More to come next week!
Ben Langfeld 18 October 2013 Rio de Janeiro, Brasil