Class: Signalwire::Relay::Calling::Call

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Blade::EventHandler, Common, Logger, CallConvenienceMethods, CallDetectMethods
Defined in:
lib/signalwire/relay/calling/call.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from CallDetectMethods

#detect, #detect!, #detect_digit, #detect_digit!, #detect_fax, #detect_fax!, #detect_human, #detect_human!, #detect_machine, #detect_machine!, #prepare_fax_arguments

Methods included from CallConvenienceMethods

#play_audio, #play_audio!, #play_silence, #play_silence!, #play_tts, #play_tts!, #prompt_audio, #prompt_audio!, #prompt_silence, #prompt_silence!, #prompt_tts, #prompt_tts!, #wait_for_answered, #wait_for_ended, #wait_for_ending, #wait_for_ringing

Methods included from Blade::EventHandler

#broadcast

Methods included from Logger

#level=, #logger, logger

Constructor Details

#initialize(client, call_options) ⇒ Call

Returns a new instance of Call.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/signalwire/relay/calling/call.rb', line 23

def initialize(client, call_options)
  @client = client

  @id = call_options[:call_id]
  setup_call_options(call_options)
  @type = @device[:type]

  @from = @device[:params][:from_number]
  @to = @device[:params][:to_number]
  @timeout = @device[:params][:timeout] || 30
  @tag = SecureRandom.uuid

  @components = []

  setup_call_event_handlers
end

Instance Attribute Details

#busyObject (readonly)

Returns the value of attribute busy.



14
15
16
# File 'lib/signalwire/relay/calling/call.rb', line 14

def busy
  @busy
end

#clientObject (readonly)

Returns the value of attribute client.



14
15
16
# File 'lib/signalwire/relay/calling/call.rb', line 14

def client
  @client
end

#componentsObject (readonly)

Returns the value of attribute components.



14
15
16
# File 'lib/signalwire/relay/calling/call.rb', line 14

def components
  @components
end

#contextObject (readonly)

Returns the value of attribute context.



14
15
16
# File 'lib/signalwire/relay/calling/call.rb', line 14

def context
  @context
end

#deviceObject (readonly)

Returns the value of attribute device.



14
15
16
# File 'lib/signalwire/relay/calling/call.rb', line 14

def device
  @device
end

#failedObject (readonly)

Returns the value of attribute failed.



14
15
16
# File 'lib/signalwire/relay/calling/call.rb', line 14

def failed
  @failed
end

#fromObject (readonly)

Returns the value of attribute from.



14
15
16
# File 'lib/signalwire/relay/calling/call.rb', line 14

def from
  @from
end

#node_idObject (readonly)

Returns the value of attribute node_id.



14
15
16
# File 'lib/signalwire/relay/calling/call.rb', line 14

def node_id
  @node_id
end

#peer_callObject (readonly)

Returns the value of attribute peer_call.



14
15
16
# File 'lib/signalwire/relay/calling/call.rb', line 14

def peer_call
  @peer_call
end

#previous_stateObject (readonly)

Returns the value of attribute previous_state.



14
15
16
# File 'lib/signalwire/relay/calling/call.rb', line 14

def previous_state
  @previous_state
end

#stateObject (readonly)

Returns the value of attribute state.



14
15
16
# File 'lib/signalwire/relay/calling/call.rb', line 14

def state
  @state
end

#tagObject (readonly)

Returns the value of attribute tag.



14
15
16
# File 'lib/signalwire/relay/calling/call.rb', line 14

def tag
  @tag
end

#timeoutObject (readonly)

Returns the value of attribute timeout.



14
15
16
# File 'lib/signalwire/relay/calling/call.rb', line 14

def timeout
  @timeout
end

#toObject (readonly)

Returns the value of attribute to.



14
15
16
# File 'lib/signalwire/relay/calling/call.rb', line 14

def to
  @to
end

#typeObject (readonly)

Returns the value of attribute type.



14
15
16
# File 'lib/signalwire/relay/calling/call.rb', line 14

def type
  @type
end

Class Method Details

.from_event(client, event) ⇒ Object



19
20
21
# File 'lib/signalwire/relay/calling/call.rb', line 19

def self.from_event(client, event)
  new(client, event.call_params)
end

Instance Method Details

#active?Boolean

Returns:

  • (Boolean)


94
95
96
# File 'lib/signalwire/relay/calling/call.rb', line 94

def active?
  !ended?
end

#answerObject



102
103
104
105
106
# File 'lib/signalwire/relay/calling/call.rb', line 102

def answer
  answer_component = Signalwire::Relay::Calling::Answer.new(call: self)
  answer_component.wait_for(Relay::CallState::ANSWERED, Relay::CallState::ENDING, Relay::CallState::ENDED)
  AnswerResult.new(component: answer_component)
end

#answered?Boolean

Returns:

  • (Boolean)


86
87
88
# File 'lib/signalwire/relay/calling/call.rb', line 86

def answered?
  @state == 'answered'
end

#call_match_event(event) ⇒ Object



76
77
78
79
80
# File 'lib/signalwire/relay/calling/call.rb', line 76

def call_match_event(event)
  event.event_type.match(/calling\.call/) &&
    !event.event_type.match(/receive/) &&
    (event.call_id == id || event.call_params[:tag] == tag)
end

#change_call_state(event_params) ⇒ Object



55
56
57
58
59
60
61
62
# File 'lib/signalwire/relay/calling/call.rb', line 55

def change_call_state(event_params)
  call_state = event_params[:params]
  @previous_state = @state
  @state = call_state[:call_state]
  broadcast :call_state_change, previous_state: @previous_state, state: @state
  broadcast @state.to_sym, previous_state: @previous_state, state: @state
  finish_call(event_params) if @state == Relay::CallState::ENDED
end

#change_connect_state(new_connect_state) ⇒ Object



70
71
72
73
74
# File 'lib/signalwire/relay/calling/call.rb', line 70

def change_connect_state(new_connect_state)
  @previous_connect_state = @connect_state
  @connect_state = new_connect_state
  broadcast :connect_state_change, previous_state: @previous_connect_state, state: @connect_state
end

#connect(devices_object) ⇒ Object



138
139
140
141
142
# File 'lib/signalwire/relay/calling/call.rb', line 138

def connect(devices_object)
  component = Connect.new(call: self, devices: devices_object)
  component.wait_for(Relay::CallConnectState::CONNECTED, Relay::CallConnectState::FAILED)
  ConnectResult.new(component: component)
end

#connect!(devices_object) ⇒ Object



144
145
146
147
148
# File 'lib/signalwire/relay/calling/call.rb', line 144

def connect!(devices_object)
  component = Connect.new(call: self, devices: devices_object)
  component.execute
  ConnectAction.new(component: component)
end

#dialObject



168
169
170
171
172
# File 'lib/signalwire/relay/calling/call.rb', line 168

def dial
  dial_component = Signalwire::Relay::Calling::Dial.new(call: self)
  dial_component.wait_for(Relay::CallState::ANSWERED, Relay::CallState::ENDING, Relay::CallState::ENDED)
  DialResult.new(component: dial_component)
end

#ended?Boolean

Returns:

  • (Boolean)


90
91
92
# File 'lib/signalwire/relay/calling/call.rb', line 90

def ended?
  @state == 'ending' || @state == 'ended'
end

#fax_receiveObject



174
175
176
177
178
# File 'lib/signalwire/relay/calling/call.rb', line 174

def fax_receive
  component = Signalwire::Relay::Calling::FaxReceive.new(call: self)
  component.wait_for(Relay::CallFaxState::ERROR, Relay::CallFaxState::FINISHED)
  FaxResult.new(component: component)
end

#fax_receive!Object



180
181
182
183
184
# File 'lib/signalwire/relay/calling/call.rb', line 180

def fax_receive!
  component = Signalwire::Relay::Calling::FaxReceive.new(call: self)
  component.execute
  FaxAction.new(component: component)
end

#fax_send(document:, identity: nil, header: nil) ⇒ Object



186
187
188
189
190
# File 'lib/signalwire/relay/calling/call.rb', line 186

def fax_send(document: , identity: nil, header: nil)
  component = Signalwire::Relay::Calling::FaxSend.new(call: self, document: document, identity: identity, header: header)
  component.wait_for(Relay::CallFaxState::ERROR, Relay::CallFaxState::FINISHED)
  FaxResult.new(component: component)
end

#fax_send!(document:, identity: nil, header: nil) ⇒ Object



192
193
194
195
196
# File 'lib/signalwire/relay/calling/call.rb', line 192

def fax_send!(document: , identity: nil, header: nil)
  component = Signalwire::Relay::Calling::FaxSend.new(call: self, document: document, identity: identity, header: header)
  component.execute
  FaxAction.new(component: component)
end

#finish_call(params) ⇒ Object



233
234
235
236
237
238
239
# File 'lib/signalwire/relay/calling/call.rb', line 233

def finish_call(params)
  terminate_components(params)
  client.calling.end_call(id)
  @busy = true if params[:reason] == Relay::DisconnectReason::BUSY
  @failed = true if params[:reason] == Relay::DisconnectReason::FAILED
  broadcast :ended, previous_state: @previous_state, state: @state
end

#hangup(reason = 'hangup') ⇒ Object



162
163
164
165
166
# File 'lib/signalwire/relay/calling/call.rb', line 162

def hangup(reason = 'hangup')
  hangup_component = Signalwire::Relay::Calling::Hangup.new(call: self, reason: reason)
  hangup_component.wait_for(Relay::CallState::ENDED)
  HangupResult.new(component: hangup_component)
end

#idObject



82
83
84
# File 'lib/signalwire/relay/calling/call.rb', line 82

def id
  @id ||= SecureRandom.uuid
end

#peerObject



98
99
100
# File 'lib/signalwire/relay/calling/call.rb', line 98

def peer
  @client.calling.find_call_by_id(@peer_call[:call_id]) if @peer_call && @peer_call[:call_id]
end

#play(play_object) ⇒ Object



108
109
110
111
112
# File 'lib/signalwire/relay/calling/call.rb', line 108

def play(play_object)
  play_component = Signalwire::Relay::Calling::Play.new(call: self, play: play_object)
  play_component.wait_for(Relay::CallPlayState::FINISHED, Relay::CallPlayState::ERROR)
  PlayResult.new(component: play_component)
end

#play!(play_object) ⇒ Object



114
115
116
117
118
# File 'lib/signalwire/relay/calling/call.rb', line 114

def play!(play_object)
  play_component = Signalwire::Relay::Calling::Play.new(call: self, play: play_object)
  play_component.execute
  PlayAction.new(component: play_component)
end

#prompt(collect_p = nil, play_p = nil, collect: nil, play: nil) ⇒ Object



120
121
122
123
124
125
126
127
128
# File 'lib/signalwire/relay/calling/call.rb', line 120

def prompt(collect_p = nil, play_p = nil, collect: nil, play: nil)
  set_parameters(binding, i{collect play}, i{collect play})

  component = Prompt.new(call: self, collect: collect, play: play)
  component.wait_for(Relay::CallPromptState::ERROR, Relay::CallPromptState::NO_INPUT, 
                     Relay::CallPromptState::NO_MATCH, Relay::CallPromptState::DIGIT,
                     Relay::CallPromptState::SPEECH)
  PromptResult.new(component: component)
end

#prompt!(collect_p = nil, play_p = nil, collect: nil, play: nil) ⇒ Object



130
131
132
133
134
135
136
# File 'lib/signalwire/relay/calling/call.rb', line 130

def prompt!(collect_p = nil, play_p = nil, collect: nil, play: nil)
  set_parameters(binding, i{collect play}, i{collect play})

  component = Prompt,new(call: self, collect: collect, play: play)
  component.execute
  PromptAction.new(component: component)
end

#record(record_object) ⇒ Object



150
151
152
153
154
# File 'lib/signalwire/relay/calling/call.rb', line 150

def record(record_object)
  component = Record.new(call: self, record: record_object)
  component.wait_for(Relay::CallRecordState::NO_INPUT, Relay::CallRecordState::FINISHED)
  RecordResult.new(component: component)
end

#record!(record_object) ⇒ Object



156
157
158
159
160
# File 'lib/signalwire/relay/calling/call.rb', line 156

def record!(record_object)
  component = Record.new(call: self, record: record_object)
  component.execute
  RecordAction.new(component: component)
end

#register_component(component) ⇒ Object



223
224
225
# File 'lib/signalwire/relay/calling/call.rb', line 223

def register_component(component)
  @components << component
end

#setup_call_event_handlersObject



40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/signalwire/relay/calling/call.rb', line 40

def setup_call_event_handlers
  @client.on(:event, proc { |evt| call_match_event(evt) }) do |event|
    case event.event_type
    when 'calling.call.connect'
      change_connect_state(event.call_params[:connect_state])
    when 'calling.call.state'
      change_call_state(event.event_params)
    end

    update_call_fields(event.call_params)
    broadcast :event, event
    broadcast :state_change, event
  end
end

#tap_media(tap:, device:) ⇒ Object



198
199
200
201
202
# File 'lib/signalwire/relay/calling/call.rb', line 198

def tap_media(tap:, device:)
  component = Signalwire::Relay::Calling::Tap.new(call: self, tap: tap, device: device)
  component.wait_for(Relay::CallTapState::FINISHED)
  TapResult.new(component: component)
end

#tap_media!(tap:, device:) ⇒ Object



204
205
206
207
208
# File 'lib/signalwire/relay/calling/call.rb', line 204

def tap_media!(tap:, device:)
  component = Signalwire::Relay::Calling::Tap.new(call: self, tap: tap, device: device)
  component.execute
  TapAction.new(component: component)
end

#terminate_components(params = {}) ⇒ Object



227
228
229
230
231
# File 'lib/signalwire/relay/calling/call.rb', line 227

def terminate_components(params = {})
  @components.each do |comp|
    comp.terminate(params) unless component.completed
  end
end

#update_call_fields(call_state) ⇒ Object



64
65
66
67
68
# File 'lib/signalwire/relay/calling/call.rb', line 64

def update_call_fields(call_state)
  @id = call_state[:call_id] if call_state[:call_id]
  @node_id = call_state[:node_id] if call_state[:node_id]
  @peer_call = call_state[:peer] if call_state[:peer]
end

#wait_for(*events) ⇒ Object



210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/signalwire/relay/calling/call.rb', line 210

def wait_for(*events)
  events = [Relay::CallState::ENDED] if events.empty?
  
  current_state_index = Relay::CALL_STATES.find_index(@state)
  max_index = events.map { |evt| Relay::CALL_STATES.find_index(evt) }.max

  return true if current_state_index >= max_index

  component = Await.new(call: self)
  component.wait_for(*events)
  component.successful
end