signalwire 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/examples/relay/fax/fax_receive.rb +22 -0
  4. data/examples/relay/fax/fax_send.rb +22 -0
  5. data/examples/relay/inbound_consumer.rb +1 -1
  6. data/examples/relay/inbound_dial.rb +1 -1
  7. data/examples/relay/messaging/messaging_receive.rb +30 -0
  8. data/examples/relay/messaging/messaging_send.rb +23 -0
  9. data/examples/relay/outbound_detect.rb +27 -0
  10. data/examples/relay/outbound_tap.rb +30 -0
  11. data/examples/relay/tasking/tasking_receive.rb +23 -0
  12. data/examples/relay/tasking/tasking_send.rb +13 -0
  13. data/lib/signalwire/relay.rb +18 -0
  14. data/lib/signalwire/relay/calling.rb +2 -12
  15. data/lib/signalwire/relay/calling/action/detect_action.rb +15 -0
  16. data/lib/signalwire/relay/calling/action/fax_action.rb +15 -0
  17. data/lib/signalwire/relay/calling/action/tap_action.rb +17 -0
  18. data/lib/signalwire/relay/calling/call.rb +37 -0
  19. data/lib/signalwire/relay/calling/call_detect_methods.rb +110 -0
  20. data/lib/signalwire/relay/calling/component/base_fax.rb +40 -0
  21. data/lib/signalwire/relay/calling/component/detect.rb +62 -0
  22. data/lib/signalwire/relay/calling/component/fax_receive.rb +15 -0
  23. data/lib/signalwire/relay/calling/component/fax_send.rb +28 -0
  24. data/lib/signalwire/relay/calling/component/tap.rb +61 -0
  25. data/lib/signalwire/relay/calling/result/detect_result.rb +7 -0
  26. data/lib/signalwire/relay/calling/result/fax_result.rb +7 -0
  27. data/lib/signalwire/relay/calling/result/tap_result.rb +7 -0
  28. data/lib/signalwire/relay/client.rb +27 -1
  29. data/lib/signalwire/relay/constants.rb +45 -0
  30. data/lib/signalwire/relay/consumer.rb +21 -13
  31. data/lib/signalwire/relay/event.rb +4 -0
  32. data/lib/signalwire/relay/messaging.rb +58 -0
  33. data/lib/signalwire/relay/messaging/message.rb +32 -0
  34. data/lib/signalwire/relay/messaging/send_result.rb +25 -0
  35. data/lib/signalwire/relay/task.rb +45 -0
  36. data/lib/signalwire/version.rb +1 -1
  37. metadata +26 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4d68736f7bf37f324c9f85a604165cd994d45974d73741c90cd9290e4ef63b4c
4
- data.tar.gz: f47bcfe838a3ce0576d7f2ba199f415ab5a36f23d07feef554ad3c340c20d015
3
+ metadata.gz: 85b3509109fd09ce52f1f579294b3723c4bfc63337584dfc753c491645221868
4
+ data.tar.gz: 35cf3f667c586fc788136eec75930785c360315594246a3dd9b0800123f86ee1
5
5
  SHA512:
6
- metadata.gz: 782c53f901d1bf44cb4bf9dd523a6268bf4bd6c165aa39223e054501f75092524e47a92ce97acb6b247cf2ad89f311fb44722bb27c5db82fbf6da7c9e88cd65e
7
- data.tar.gz: 0ace788a9baf5c7c9aee04bcae89478777bdbbd7f107040da98687e5bb211d0ecccc8222fb11e6ce97037c8d773c61914538df43ab40eeb0360a1aab7358ccca
6
+ metadata.gz: 5d9261efe1e472198348e53f8f7805baa24f50c4c6282e510200b84860bb17919a7bc0b0059b73c6b9c8b078eb854592e4d88a1bd6424598a433afa44f00ab20
7
+ data.tar.gz: 18ce795d935a76bad953e7128d98932b5fc24353d8d842d639628ba10bb9f69f0ddcc91fadb3c4d2443809190ecc1a2851641e03f232b196652a7b818ad03016
@@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file.
3
3
 
4
4
  This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5
5
 
6
+ ## [2.1.0] 2019-07-29
7
+ ### Added
8
+ - Tap API for Relay
9
+ - `:task` broadcast from client
10
+ - `Relay::Task` and `on_task` handler for `Consumer`
11
+ - Fax API for Relay
12
+ - `Detect` API for Relay
13
+ - Messaging API for Relay
14
+ ### Changed
15
+ - Changed `SIGNALWIRE_ACCOUNT` environment variable to `SIGNALWIRE_PROJECT_KEY` to match UI
16
+
6
17
  ## [2.0.0] - 2019-07-16
7
18
  ### Added
8
19
  - Connection Retry upon disconnect.
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
4
+ %w[
5
+ bundler/setup
6
+ signalwire
7
+ ].each { |f| require f }
8
+
9
+ Signalwire::Logger.logger.level = ::Logger::DEBUG
10
+
11
+ class MyConsumer < Signalwire::Relay::Consumer
12
+ contexts ['incoming']
13
+
14
+ def on_incoming_call(call)
15
+ call.answer
16
+ fax_result = call.fax_receive
17
+ logger.debug "Received a fax: #{fax_result.document} that is #{fax_result.pages} pages long."
18
+ call.hangup
19
+ end
20
+ end
21
+
22
+ MyConsumer.new.run
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
4
+ %w[
5
+ bundler/setup
6
+ signalwire
7
+ ].each { |f| require f }
8
+
9
+ Signalwire::Logger.logger.level = ::Logger::DEBUG
10
+
11
+ class OutboundConsumer < Signalwire::Relay::Consumer
12
+ def ready
13
+ call = client.calling.new_call(from: ENV['FAX_FROM_NUMBER'], to: ENV['FAX_TO_NUMBER'])
14
+ call.dial
15
+ call.fax_send(document: "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf")
16
+ rescue StandardError => e
17
+ logger.error e.inspect
18
+ logger.error e.backtrace
19
+ end
20
+ end
21
+
22
+ OutboundConsumer.new.run
@@ -7,7 +7,7 @@ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
7
7
  ].each { |f| require f }
8
8
 
9
9
  # Setup your ENV with:
10
- # SIGNALWIRE_ACCOUNT=YOUR_SIGNALWIRE_ACCOUNT_ID
10
+ # SIGNALWIRE_PROJECT_KEY=YOUR_SIGNALWIRE_ACCOUNT_ID
11
11
  # SIGNALWIRE_TOKEN=YOUR_SIGNALWIRE_ACCOUNT_TOKEN
12
12
  #
13
13
  Signalwire::Logger.logger.level = ::Logger::DEBUG
@@ -7,7 +7,7 @@ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
7
7
  ].each { |f| require f }
8
8
 
9
9
  # Setup your ENV with:
10
- # SIGNALWIRE_ACCOUNT=YOUR_SIGNALWIRE_ACCOUNT_ID
10
+ # SIGNALWIRE_PROJECT_KEY=YOUR_SIGNALWIRE_ACCOUNT_ID
11
11
  # SIGNALWIRE_TOKEN=YOUR_SIGNALWIRE_ACCOUNT_TOKEN
12
12
  #
13
13
  # Set logging to debug for testing
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
4
+ %w[
5
+ bundler/setup
6
+ signalwire
7
+ ].each { |f| require f }
8
+
9
+ # Set logging to debug for testing
10
+ Signalwire::Logger.logger.level = ::Logger::DEBUG
11
+
12
+ class MessageSendConsumer < Signalwire::Relay::Consumer
13
+ contexts ['incoming']
14
+
15
+ def on_incoming_message(message)
16
+ logger.info "Received message from #{message.from}: #{message.body}"
17
+ rescue StandardError => e
18
+ logger.error e.inspect
19
+ logger.error e.backtrace
20
+ end
21
+
22
+ def on_message_state_change(message)
23
+ logger.info "Received state change: #{message.id} #{message.state}"
24
+ rescue StandardError => e
25
+ logger.error e.inspect
26
+ logger.error e.backtrace
27
+ end
28
+ end
29
+
30
+ MessageSendConsumer.new.run
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
4
+ %w[
5
+ bundler/setup
6
+ signalwire
7
+ ].each { |f| require f }
8
+
9
+ # Set logging to debug for testing
10
+ Signalwire::Logger.logger.level = ::Logger::DEBUG
11
+
12
+ class MessageSendConsumer < Signalwire::Relay::Consumer
13
+ def ready
14
+ logger.debug "Sending an SMS to #{ENV['TO_NUMBER']}"
15
+ result = client.messaging.send(from: ENV['FROM_NUMBER'], to: ENV['TO_NUMBER'], context: 'incoming', body: 'hello world!')
16
+ logger.debug "message id #{result.message_id} was successfully sent" if result.successful
17
+ rescue StandardError => e
18
+ logger.error e.inspect
19
+ logger.error e.backtrace
20
+ end
21
+ end
22
+
23
+ MessageSendConsumer.new.run
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
4
+ %w[
5
+ bundler/setup
6
+ signalwire
7
+ ].each { |f| require f }
8
+
9
+ # Set logging to debug for testing
10
+ Signalwire::Logger.logger.level = ::Logger::DEBUG
11
+
12
+ class OutboundConsumer < Signalwire::Relay::Consumer
13
+ def ready
14
+ logger.info 'Dialing out'
15
+ call = client.calling.new_call(from: ENV['FROM_NUMBER'], to: ENV['TO_NUMBER'])
16
+ call.dial
17
+ result = call.detect_digit(digits: "345", timeout: 10)
18
+
19
+ logger.debug "User pressed #{result.result}"
20
+ call.hangup
21
+ rescue StandardError => e
22
+ logger.error e.inspect
23
+ logger.error e.backtrace
24
+ end
25
+ end
26
+
27
+ OutboundConsumer.new.run
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
4
+ %w[
5
+ bundler/setup
6
+ signalwire
7
+ ].each { |f| require f }
8
+
9
+ # Set logging to debug for testing
10
+ Signalwire::Logger.logger.level = ::Logger::DEBUG
11
+
12
+ class OutboundConsumer < Signalwire::Relay::Consumer
13
+ def ready
14
+ logger.info 'Dialing out'
15
+ call = client.calling.new_call(from: ENV['FROM_NUMBER'], to: ENV['TO_NUMBER'])
16
+ call.dial
17
+
18
+ tap_arguments = { type: "audio", params: { direction: "listen" } }
19
+ device_arguments = { type: "rtp", params: { addr: "127.0.0.1", port: 1234 } }
20
+
21
+ call.tap_media(tap: tap_arguments, device: device_arguments)
22
+
23
+ call.hangup
24
+ rescue StandardError => e
25
+ logger.error e.inspect
26
+ logger.error e.backtrace
27
+ end
28
+ end
29
+
30
+ OutboundConsumer.new.run
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
4
+ %w[
5
+ bundler/setup
6
+ signalwire
7
+ ].each { |f| require f }
8
+
9
+ # Setup your ENV with:
10
+ # SIGNALWIRE_PROJECT_KEY=YOUR_SIGNALWIRE_ACCOUNT_ID
11
+ # SIGNALWIRE_TOKEN=YOUR_SIGNALWIRE_ACCOUNT_TOKEN
12
+ #
13
+ Signalwire::Logger.logger.level = ::Logger::DEBUG
14
+
15
+ class MyConsumer < Signalwire::Relay::Consumer
16
+ contexts ['incoming']
17
+
18
+ def on_task(task)
19
+ logger.debug "Received #{task.message}"
20
+ end
21
+ end
22
+
23
+ MyConsumer.new.run
@@ -0,0 +1,13 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
2
+ %w[
3
+ bundler/setup
4
+ signalwire/relay/task
5
+ ].each { |f| require f }
6
+
7
+ task = Signalwire::Relay::Task.new(
8
+ project: ENV['SIGNALWIRE_PROJECT_KEY'],
9
+ token: ENV['SIGNALWIRE_TOKEN'],
10
+ host: ENV['SIGNALWIRE_HOST']
11
+ )
12
+
13
+ task.deliver(context: 'incoming', message: { foo: 'bar' })
@@ -11,30 +11,48 @@ require 'signalwire/relay/consumer'
11
11
 
12
12
  require 'signalwire/relay/calling'
13
13
  require 'signalwire/relay/calling/call_convenience_methods'
14
+ require 'signalwire/relay/calling/call_detect_methods'
14
15
  require 'signalwire/relay/calling/call'
15
16
 
17
+ require 'signalwire/relay/task'
18
+
16
19
  require 'signalwire/relay/calling/action'
17
20
  require 'signalwire/relay/calling/action/connect_action'
21
+ require 'signalwire/relay/calling/action/detect_action'
18
22
  require 'signalwire/relay/calling/action/play_action'
19
23
  require 'signalwire/relay/calling/action/prompt_action'
20
24
  require 'signalwire/relay/calling/action/record_action'
25
+ require 'signalwire/relay/calling/action/fax_action'
26
+ require 'signalwire/relay/calling/action/tap_action'
21
27
 
22
28
  require 'signalwire/relay/calling/result'
23
29
  require 'signalwire/relay/calling/result/answer_result'
24
30
  require 'signalwire/relay/calling/result/connect_result'
31
+ require 'signalwire/relay/calling/result/detect_result'
25
32
  require 'signalwire/relay/calling/result/dial_result'
26
33
  require 'signalwire/relay/calling/result/hangup_result'
27
34
  require 'signalwire/relay/calling/result/play_result'
28
35
  require 'signalwire/relay/calling/result/prompt_result'
29
36
  require 'signalwire/relay/calling/result/record_result'
37
+ require 'signalwire/relay/calling/result/fax_result'
38
+ require 'signalwire/relay/calling/result/tap_result'
30
39
 
31
40
  require 'signalwire/relay/calling/component'
32
41
  require 'signalwire/relay/calling/control_component'
33
42
  require 'signalwire/relay/calling/component/answer'
34
43
  require 'signalwire/relay/calling/component/connect'
44
+ require 'signalwire/relay/calling/component/detect'
35
45
  require 'signalwire/relay/calling/component/dial'
36
46
  require 'signalwire/relay/calling/component/hangup'
37
47
  require 'signalwire/relay/calling/component/play'
38
48
  require 'signalwire/relay/calling/component/prompt'
39
49
  require 'signalwire/relay/calling/component/record'
40
50
  require 'signalwire/relay/calling/component/await'
51
+ require 'signalwire/relay/calling/component/base_fax'
52
+ require 'signalwire/relay/calling/component/fax_send'
53
+ require 'signalwire/relay/calling/component/fax_receive'
54
+ require 'signalwire/relay/calling/component/tap'
55
+
56
+ require 'signalwire/relay/messaging'
57
+ require 'signalwire/relay/messaging/message'
58
+ require 'signalwire/relay/messaging/send_result.rb'
@@ -21,7 +21,7 @@ module Signalwire::Relay
21
21
  end
22
22
 
23
23
  def contexts
24
- @contexts ||= Concurrent::Array.new
24
+ @client.contexts
25
25
  end
26
26
 
27
27
  def receive(context:, &block)
@@ -32,17 +32,7 @@ module Signalwire::Relay
32
32
  block.call(call_obj) if block_given?
33
33
  end
34
34
 
35
- receive_command = {
36
- protocol: protocol,
37
- method: 'call.receive',
38
- params: {
39
- context: context
40
- }
41
- }
42
-
43
- relay_execute receive_command do
44
- contexts << context
45
- end
35
+ @client.setup_context(context)
46
36
  end
47
37
 
48
38
  def find_call_by_id(call_id)
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ module Signalwire::Relay::Calling
6
+ class DetectAction < Action
7
+ def result
8
+ DetectResult.new(@component)
9
+ end
10
+
11
+ def stop
12
+ @component.stop
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ module Signalwire::Relay::Calling
6
+ class FaxAction < Action
7
+ def result
8
+ FaxResult.new(@component)
9
+ end
10
+
11
+ def stop
12
+ @component.stop
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ module Signalwire::Relay::Calling
6
+ class TapAction < Action
7
+ def_delegators :@component, :source_device
8
+
9
+ def result
10
+ TapResult.new(@component)
11
+ end
12
+
13
+ def stop
14
+ @component.stop
15
+ end
16
+ end
17
+ end
@@ -8,6 +8,7 @@ module Signalwire::Relay::Calling
8
8
  include Signalwire::Common
9
9
  include Signalwire::Blade::EventHandler
10
10
  include Signalwire::Relay::Calling::CallConvenienceMethods
11
+ include Signalwire::Relay::Calling::CallDetectMethods
11
12
  extend Forwardable
12
13
 
13
14
  attr_reader :device, :type, :node_id, :context, :from, :to,
@@ -162,6 +163,42 @@ module Signalwire::Relay::Calling
162
163
  DialResult.new(component: dial_component)
163
164
  end
164
165
 
166
+ def fax_receive
167
+ component = Signalwire::Relay::Calling::FaxReceive.new(call: self)
168
+ component.wait_for(Relay::CallFaxState::ERROR, Relay::CallFaxState::FINISHED)
169
+ FaxResult.new(component: component)
170
+ end
171
+
172
+ def fax_receive!
173
+ component = Signalwire::Relay::Calling::FaxReceive.new(call: self)
174
+ component.execute
175
+ FaxAction.new(component: component)
176
+ end
177
+
178
+ def fax_send(document: , identity: nil, header: nil)
179
+ component = Signalwire::Relay::Calling::FaxSend.new(call: self, document: document, identity: identity, header: header)
180
+ component.wait_for(Relay::CallFaxState::ERROR, Relay::CallFaxState::FINISHED)
181
+ FaxResult.new(component: component)
182
+ end
183
+
184
+ def fax_send!(document: , identity: nil, header: nil)
185
+ component = Signalwire::Relay::Calling::FaxSend.new(call: self, document: document, identity: identity, header: header)
186
+ component.execute
187
+ FaxAction.new(component: component)
188
+ end
189
+
190
+ def tap_media(tap:, device:)
191
+ component = Signalwire::Relay::Calling::Tap.new(call: self, tap: tap, device: device)
192
+ component.wait_for(Relay::CallTapState::FINISHED)
193
+ TapResult.new(component: component)
194
+ end
195
+
196
+ def tap_media!(tap:, device:)
197
+ component = Signalwire::Relay::Calling::Tap.new(call: self, tap: tap, device: device)
198
+ component.execute
199
+ TapAction.new(component: component)
200
+ end
201
+
165
202
  def wait_for(*events)
166
203
  events = [Relay::CallState::ENDED] if events.empty?
167
204
 
@@ -0,0 +1,110 @@
1
+ module Signalwire::Relay::Calling
2
+ module CallDetectMethods
3
+ def detect(detect:, timeout: Relay::DEFAULT_CALL_TIMEOUT)
4
+ component = Signalwire::Relay::Calling::Detect.new(call: self, detect: detect, timeout: timeout)
5
+ component.wait_for(Relay::CallDetectState::FINISHED, Relay::CallDetectState::ERROR)
6
+ DetectResult.new(component: component)
7
+ end
8
+
9
+ def detect!(detect:, timeout: Relay::DEFAULT_CALL_TIMEOUT)
10
+ component = Signalwire::Relay::Calling::Detect.new(call: self, detect: detect, timeout: timeout)
11
+ component.execute
12
+ DetectAction.new(component: component)
13
+ end
14
+
15
+ def detect_human(params: {}, timeout: Relay::DEFAULT_CALL_TIMEOUT)
16
+ detect = {
17
+ type: Relay::CallDetectType::MACHINE,
18
+ params: params
19
+ }
20
+ component = Signalwire::Relay::Calling::Detect.new(call: self, detect: detect, timeout: timeout)
21
+ component.wait_for(Relay::CallDetectState::FINISHED, Relay::CallDetectState::ERROR, Relay::CallDetectState::HUMAN)
22
+ DetectResult.new(component: component)
23
+ end
24
+
25
+ def detect_human!(params: {}, timeout: Relay::DEFAULT_CALL_TIMEOUT)
26
+ detect = {
27
+ type: Relay::CallDetectType::MACHINE,
28
+ params: params
29
+ }
30
+ component = Signalwire::Relay::Calling::Detect.new(call: self, detect: detect, timeout: timeout)
31
+ component.setup_waiting_events([Relay::CallDetectState::FINISHED, Relay::CallDetectState::ERROR, Relay::CallDetectState::HUMAN])
32
+ component.execute
33
+ DetectAction.new(component: component)
34
+ end
35
+
36
+ def detect_machine(params: {}, timeout: Relay::DEFAULT_CALL_TIMEOUT)
37
+ detect = {
38
+ type: Relay::CallDetectType::MACHINE,
39
+ params: params
40
+ }
41
+ component = Signalwire::Relay::Calling::Detect.new(call: self, detect: detect, timeout: timeout)
42
+ component.wait_for(Relay::CallDetectState::FINISHED, Relay::CallDetectState::ERROR,
43
+ Relay::CallDetectState::MACHINE, Relay::CallDetectState::READY,
44
+ Relay::CallDetectState::NOT_READY)
45
+ DetectResult.new(component: component)
46
+ end
47
+
48
+ def detect_machine!(params: {}, timeout: Relay::DEFAULT_CALL_TIMEOUT)
49
+ detect = {
50
+ type: Relay::CallDetectType::MACHINE,
51
+ params: params
52
+ }
53
+ component = Signalwire::Relay::Calling::Detect.new(call: self, detect: detect, timeout: timeout)
54
+ component.setup_waiting_events([Relay::CallDetectState::FINISHED, Relay::CallDetectState::ERROR,
55
+ Relay::CallDetectState::MACHINE, Relay::CallDetectState::READY,
56
+ Relay::CallDetectState::NOT_READY])
57
+ component.execute
58
+ DetectAction.new(component: component)
59
+ end
60
+
61
+ def detect_fax(tone: nil, timeout: Relay::DEFAULT_CALL_TIMEOUT)
62
+ detect, events = prepare_fax_arguments(tone)
63
+
64
+ component = Signalwire::Relay::Calling::Detect.new(call: self, detect: detect, timeout: timeout)
65
+ component.wait_for(*events)
66
+ DetectResult.new(component: component)
67
+ end
68
+
69
+ def detect_fax!(tone: nil, timeout: Relay::DEFAULT_CALL_TIMEOUT)
70
+ detect, events = prepare_fax_arguments(tone)
71
+ component = Signalwire::Relay::Calling::Detect.new(call: self, detect: detect, timeout: timeout)
72
+ component.setup_waiting_events(events)
73
+ component.execute
74
+ DetectAction.new(component: component)
75
+ end
76
+
77
+ def detect_digit(digits: nil, timeout: Relay::DEFAULT_CALL_TIMEOUT)
78
+ detect = {
79
+ type: Relay::CallDetectType::DIGIT,
80
+ params: {}
81
+ }
82
+ detect[:params][:digits] = digits if digits
83
+ detect(detect: detect, timeout: timeout)
84
+ end
85
+
86
+ def detect_digit!(digits: nil, timeout: Relay::DEFAULT_CALL_TIMEOUT)
87
+ detect = {
88
+ type: Relay::CallDetectType::DIGIT,
89
+ params: {}
90
+ }
91
+ detect[:params][:digits] = digits if digits
92
+ detect!(detect: detect, timeout: timeout)
93
+ end
94
+
95
+ def prepare_fax_arguments(tone)
96
+ fax_events = [Relay::CallDetectState::CED, Relay::CallDetectState::CNG]
97
+ events = [Relay::CallDetectState::FINISHED, Relay::CallDetectState::ERROR]
98
+ detect = { type: Relay::CallDetectType::FAX, params: {} }
99
+
100
+ if fax_events.include?(tone)
101
+ detect[:params] = { tone: tone }
102
+ events << tone
103
+ else
104
+ events = events + fax_events
105
+ end
106
+
107
+ [detect, events]
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Signalwire::Relay::Calling
4
+ class BaseFax < ControlComponent
5
+ attr_reader :direction, :identity, :remote_identity, :document, :pages
6
+
7
+ def event_type
8
+ Relay::CallNotification::FAX
9
+ end
10
+
11
+ def notification_handler(event)
12
+ fax_state = event.call_params[:fax]
13
+ fax_params = fax_state[:params]
14
+ @state = fax_state[:type]
15
+
16
+ @completed = @state != Relay::CallFaxState::PAGE
17
+
18
+ if @completed
19
+ if fax_params[:success]
20
+ @successful = true
21
+ @direction = fax_params[:direction]
22
+ @identity = fax_params[:identity]
23
+ @remote_identity = fax_params[:remote_identity]
24
+ @document = fax_params[:document]
25
+ @pages = fax_params[:pages]
26
+ end
27
+
28
+ @event = event
29
+ end
30
+
31
+ broadcast_event(event)
32
+ check_for_waiting_events
33
+ end
34
+
35
+ def broadcast_event(event)
36
+ @call.broadcast "fax_#{@state}".to_sym, event
37
+ @call.broadcast :fax_state_change, event
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Signalwire::Relay::Calling
4
+ class Detect < ControlComponent
5
+ attr_reader :result, :type
6
+
7
+ def initialize(call:, detect:, timeout: 30)
8
+ super(call: call)
9
+ @detect = detect
10
+ @timeout = timeout
11
+ @received_events = Concurrent::Array.new
12
+ end
13
+
14
+ def method
15
+ Relay::ComponentMethod::DETECT
16
+ end
17
+
18
+ def event_type
19
+ Relay::CallNotification::DETECT
20
+ end
21
+
22
+ def inner_params
23
+ {
24
+ node_id: @call.node_id,
25
+ call_id: @call.id,
26
+ control_id: control_id,
27
+ detect: @detect,
28
+ timeout: @timeout
29
+ }
30
+ end
31
+
32
+ def notification_handler(event)
33
+ result = event.call_params[:detect]
34
+ @type = result[:type]
35
+ params = result[:params]
36
+ res_event = params[:event]
37
+ @state = res_event
38
+
39
+ if @state != Relay::CallDetectState::FINISHED && @state != Relay::CallDetectState::ERROR
40
+ @received_events << res_event
41
+ end
42
+
43
+ @completed = @events_waiting.include?(@state)
44
+
45
+ if @completed
46
+ @successful = @state != Relay::CallDetectState::ERROR
47
+ @result = @received_events.join(' ')
48
+ @event = event
49
+ unblock(event)
50
+ end
51
+
52
+ broadcast_event(event)
53
+ # This component has complex logic so we handle it separately
54
+ # check_for_waiting_events
55
+ end
56
+
57
+ def broadcast_event(event)
58
+ @call.broadcast "detect_#{@state}".to_sym, event
59
+ @call.broadcast :detect_state_change, event
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,15 @@
1
+ module Signalwire::Relay::Calling
2
+ class FaxReceive < BaseFax
3
+ def method
4
+ Relay::ComponentMethod::RECEIVE_FAX
5
+ end
6
+
7
+ def inner_params
8
+ params = {
9
+ node_id: @call.node_id,
10
+ call_id: @call.id,
11
+ control_id: control_id
12
+ }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,28 @@
1
+ module Signalwire::Relay::Calling
2
+ class FaxSend < BaseFax
3
+ def initialize(call:, document:, identity: nil, header: nil)
4
+ super(call: call)
5
+ @priv_document = document
6
+ @priv_identity = identity
7
+ @priv_header = header
8
+ end
9
+
10
+ def method
11
+ Relay::ComponentMethod::SEND_FAX
12
+ end
13
+
14
+ def inner_params
15
+ params = {
16
+ node_id: @call.node_id,
17
+ call_id: @call.id,
18
+ control_id: control_id,
19
+ document: @priv_document
20
+ }
21
+
22
+ params[:identity] = @priv_identity if @priv_identity
23
+ params[:header_info] = @priv_header if @priv_header
24
+
25
+ params
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Signalwire::Relay::Calling
4
+ class Tap < ControlComponent
5
+ attr_accessor :device
6
+
7
+ def initialize(call:, tap:, device:)
8
+ super(call: call)
9
+ @tap = tap
10
+ @device = device
11
+ end
12
+
13
+ def method
14
+ Relay::ComponentMethod::TAP
15
+ end
16
+
17
+ def event_type
18
+ Relay::CallNotification::TAP
19
+ end
20
+
21
+ def source_device
22
+ return unless @execute_result
23
+
24
+ @execute_result.dig(:result, :result, :source_device)
25
+ end
26
+
27
+ def inner_params
28
+ {
29
+ node_id: @call.node_id,
30
+ call_id: @call.id,
31
+ control_id: control_id,
32
+ tap: @tap,
33
+ device: @device
34
+ }
35
+ end
36
+
37
+ def tap_media
38
+ @tap
39
+ end
40
+
41
+ def notification_handler(event)
42
+ @state = event.call_params[:state]
43
+ @device = event.call_params[:device]
44
+ @tap = event.call_params[:tap]
45
+
46
+ @completed = @state == Relay::CallTapState::FINISHED
47
+ if @completed
48
+ @successful = true
49
+ @event = event
50
+ end
51
+
52
+ broadcast_event(event)
53
+ check_for_waiting_events
54
+ end
55
+
56
+ def broadcast_event(event)
57
+ @call.broadcast "tap_#{@state}".to_sym, event
58
+ @call.broadcast :tap_state_change, event
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Signalwire::Relay::Calling
4
+ class DetectResult < Result
5
+ def_delegators :@component, :type, :result
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Signalwire::Relay::Calling
4
+ class FaxResult < Result
5
+ def_delegators :@component, :direction, :identity, :remote_identity, :document, :pages
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Signalwire::Relay::Calling
4
+ class TapResult < Result
5
+ def_delegators :@component, :tap_media, :source_device, :device
6
+ end
7
+ end
@@ -31,7 +31,7 @@ module Signalwire::Relay
31
31
  # Starts the client connection
32
32
  #
33
33
  def connect!
34
- logger.debug "Connecting to #{@space_url}"
34
+ logger.debug "Connecting to #{@url}"
35
35
  session.connect!
36
36
  end
37
37
 
@@ -80,9 +80,11 @@ module Signalwire::Relay
80
80
  logger.error "Relay command failed with code #{code} and message: #{message}" unless success
81
81
  else
82
82
  logger.error 'Unknown Relay command failure, result code not found'
83
+ block.call(event, :failure) if block_given?
83
84
  end
84
85
  else
85
86
  logger.error 'Unknown Relay command failure, command timed out'
87
+ block.call(event, :failure) if block_given?
86
88
  end
87
89
  end
88
90
 
@@ -90,6 +92,29 @@ module Signalwire::Relay
90
92
  @calling ||= Signalwire::Relay::Calling::Instance.new(self)
91
93
  end
92
94
 
95
+ def messaging
96
+ @messaging ||= Signalwire::Relay::Messaging::Instance.new(self)
97
+ end
98
+
99
+ def setup_context(context)
100
+ return if contexts.include?(context)
101
+ receive_command = {
102
+ protocol: @protocol,
103
+ method: 'call.receive',
104
+ params: {
105
+ context: context
106
+ }
107
+ }
108
+
109
+ relay_execute receive_command do
110
+ contexts << context
111
+ end
112
+ end
113
+
114
+ def contexts
115
+ @contexts ||= Concurrent::Array.new
116
+ end
117
+
93
118
  private
94
119
 
95
120
  def setup_handlers
@@ -141,6 +166,7 @@ module Signalwire::Relay
141
166
  @session.on :message, %i[\[\] method] => 'blade.broadcast' do |event|
142
167
  relay = Signalwire::Relay::Event.from_blade(event)
143
168
  broadcast :event, relay
169
+ broadcast :task, relay if relay.dig(:params, :event) == "queuing.relay.tasks"
144
170
  end
145
171
  end
146
172
  end
@@ -60,6 +60,9 @@ module Signalwire::Relay
60
60
  RECORD = 'calling.call.record'
61
61
  PLAY = 'calling.call.play'
62
62
  COLLECT = 'calling.call.collect'
63
+ FAX = 'calling.call.fax'
64
+ TAP = 'calling.call.tap'
65
+ DETECT = 'calling.call.detect'
63
66
  end
64
67
 
65
68
  CALL_EVENT_STATE_FIELDS = {
@@ -91,6 +94,15 @@ module Signalwire::Relay
91
94
  FINISHED = 'finished'
92
95
  end
93
96
 
97
+ module MessageState
98
+ QUEUED = 'queued'
99
+ INITIATED = 'initiated'
100
+ SENT = 'sent'
101
+ DELIVERED = 'delivered'
102
+ UNDELIVERED = 'undelivered'
103
+ FAILED = 'failed'
104
+ end
105
+
94
106
  module ComponentMethod
95
107
  ANSWER = 'call.answer'
96
108
  CONNECT = 'call.connect'
@@ -99,11 +111,44 @@ module Signalwire::Relay
99
111
  PLAY = 'call.play'
100
112
  PROMPT = 'call.play_and_collect'
101
113
  RECORD = 'call.record'
114
+ SEND_FAX = 'call.send_fax'
115
+ RECEIVE_FAX = 'call.receive_fax'
116
+ TAP = 'call.tap'
117
+ DETECT = 'call.detect'
102
118
  end
103
119
 
104
120
  module CommonState
105
121
  SUCCESSFUL = 'successful'
106
122
  end
123
+
124
+ module CallFaxState
125
+ PAGE = 'page',
126
+ ERROR = 'error',
127
+ FINISHED = 'finished'
128
+ end
129
+
130
+ module CallTapState
131
+ TAPPING = 'tapping'
132
+ FINISHED = 'finished'
133
+ end
134
+
135
+ module CallDetectState
136
+ ERROR = 'error'
137
+ FINISHED = 'finished'
138
+ CED = 'CED'
139
+ CNG = 'CNG'
140
+ MACHINE = 'MACHINE'
141
+ HUMAN = 'HUMAN'
142
+ UNKNOWN = 'UNKNOWN'
143
+ READY = 'READY'
144
+ NOT_READY = 'NOT_READY'
145
+ end
146
+
147
+ module CallDetectType
148
+ FAX = "fax"
149
+ MACHINE = "machine"
150
+ DIGIT = "digit"
151
+ end
107
152
  end
108
153
 
109
154
  Relay = Signalwire::Relay
@@ -18,7 +18,7 @@ module Signalwire::Relay
18
18
  # Creates a Consumer instance ready to be run
19
19
  #
20
20
  # The initialization parameters can also be supplied via ENV variables
21
- # (SIGNALWIRE_ACCOUNT, SIGNALWIRE_TOKEN and SIGNALWIRE_HOST)
21
+ # (SIGNALWIRE_PROJECT_KEY, SIGNALWIRE_TOKEN and SIGNALWIRE_HOST)
22
22
  # Passed-in values override the environment ones.
23
23
  #
24
24
  # @param project [String] Your SignalWire project identifier
@@ -26,26 +26,22 @@ module Signalwire::Relay
26
26
  # @param SIGNALWIRE_HOST [String] Your SignalWire space URL (not needed for production usage)
27
27
 
28
28
  def initialize(project: nil, token: nil, host: nil)
29
- @project = project || ENV['SIGNALWIRE_ACCOUNT']
29
+ @project = project || ENV['SIGNALWIRE_PROJECT_KEY']
30
30
  @token = token || ENV['SIGNALWIRE_TOKEN']
31
31
  @url = host || ENV['SIGNALWIRE_HOST'] || Signalwire::Relay::DEFAULT_URL
32
32
  @client = Signalwire::Relay::Client.new(project: @project,
33
33
  token: @token, host: @url)
34
34
  end
35
35
 
36
- def setup
37
- # do stuff here.
38
- end
36
+ def setup; end
39
37
 
40
- def ready
41
- # do stuff here.
42
- end
38
+ def ready; end
43
39
 
44
- def teardown
45
- # do stuff here.
46
- end
40
+ def teardown; end
47
41
 
48
42
  def on_task(task); end
43
+ def on_incoming_message(message); end
44
+ def on_message_state_change(message); end
49
45
 
50
46
  def on_event(event)
51
47
  # all-events firespout
@@ -56,10 +52,11 @@ module Signalwire::Relay
56
52
  def run
57
53
  setup
58
54
  client.once :ready do
59
- ready
60
55
  setup_receive_listeners
61
56
  setup_all_events_listener
62
- # not sure if ordering matters
57
+ setup_task_listeners
58
+ setup_messaging_listeners
59
+ ready
63
60
  end
64
61
  client.connect!
65
62
  end
@@ -79,10 +76,21 @@ module Signalwire::Relay
79
76
  end
80
77
  end
81
78
 
79
+ def setup_task_listeners
80
+ client.on :task do |task|
81
+ on_task(task)
82
+ end
83
+ end
84
+
82
85
  def setup_all_events_listener
83
86
  client.on :event do |evt|
84
87
  on_event(evt)
85
88
  end
86
89
  end
90
+
91
+ def setup_messaging_listeners
92
+ client.messaging.on(:message_received) { |evt|on_incoming_message(evt) }
93
+ client.messaging.on(:message_state_change) { |evt| on_message_state_change(evt) }
94
+ end
87
95
  end
88
96
  end
@@ -34,6 +34,10 @@ module Signalwire::Relay
34
34
  {}
35
35
  end
36
36
 
37
+ def message
38
+ event_params[:message]
39
+ end
40
+
37
41
  def self.from_blade(blade_event)
38
42
  new(blade_event.payload)
39
43
  end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+ require 'concurrent-ruby'
5
+
6
+ module Signalwire::Relay
7
+ module Messaging
8
+ class Instance
9
+ extend Forwardable
10
+ include Signalwire::Logger
11
+ include Signalwire::Common
12
+
13
+ alias_method :object_send, :send
14
+
15
+ def_delegators :@client, :relay_execute, :protocol, :on, :once, :broadcast
16
+
17
+ def initialize(client)
18
+ @client = client
19
+ setup_events
20
+ end
21
+
22
+ def send(from:, to:, context:, body: nil, media: nil, tags: nil, region: nil)
23
+ params = {
24
+ from_number: from_number,
25
+ to_number: to_number,
26
+ context: context
27
+ }
28
+
29
+ params[:body] = body if body
30
+ params[:media] = media if media
31
+ params[:tags] = tags if tags
32
+ params[:region] = region if region
33
+
34
+ messaging_send = {
35
+ protocol: protocol,
36
+ method: 'messaging.send',
37
+ params: params
38
+ }
39
+
40
+ response = nil
41
+ relay_execute messaging_send do |event|
42
+ response = Signalwire::Relay::Messaging::SendResult.new(event)
43
+ end
44
+ response
45
+ end
46
+
47
+ def setup_events
48
+ @client.on :event, event_type: 'messaging.receive' do |event|
49
+ broadcast :message_received, Signalwire::Relay::Messaging::Message.new(event.payload)
50
+ end
51
+
52
+ @client.on :event, event_type: 'messaging.state' do |event|
53
+ broadcast :message_state_change, Signalwire::Relay::Messaging::Message.new(event.payload)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Signalwire::Relay::Messaging
4
+ class Message < Signalwire::Relay::Event
5
+ alias_method :blade_id, :id
6
+
7
+ FIELDS = %i{body message_id context tags
8
+ from_number to_number media
9
+ segments message_state}.freeze
10
+ def message_params
11
+ dig(:params, :params, :params)
12
+ rescue StandardError
13
+ {}
14
+ end
15
+
16
+ FIELDS.each do |meth|
17
+ defined_method = case meth
18
+ when :to_number
19
+ :to
20
+ when :from_number
21
+ :from
22
+ when :message_state
23
+ :state
24
+ when :message_id
25
+ :id
26
+ else
27
+ meth
28
+ end
29
+ define_method(defined_method) { message_params[meth] }
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,25 @@
1
+ module Signalwire::Relay::Messaging
2
+ attr_accessor :event
3
+ class SendResult < Signalwire::Relay::Event
4
+ def initialize(event)
5
+ super(event.payload)
6
+ @event = event
7
+ end
8
+
9
+ def code
10
+ dig(:result, :result, :code)
11
+ end
12
+
13
+ def message_id
14
+ dig(:result, :result, :message_id)
15
+ end
16
+
17
+ def message
18
+ dig(:result, :result, :message)
19
+ end
20
+
21
+ def successful
22
+ code == "200"
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,45 @@
1
+ require 'uri'
2
+ require 'faraday'
3
+ require 'json'
4
+
5
+ module Signalwire::Relay
6
+ class Task
7
+ DEFAULT_HOST = "relay.signalwire.com"
8
+ attr_accessor :host
9
+
10
+ def initialize(project:, token:, host: nil )
11
+ @project = project
12
+ @token = token
13
+ @host = host || DEFAULT_HOST
14
+ end
15
+
16
+ def deliver(context:, message:)
17
+ message = JSON.generate({
18
+ context: context,
19
+ message: message
20
+ })
21
+ conn = Faraday.new(
22
+ url: normalize_host(@host),
23
+ headers: {'Content-Type' => 'application/json'}
24
+ )
25
+ conn.basic_auth(@project, @token)
26
+
27
+ resp = conn.post('/api/relay/rest/tasks') do |req|
28
+ req.body = message
29
+ end
30
+ return resp.status == 204
31
+ end
32
+
33
+ def normalize_host(passed_host)
34
+ uri = URI.parse(passed_host)
35
+ if uri.scheme.nil? && uri.host.nil?
36
+ unless uri.path.nil?
37
+ uri.scheme = 'https'
38
+ uri.host = uri.path
39
+ uri.path = ''
40
+ end
41
+ end
42
+ uri.to_s
43
+ end
44
+ end
45
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Signalwire
4
- VERSION = '2.0.0'
4
+ VERSION = '2.1.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: signalwire
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - SignalWire Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-07-16 00:00:00.000000000 Z
11
+ date: 2019-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -255,11 +255,19 @@ files:
255
255
  - Makefile
256
256
  - README.md
257
257
  - Rakefile
258
+ - examples/relay/fax/fax_receive.rb
259
+ - examples/relay/fax/fax_send.rb
258
260
  - examples/relay/inbound_consumer.rb
259
261
  - examples/relay/inbound_dial.rb
262
+ - examples/relay/messaging/messaging_receive.rb
263
+ - examples/relay/messaging/messaging_send.rb
260
264
  - examples/relay/outbound_collect.rb
261
265
  - examples/relay/outbound_consumer.rb
266
+ - examples/relay/outbound_detect.rb
262
267
  - examples/relay/outbound_record.rb
268
+ - examples/relay/outbound_tap.rb
269
+ - examples/relay/tasking/tasking_receive.rb
270
+ - examples/relay/tasking/tasking_send.rb
263
271
  - lib/signalwire.rb
264
272
  - lib/signalwire/blade.rb
265
273
  - lib/signalwire/blade/connection.rb
@@ -274,34 +282,50 @@ files:
274
282
  - lib/signalwire/relay/calling.rb
275
283
  - lib/signalwire/relay/calling/action.rb
276
284
  - lib/signalwire/relay/calling/action/connect_action.rb
285
+ - lib/signalwire/relay/calling/action/detect_action.rb
286
+ - lib/signalwire/relay/calling/action/fax_action.rb
277
287
  - lib/signalwire/relay/calling/action/play_action.rb
278
288
  - lib/signalwire/relay/calling/action/prompt_action.rb
279
289
  - lib/signalwire/relay/calling/action/record_action.rb
290
+ - lib/signalwire/relay/calling/action/tap_action.rb
280
291
  - lib/signalwire/relay/calling/call.rb
281
292
  - lib/signalwire/relay/calling/call_convenience_methods.rb
293
+ - lib/signalwire/relay/calling/call_detect_methods.rb
282
294
  - lib/signalwire/relay/calling/component.rb
283
295
  - lib/signalwire/relay/calling/component/answer.rb
284
296
  - lib/signalwire/relay/calling/component/await.rb
297
+ - lib/signalwire/relay/calling/component/base_fax.rb
285
298
  - lib/signalwire/relay/calling/component/connect.rb
299
+ - lib/signalwire/relay/calling/component/detect.rb
286
300
  - lib/signalwire/relay/calling/component/dial.rb
301
+ - lib/signalwire/relay/calling/component/fax_receive.rb
302
+ - lib/signalwire/relay/calling/component/fax_send.rb
287
303
  - lib/signalwire/relay/calling/component/hangup.rb
288
304
  - lib/signalwire/relay/calling/component/play.rb
289
305
  - lib/signalwire/relay/calling/component/prompt.rb
290
306
  - lib/signalwire/relay/calling/component/record.rb
307
+ - lib/signalwire/relay/calling/component/tap.rb
291
308
  - lib/signalwire/relay/calling/control_component.rb
292
309
  - lib/signalwire/relay/calling/result.rb
293
310
  - lib/signalwire/relay/calling/result/answer_result.rb
294
311
  - lib/signalwire/relay/calling/result/connect_result.rb
312
+ - lib/signalwire/relay/calling/result/detect_result.rb
295
313
  - lib/signalwire/relay/calling/result/dial_result.rb
314
+ - lib/signalwire/relay/calling/result/fax_result.rb
296
315
  - lib/signalwire/relay/calling/result/hangup_result.rb
297
316
  - lib/signalwire/relay/calling/result/play_result.rb
298
317
  - lib/signalwire/relay/calling/result/prompt_result.rb
299
318
  - lib/signalwire/relay/calling/result/record_result.rb
319
+ - lib/signalwire/relay/calling/result/tap_result.rb
300
320
  - lib/signalwire/relay/client.rb
301
321
  - lib/signalwire/relay/constants.rb
302
322
  - lib/signalwire/relay/consumer.rb
303
323
  - lib/signalwire/relay/event.rb
324
+ - lib/signalwire/relay/messaging.rb
325
+ - lib/signalwire/relay/messaging/message.rb
326
+ - lib/signalwire/relay/messaging/send_result.rb
304
327
  - lib/signalwire/relay/request.rb
328
+ - lib/signalwire/relay/task.rb
305
329
  - lib/signalwire/rest/client.rb
306
330
  - lib/signalwire/sdk.rb
307
331
  - lib/signalwire/sdk/configuration.rb