Module: Adhearsion::CallController::Dial

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

Defined Under Namespace

Classes: DialStatus

Instance Method Summary (collapse)

Instance Method Details

- (DialStatus) dial(to[String], options = {}) - (DialStatus) dial(to[Array], options = {}) - (DialStatus) dial(to[Hash], options = {})

Dial one or more third parties and join one to this call

Examples:

Make a call to the PSTN using my SIP provider for VoIP termination

dial "SIP/19095551001@my.sip.voip.terminator.us"

Make 3 simulataneous calls to the SIP extensions, try for 15 seconds and use the callerid for this call specified by the variable my_callerid

dial %w{SIP/jay-desk-650 SIP/jay-desk-601 SIP/jay-desk-601-2}, :for => 15.seconds, :from => my_callerid

Make a call using the IAX provider to the PSTN

dial "IAX2/my.id@voipjet/19095551234", :from => "John Doe <9095551234>"

Overloads:

  • - (DialStatus) dial(to[String], options = {})

    Parameters:

    • to (String)

      The target URI to dial. You must specify a properly formatted string that your VoIP platform understands. eg. sip:foo@bar.com, tel:+14044754840, or SIP/foo/1234

    • options (Hash)

      see below

  • - (DialStatus) dial(to[Array], options = {})

    Parameters:

    • to (Array<String>)

      Target URIs to dial. Each will be called with the same options simultaneously. The first call answered is joined, the others are hung up.

    • options (Hash)

      see below

  • - (DialStatus) dial(to[Hash], options = {})

    Parameters:

    • to (Hash<String => Hash>)

      Target URIs to dial, mapped to their per-target options overrides. Each will be called with the same options simultaneously. The first call answered is joined, the others are hung up. Each calls options are deep-merged with the global options hash.

    • options (Hash)

      see below

Parameters:

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

    a customizable set of options

Options Hash (options):

  • :from (String)

    the caller id 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.

  • :for (Numeric)

    this option can be thought of best as a timeout. i.e. timeout after :for if no one answers the call

Returns:

  • (DialStatus)

    the status of the dial operation



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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/adhearsion/call_controller/dial.rb', line 45

def dial(to, options = {}, latch = nil)
  targets = to.respond_to?(:has_key?) ? to : Array(to)

  status = DialStatus.new

  latch ||= CountDownLatch.new targets.size

  call.on_end { |_| latch.countdown! until latch.count == 0 }

  _for = options.delete :for
  options[:timeout] ||= _for if _for

  options[:from] ||= call.from

  calls = targets.map do |target, specific_options|
    new_call = OutboundCall.new

    new_call.on_answer do |event|
      calls.each do |call_to_hangup, _|
        begin
          next if call_to_hangup.id == new_call.id
          logger.debug "#dial hanging up call #{call_to_hangup.id} because this call has been answered by another channel"
          call_to_hangup.hangup
        rescue Celluloid::DeadActorError
          # This actor may previously have been shut down due to the call ending
        end
      end

      new_call.register_event_handler Punchblock::Event::Unjoined, :call_id => call.id do |unjoined|
        new_call["dial_countdown_#{call.id}"] = true
        latch.countdown!
        throw :pass
      end

      logger.debug "#dial joining call #{new_call.id} to #{call.id}"
      new_call.join call
      status.answer!
    end

    new_call.on_end do |event|
      latch.countdown! unless new_call["dial_countdown_#{call.id}"]

      case event.reason
      when :error
        status.error!
      end
    end

    [new_call, target, specific_options]
  end

  calls.map! do |call, target, specific_options|
    local_options = options.dup.deep_merge specific_options if specific_options
    call.dial target, (local_options || options)
    call
  end

  status.calls = calls

  no_timeout = latch.wait options[:timeout]
  status.timeout! unless no_timeout

  logger.debug "#dial finished. Hanging up #{calls.size} outbound calls: #{calls.map(&:id).join ", "}."
  calls.each do |outbound_call|
    begin
      outbound_call.hangup
    rescue Celluloid::DeadActorError
      # This actor may previously have been shut down due to the call ending
    end
  end

  status
end