signalwire 1.4.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +55 -0
  3. data/.rubocop.yml +14 -2
  4. data/AUTHORS.md +1 -0
  5. data/CHANGELOG.md +30 -5
  6. data/Gemfile +4 -18
  7. data/LICENSE +21 -0
  8. data/README.md +22 -82
  9. data/Rakefile +0 -17
  10. data/examples/relay/inbound_consumer.rb +26 -0
  11. data/examples/relay/inbound_dial.rb +28 -0
  12. data/examples/relay/outbound_collect.rb +27 -0
  13. data/examples/relay/outbound_consumer.rb +22 -0
  14. data/examples/relay/outbound_record.rb +25 -0
  15. data/lib/signalwire.rb +13 -0
  16. data/lib/signalwire/blade.rb +12 -0
  17. data/lib/signalwire/blade/connection.rb +200 -0
  18. data/lib/signalwire/blade/event_handler.rb +15 -0
  19. data/lib/signalwire/blade/message.rb +38 -0
  20. data/lib/signalwire/blade/message/connect.rb +18 -0
  21. data/lib/signalwire/blade/message/execute.rb +16 -0
  22. data/lib/signalwire/blade/message/subscribe.rb +15 -0
  23. data/lib/signalwire/common.rb +6 -0
  24. data/lib/signalwire/logger.rb +27 -0
  25. data/lib/signalwire/relay.rb +40 -0
  26. data/lib/signalwire/relay/calling.rb +82 -0
  27. data/lib/signalwire/relay/calling/action.rb +16 -0
  28. data/lib/signalwire/relay/calling/action/connect_action.rb +11 -0
  29. data/lib/signalwire/relay/calling/action/play_action.rb +15 -0
  30. data/lib/signalwire/relay/calling/action/prompt_action.rb +15 -0
  31. data/lib/signalwire/relay/calling/action/record_action.rb +15 -0
  32. data/lib/signalwire/relay/calling/call.rb +210 -0
  33. data/lib/signalwire/relay/calling/call_convenience_methods.rb +79 -0
  34. data/lib/signalwire/relay/calling/component.rb +115 -0
  35. data/lib/signalwire/relay/calling/component/answer.rb +27 -0
  36. data/lib/signalwire/relay/calling/component/await.rb +20 -0
  37. data/lib/signalwire/relay/calling/component/connect.rb +45 -0
  38. data/lib/signalwire/relay/calling/component/dial.rb +34 -0
  39. data/lib/signalwire/relay/calling/component/hangup.rb +41 -0
  40. data/lib/signalwire/relay/calling/component/play.rb +46 -0
  41. data/lib/signalwire/relay/calling/component/prompt.rb +62 -0
  42. data/lib/signalwire/relay/calling/component/record.rb +53 -0
  43. data/lib/signalwire/relay/calling/control_component.rb +35 -0
  44. data/lib/signalwire/relay/calling/result.rb +16 -0
  45. data/lib/signalwire/relay/calling/result/answer_result.rb +6 -0
  46. data/lib/signalwire/relay/calling/result/connect_result.rb +9 -0
  47. data/lib/signalwire/relay/calling/result/dial_result.rb +7 -0
  48. data/lib/signalwire/relay/calling/result/hangup_result.rb +7 -0
  49. data/lib/signalwire/relay/calling/result/play_result.rb +6 -0
  50. data/lib/signalwire/relay/calling/result/prompt_result.rb +11 -0
  51. data/lib/signalwire/relay/calling/result/record_result.rb +7 -0
  52. data/lib/signalwire/relay/client.rb +147 -0
  53. data/lib/signalwire/relay/constants.rb +109 -0
  54. data/lib/signalwire/relay/consumer.rb +88 -0
  55. data/lib/signalwire/relay/event.rb +41 -0
  56. data/lib/signalwire/relay/request.rb +6 -0
  57. data/lib/signalwire/rest/client.rb +5 -5
  58. data/lib/signalwire/sdk/fax_response.rb +3 -3
  59. data/lib/signalwire/sdk/messaging_response.rb +0 -2
  60. data/lib/signalwire/sdk/twilio_set_fax.rb +9 -8
  61. data/lib/signalwire/sdk/twilio_set_host.rb +8 -3
  62. data/lib/signalwire/version.rb +5 -0
  63. data/signalwire.gemspec +36 -106
  64. metadata +173 -76
  65. data/LICENSE.txt +0 -20
  66. data/VERSION +0 -1
  67. data/spec/signalwire/rest/client_spec.rb +0 -30
  68. data/spec/signalwire/rest/integration_spec.rb +0 -102
  69. data/spec/signalwire/sdk/configuration_spec.rb +0 -28
  70. data/spec/signalwire/sdk/fax_response_spec.rb +0 -26
  71. data/spec/signalwire/sdk/messaging_response_spec.rb +0 -18
  72. data/spec/signalwire/sdk/voice_response_spec.rb +0 -20
  73. data/spec/signalwire/sdk_spec.rb +0 -27
  74. data/spec/spec_helper.rb +0 -119
  75. data/spec/vcr_cassettes/accounts.yml +0 -27
  76. data/spec/vcr_cassettes/applications.yml +0 -29
  77. data/spec/vcr_cassettes/get_fax.yml +0 -25
  78. data/spec/vcr_cassettes/get_fax_media_instance.yml +0 -27
  79. data/spec/vcr_cassettes/get_fax_media_list.yml +0 -47
  80. data/spec/vcr_cassettes/list_faxes.yml +0 -25
  81. data/spec/vcr_cassettes/local_numbers.yml +0 -26
  82. data/spec/vcr_cassettes/recordings.yml +0 -27
  83. data/spec/vcr_cassettes/send_fax.yml +0 -27
  84. data/spec/vcr_cassettes/toll_free_numbers.yml +0 -34
  85. data/spec/vcr_cassettes/transcriptions.yml +0 -28
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Signalwire::Relay::Calling
4
+ class Answer < Component
5
+ def method
6
+ Relay::ComponentMethod::ANSWER
7
+ end
8
+
9
+ def event_type
10
+ Relay::CallNotification::STATE
11
+ end
12
+
13
+ def notification_handler(event)
14
+ @state = event.call_params[:call_state]
15
+
16
+ ended_events = [Relay::CallState::ANSWERED]
17
+
18
+ if ended_events.include?(@state)
19
+ @completed = true
20
+ @successful = true
21
+ @event = event
22
+ end
23
+
24
+ check_for_waiting_events
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ module Signalwire::Relay::Calling
2
+ # A special component that only waits for call events
3
+ #
4
+ class Await < Component
5
+ def event_type
6
+ Relay::CallNotification::STATE
7
+ end
8
+
9
+ def notification_handler(event)
10
+ @state = event.call_params[:call_state]
11
+ @event = event
12
+ @successful = true if @events_waiting.include?(@state)
13
+ check_for_waiting_events
14
+ end
15
+
16
+ def execute
17
+ setup_handlers
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Signalwire::Relay::Calling
4
+ class Connect < Component
5
+ def initialize(call:, devices:)
6
+ super(call: call)
7
+ @devices = devices
8
+ end
9
+
10
+ def method
11
+ Relay::ComponentMethod::CONNECT
12
+ end
13
+
14
+ def event_type
15
+ Relay::CallNotification::CONNECT
16
+ end
17
+
18
+ def inner_params
19
+ {
20
+ node_id: @call.node_id,
21
+ call_id: @call.id,
22
+ devices: @devices
23
+ }
24
+ end
25
+
26
+ def notification_handler(event)
27
+ @state = event.call_params[:connect_state]
28
+
29
+ @completed = @state != Relay::CallConnectState::CONNECTING
30
+
31
+ if @completed
32
+ @successful = @state == Relay::CallConnectState::CONNECTED
33
+ @event = event
34
+ end
35
+
36
+ broadcast_event(event)
37
+ check_for_waiting_events
38
+ end
39
+
40
+ def broadcast_event(event)
41
+ @call.broadcast "connect_#{@state}".to_sym, event
42
+ @call.broadcast :connect_state_change, event
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Signalwire::Relay::Calling
4
+ class Dial < Component
5
+ def method
6
+ Relay::ComponentMethod::DIAL
7
+ end
8
+
9
+ def event_type
10
+ Relay::CallNotification::STATE
11
+ end
12
+
13
+ def inner_params
14
+ {
15
+ tag: @call.tag,
16
+ device: @call.device
17
+ }
18
+ end
19
+
20
+ def notification_handler(event)
21
+ @state = event.call_params[:call_state]
22
+
23
+ ended_events = [Relay::CallState::ANSWERED, Relay::CallState::ENDING, Relay::CallState::ENDED]
24
+
25
+ if ended_events.include?(@state)
26
+ @completed = true
27
+ @successful = true if @state == Relay::CallState::ANSWERED
28
+ @event = event
29
+ end
30
+
31
+ check_for_waiting_events
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Signalwire::Relay::Calling
4
+ class Hangup < Component
5
+ def initialize(call:, reason:)
6
+ super(call: call)
7
+ @reason = reason
8
+ end
9
+
10
+ def method
11
+ Relay::ComponentMethod::HANGUP
12
+ end
13
+
14
+ def event_type
15
+ Relay::CallNotification::STATE
16
+ end
17
+
18
+ def inner_params
19
+ {
20
+ node_id: @call.node_id,
21
+ call_id: @call.id,
22
+ reason: @reason
23
+ }
24
+ end
25
+
26
+ def notification_handler(event)
27
+ @state = event.call_params[:call_state]
28
+ end_reason = event.call_params[:call_state]
29
+
30
+ @completed = @state == Relay::CallState::ENDED
31
+
32
+ if @completed
33
+ @successful = true
34
+ @reason = end_reason
35
+ @event = event
36
+ end
37
+
38
+ check_for_waiting_events
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Signalwire::Relay::Calling
4
+ class Play < ControlComponent
5
+ def initialize(call:, play:)
6
+ super(call: call)
7
+ @play = play
8
+ end
9
+
10
+ def method
11
+ Relay::ComponentMethod::PLAY
12
+ end
13
+
14
+ def event_type
15
+ Relay::CallNotification::PLAY
16
+ end
17
+
18
+ def inner_params
19
+ {
20
+ node_id: @call.node_id,
21
+ call_id: @call.id,
22
+ control_id: control_id,
23
+ play: @play
24
+ }
25
+ end
26
+
27
+ def notification_handler(event)
28
+ @state = event.call_params[:state]
29
+
30
+ @completed = @state != Relay::CallPlayState::PLAYING
31
+
32
+ if @completed
33
+ @successful = true if @state == Relay::CallPlayState::FINISHED
34
+ @event = event
35
+ end
36
+
37
+ broadcast_event(event)
38
+ check_for_waiting_events
39
+ end
40
+
41
+ def broadcast_event(event)
42
+ @call.broadcast "play_#{@state}".to_sym, event
43
+ @call.broadcast :play_state_change, event
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Signalwire::Relay::Calling
4
+ class Prompt < ControlComponent
5
+ attr_reader :type, :input, :terminator
6
+ def initialize(call:, collect:, play:)
7
+ super(call: call)
8
+ @play = play
9
+ @collect = collect
10
+ end
11
+
12
+ def method
13
+ Relay::ComponentMethod::PROMPT
14
+ end
15
+
16
+ def event_type
17
+ Relay::CallNotification::COLLECT
18
+ end
19
+
20
+ def inner_params
21
+ {
22
+ node_id: @call.node_id,
23
+ call_id: @call.id,
24
+ control_id: control_id,
25
+ play: @play,
26
+ collect: @collect
27
+ }
28
+ end
29
+
30
+ def notification_handler(event)
31
+ @completed = true
32
+ result = event.call_params[:result]
33
+ @type = result[:type]
34
+ @state = @type
35
+
36
+ if @type == Relay::CallPromptState::DIGIT
37
+ digit_event(result)
38
+ elsif type == Relay::CallPromptState::SPEECH
39
+ speech_event(result)
40
+ else
41
+ @state = @type
42
+ @successful = false
43
+ end
44
+
45
+ check_for_waiting_events
46
+ end
47
+
48
+ private
49
+
50
+ def digit_event(result)
51
+ @successful = true
52
+ @input = result.dig(:params, :digits)
53
+ @terminator = result.dig(:params, :terminator)
54
+ end
55
+
56
+ def speech_event(result)
57
+ @successful = true
58
+ @input = result.dig(:params, :text)
59
+ @confidence = result.dig(:params, :confidence)
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Signalwire::Relay::Calling
4
+ class Record < ControlComponent
5
+ attr_reader :url, :duration, :size
6
+ def initialize(call:, record:)
7
+ super(call: call)
8
+ @record = record
9
+ end
10
+
11
+ def method
12
+ Relay::ComponentMethod::RECORD
13
+ end
14
+
15
+ def event_type
16
+ Relay::CallNotification::RECORD
17
+ end
18
+
19
+ def inner_params
20
+ {
21
+ node_id: @call.node_id,
22
+ call_id: @call.id,
23
+ control_id: control_id,
24
+ record: @record
25
+ }
26
+ end
27
+
28
+ def notification_handler(event)
29
+ @state = event.call_params[:state]
30
+ url = event.call_params[:url]
31
+ duration = event.call_params[:duration]
32
+ size = event.call_params[:size]
33
+
34
+ @completed = @state != Relay::CallRecordState::RECORDING
35
+
36
+ if @completed
37
+ @successful = @state == Relay::CallRecordState::FINISHED
38
+ @url = url
39
+ @duration = duration
40
+ @size = size
41
+ @event = event
42
+ end
43
+
44
+ broadcast_event(event)
45
+ check_for_waiting_events
46
+ end
47
+
48
+ def broadcast_event(event)
49
+ @call.broadcast "record_#{@state}".to_sym, event
50
+ @call.broadcast :record_state_change, event
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Signalwire::Relay::Calling
6
+ class ControlComponent < Component
7
+ def control_id
8
+ @control_id ||= SecureRandom.uuid
9
+ end
10
+
11
+ def inner_params
12
+ {
13
+ nodeid: @call.node_id,
14
+ callid: @call.id,
15
+ control_id: control_id,
16
+ params: payload
17
+ }
18
+ end
19
+
20
+ def setup_handlers
21
+ @call.on :event, event_type: event_type, control_id: control_id do |evt|
22
+ notification_handler(evt)
23
+ end
24
+ end
25
+
26
+ def stop
27
+ @call.relay_execute execute_params('.stop') do |event, outcome|
28
+ if outcome == :failure
29
+ terminate(event)
30
+ return event
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ module Signalwire::Relay::Calling
6
+ class Result
7
+ extend Forwardable
8
+ attr_reader :component
9
+
10
+ def_delegators :@component, :successful, :event
11
+
12
+ def initialize(component:)
13
+ @component = component
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Signalwire::Relay::Calling
4
+ class AnswerResult < Result
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Signalwire::Relay::Calling
4
+ class ConnectResult < Result
5
+ def call
6
+ @component.call.peer
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Signalwire::Relay::Calling
4
+ class DialResult < Result
5
+ def_delegators :@component, :call
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Signalwire::Relay::Calling
4
+ class HangupResult < Result
5
+ def_delegators :@component, :reason
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Signalwire::Relay::Calling
4
+ class PlayResult < Result
5
+ end
6
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Signalwire::Relay::Calling
4
+ class PromptResult < Result
5
+ def_delegators :@component, :type, :terminator, :confidence
6
+
7
+ def result
8
+ @component.input
9
+ end
10
+ end
11
+ end