signalwire 2.1.2 → 2.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a5ba44a20acd7bb12393399af0f7457543d60030
4
- data.tar.gz: '069bc5cbbe6465918eab2e726d88b2120b5519a8'
2
+ SHA256:
3
+ metadata.gz: b79e0a17481f2f0fcb5cdf7a1b5860f86565e60826808b3b0c4c671f6797d173
4
+ data.tar.gz: d798019a441d67cf6d6cdbba6093e13b43353a788465b7333bdf48bf9e0ab969
5
5
  SHA512:
6
- metadata.gz: b93d4efd4ab92f26fba1934720c1a03b50e17ad5576ea743af02654584170ff702a793fc2b201bb614a9b44d3ae82cd4feffc49de3d5790cd82b6bd88fcc82eb
7
- data.tar.gz: 27353d85dd32d496b747c78659badb0c56df081cfdb37d707a6e8acb400d0e17399aecca433237b3a8c3efc633d96b29dd4cce346f8ef52b3b159fda58a1d535
6
+ metadata.gz: fcadfef6643451bea578ce6a8fd8355307f53704545c6078e0265ed109c03b7c24b196d25c8703416db25a93ca2aa3158bb49818197294493fa01f43922c054d
7
+ data.tar.gz: 4cf8ec00e2eb43921000836f1f48012f82e05506c44070960c9b2736d8ffefeb32d5331c8ad5dabe7f537f56bd6a949ef3ab9a70668a3ab8532789dfd4323075
@@ -3,6 +3,18 @@ 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
+ ## [Unreleased]
7
+
8
+ ## [2.1.3] - 2019-08-20
9
+ ### Fixed
10
+ - Restore the correct parameter for the REST client space URL
11
+ - Correctly handle reconnect on a server-side disconnect
12
+ - Fix REST pagination URL
13
+ ### Changed
14
+ - SDK now uses `signalwire.receive` to set up contexts
15
+ - The `call.*` actions are now `calling.*`
16
+ - Support positional parameters in older methods
17
+
6
18
  ## [2.1.2] - 2019-08-01
7
19
  ### Fixed
8
20
  - Fix CPU usage
@@ -17,7 +17,7 @@ class MyConsumer < Signalwire::Relay::Consumer
17
17
 
18
18
  def on_incoming_call(call)
19
19
  call.answer
20
- call.play_tts 'the quick brown fox jumps over the lazy dog'
20
+ call.play_tts text: 'the quick brown fox jumps over the lazy dog'
21
21
 
22
22
  call.hangup
23
23
  end
@@ -18,7 +18,7 @@ class MyConsumer < Signalwire::Relay::Consumer
18
18
 
19
19
  def on_incoming_call(call)
20
20
  call.answer
21
- call.play_tts 'connecting you to the clock service'
21
+ call.play_tts text: 'connecting you to the clock service'
22
22
  call.connect [[{ type: 'phone', params: { to_number: '+12027621401', from_number: ENV['FROM_NUMBER'], timeout: 30 } }]]
23
23
  sleep 20
24
24
  call.hangup
@@ -13,9 +13,9 @@ class OutboundConsumer < Signalwire::Relay::Consumer
13
13
  def ready
14
14
  dial_result = client.calling.new_call(from: ENV['FROM_NUMBER'], to: ENV['TO_NUMBER']).dial
15
15
  collect_params = { "initial_timeout": 10.0, "digits": { "max": 1, "digit_timeout": 5.0 } }
16
- result = dial_result.call.prompt_tts( collect_params, 'how many hamburgers would you like to order?')
16
+ result = dial_result.call.prompt_tts collect: collect_params, text: 'how many hamburgers would you like to order?')
17
17
 
18
- dial_result.call.play_tts "You ordered #{result.result} hamburgers. Thank you!"
18
+ dial_result.call.play_tts text: "You ordered #{result.result} hamburgers. Thank you!"
19
19
  dial_result.call.hangup
20
20
  # this makes it so the errors don't stop the process
21
21
  rescue StandardError => e
@@ -14,7 +14,7 @@ class OutboundConsumer < Signalwire::Relay::Consumer
14
14
  logger.info 'Dialing out'
15
15
  call = client.calling.new_call(from: ENV['FROM_NUMBER'], to: ENV['TO_NUMBER'])
16
16
  call.dial
17
- call.play_tts 'the quick brown fox jumps over the lazy dog', 'en-US', 'male'
17
+ call.play_tts text: 'the quick brown fox jumps over the lazy dog', language: 'en-US', gender: 'male'
18
18
  call.hangup
19
19
  end
20
20
  end
@@ -14,9 +14,9 @@ class OutboundConsumer < Signalwire::Relay::Consumer
14
14
  logger.info 'Dialing out'
15
15
  call = client.calling.new_call(from: ENV['FROM_NUMBER'], to: ENV['TO_NUMBER'])
16
16
  call.dial
17
- call.play_tts 'please leave your message after the beep. Press pound when done.'
17
+ call.play_tts text: 'please leave your message after the beep. Press pound when done.'
18
18
  result = call.record({"audio": { "beep": "true", "terminators": "#"}})
19
- call.play_tts 'you said:'
19
+ call.play_tts text: 'you said:'
20
20
  call.play_audio result.url
21
21
  call.hangup
22
22
  end
@@ -12,14 +12,14 @@ class MyConsumer < Signalwire::Relay::Consumer
12
12
  contexts ['incoming']
13
13
  def on_incoming_call(call)
14
14
  call.answer
15
- call.play_tts 'Welcome to Relay'
15
+ call.play_tts text: 'Welcome to Relay'
16
16
  dial = call.connect [[{ type: 'phone', params: { to_number: MY_NUMBER, from_number: call.from, timeout: 30 } }]]
17
17
  pp "Connected"
18
18
  pp dial.successful
19
- dial.call.play_tts "Hello!" if dial.successful
19
+ dial.call.play_tts(text: "Hello!") if dial.successful
20
20
  pp "Waiting on Ending"
21
21
  dial.call.wait_for_ending
22
- call.play_tts 'finished. hanging up.'
22
+ call.play_tts text: 'finished. hanging up.'
23
23
  call.hangup
24
24
  rescue StandardError => e
25
25
  logger.error e.inspect
@@ -37,9 +37,9 @@ module Signalwire::Blade
37
37
  end
38
38
 
39
39
  def reconnect!
40
+ @connected = false
40
41
  return if @shutdown
41
42
  sleep Signalwire::Blade::RECONNECT_PERIOD
42
- @connected = false
43
43
  logger.info "Attempting reconnection"
44
44
  main_loop!
45
45
  end
@@ -66,20 +66,22 @@ module Signalwire::Blade
66
66
 
67
67
  def setup_started_event
68
68
  on :started do |_event|
69
- @connected = true
70
- myreq = connect_request
71
- start_periodic_timer
72
-
73
- write_command(myreq) do |event|
74
- @session_id = event.dig(:result, :sessionid) unless @session_id
75
- @node_id = event.dig(:result, :nodeid) unless @node_d
76
- logger.info "Blade Session connected with id: #{@session_id}"
77
- broadcast :connected, event
69
+ begin
70
+ @connected = true
71
+ myreq = connect_request
72
+ start_periodic_timer
73
+
74
+ write_command(myreq) do |event|
75
+ @session_id = event.dig(:result, :sessionid) unless @session_id
76
+ @node_id = event.dig(:result, :nodeid) unless @node_d
77
+ logger.info "Blade Session connected with id: #{@session_id}"
78
+ broadcast :connected, event
79
+ end
80
+
81
+ rescue StandardError => e
82
+ logger.error e.inspect
83
+ logger.error e.backtrace
78
84
  end
79
-
80
- rescue StandardError => e
81
- logger.error e.inspect
82
- logger.error e.backtrace
83
85
  end
84
86
  end
85
87
 
@@ -107,10 +109,20 @@ module Signalwire::Blade
107
109
  end
108
110
 
109
111
  def write_command(command, &block)
110
- once(:message, id: command.id, &block) if block_given?
112
+ if block_given?
113
+ once :message, id: command.id do |event|
114
+ handle_execute_response(event, &block)
115
+ end
116
+ end
117
+
111
118
  transmit(command.build_request.to_json)
112
119
  end
113
120
 
121
+ def handle_execute_response(event, &block)
122
+ logger.error("Blade error occurred, code #{event.error_code}: #{event.error_message}") if event.error?
123
+ block.call(event)
124
+ end
125
+
114
126
  def execute(params, &block)
115
127
  block_given? ? write_command(Execute.new(params), &block) : write_command(Execute.new(params))
116
128
  end
@@ -163,11 +175,13 @@ module Signalwire::Blade
163
175
  # reconnect logic goes here
164
176
  logger.error "We got disconnected!"
165
177
  pinger.cancel
166
- reconnect!
178
+ reconnect! if connected?
167
179
  end
168
-
169
- @ws.ping 'detecting presence' do
170
- timeouter.cancel
180
+
181
+ if @connected
182
+ @ws.ping 'detecting presence' do
183
+ timeouter.cancel
184
+ end
171
185
  end
172
186
  end
173
187
  end
@@ -34,5 +34,17 @@ module Signalwire::Blade
34
34
  def to_s
35
35
  inspect
36
36
  end
37
+
38
+ def error?
39
+ @payload.has_key?(:error)
40
+ end
41
+
42
+ def error_code
43
+ @payload.dig(:error, :code)
44
+ end
45
+
46
+ def error_message
47
+ @payload.dig(:error, :message)
48
+ end
37
49
  end
38
50
  end
@@ -117,16 +117,20 @@ module Signalwire::Relay::Calling
117
117
  PlayAction.new(component: play_component)
118
118
  end
119
119
 
120
- def prompt(collect_object, play_object)
121
- component = Prompt.new(call: self, collect: collect_object, play: play_object)
120
+ def prompt(collect_p = nil, play_p = nil, collect: nil, play: nil)
121
+ set_parameters(binding, %i{collect play}, %i{collect play})
122
+
123
+ component = Prompt.new(call: self, collect: collect, play: play)
122
124
  component.wait_for(Relay::CallPromptState::ERROR, Relay::CallPromptState::NO_INPUT,
123
125
  Relay::CallPromptState::NO_MATCH, Relay::CallPromptState::DIGIT,
124
126
  Relay::CallPromptState::SPEECH)
125
127
  PromptResult.new(component: component)
126
128
  end
127
129
 
128
- def prompt!(collect_object, play_object)
129
- component = Prompt,new(call: self, collect: collect_object, play: play_object)
130
+ def prompt!(collect_p = nil, play_p = nil, collect: nil, play: nil)
131
+ set_parameters(binding, %i{collect play}, %i{collect play})
132
+
133
+ component = Prompt,new(call: self, collect: collect, play: play)
130
134
  component.execute
131
135
  PromptAction.new(component: component)
132
136
  end
@@ -247,5 +251,14 @@ module Signalwire::Relay::Calling
247
251
  @busy = false
248
252
  @failed = false
249
253
  end
254
+
255
+ def set_parameters(passed_binding, keys, mandatory_keys)
256
+ keys.each do |x|
257
+ passed_binding.local_variable_set(x, passed_binding.local_variable_get(x) || passed_binding.local_variable_get("#{x}_p"))
258
+ end
259
+ mandatory_keys.each do |x|
260
+ raise ArgumentError if passed_binding.local_variable_get(x).nil?
261
+ end
262
+ end
250
263
  end
251
264
  end
@@ -16,36 +16,50 @@ module Signalwire::Relay::Calling
16
16
  play! silence_payload(duration)
17
17
  end
18
18
 
19
- def play_tts(sentence, language='en-US', gender='female')
20
- play tts_payload(sentence, language, gender)
19
+ def play_tts(text_p=nil, language_p=Relay::DEFAULT_LANGUAGE, gender_p=Relay::DEFAULT_GENDER, text: nil, language: Relay::DEFAULT_LANGUAGE, gender: Relay::DEFAULT_GENDER)
20
+ set_parameters(binding, %i{text language gender}, %i{text})
21
+
22
+ play tts_payload(text, language, gender)
21
23
  end
22
24
 
23
- def play_tts!(sentence, language='en-US', gender='female')
24
- play! tts_payload(sentence, language, gender)
25
+ def play_tts!(text_p=nil, language_p=Relay::DEFAULT_LANGUAGE, gender_p=Relay::DEFAULT_GENDER, text: nil, language: Relay::DEFAULT_LANGUAGE, gender: Relay::DEFAULT_GENDER)
26
+ set_parameters(binding, %i{text language gender}, %i{text})
27
+ play! tts_payload(text, language, gender)
25
28
  end
26
29
 
27
- def prompt_audio(collect, url)
30
+ def prompt_audio(collect_p = nil, url_p = nil, collect: nil, url: nil)
31
+ set_parameters(binding, %i{collect url}, %i{collect url})
32
+
28
33
  prompt(collect, audio_payload(url))
29
34
  end
30
35
 
31
- def prompt_audio!(collect, url)
36
+ def prompt_audio!(collect_p = nil, url_p = nil, collect: nil, url: nil)
37
+ set_parameters(binding, %i{collect url}, %i{collect url})
38
+
32
39
  prompt!(collect, audio_payload(url))
33
40
  end
34
41
 
35
- def prompt_silence(collect, duration)
42
+ def prompt_silence(collect_p = nil, duration_p = nil, collect: nil, duration: nil)
43
+ set_parameters(binding, %i{collect duration}, %i{collect duration})
44
+
36
45
  prompt(collect, silence_payload(duration))
37
46
  end
38
47
 
39
- def prompt_silence!(collect, url)
48
+ def prompt_silence!(collect_p = nil, duration_p = nil, collect: nil, duration: nil)
49
+ set_parameters(binding, %i{collect duration}, %i{collect duration})
50
+
40
51
  prompt!(collect, silence_payload(duration))
41
52
  end
42
53
 
43
- def prompt_tts(collect, sentence, language='en-US', gender='female')
44
- prompt(collect, tts_payload(sentence, language, gender))
54
+ def prompt_tts(collect_p = nil, text_p = nil, language_p=Relay::DEFAULT_LANGUAGE, gender_p=Relay::DEFAULT_GENDER, collect: nil, text: nil, language: Relay::DEFAULT_LANGUAGE, gender: Relay::DEFAULT_GENDER)
55
+ set_parameters(binding, %i{collect text language gender}, %i{collect text})
56
+ prompt(collect, tts_payload(text, language, gender))
45
57
  end
46
58
 
47
- def prompt_tts!(collect, sentence, language='en-US', gender='female')
48
- prompt!(collect, tts_payload(sentence, language, gender))
59
+ def prompt_tts!(collect_p = nil, text_p = nil, language_p=Relay::DEFAULT_LANGUAGE, gender_p=Relay::DEFAULT_GENDER, collect: nil, text: nil, language: Relay::DEFAULT_LANGUAGE, gender: Relay::DEFAULT_GENDER)
60
+ set_parameters(binding, %i{collect text language gender}, %i{collect text})
61
+
62
+ prompt!(collect, tts_payload(text, language, gender))
49
63
  end
50
64
 
51
65
  def wait_for_ringing
@@ -64,6 +78,8 @@ module Signalwire::Relay::Calling
64
78
  wait_for(Relay::CallState::ENDED)
65
79
  end
66
80
 
81
+ private
82
+
67
83
  def audio_payload(url)
68
84
  [{ type: "audio", params: { url: url } }]
69
85
  end
@@ -72,8 +88,8 @@ module Signalwire::Relay::Calling
72
88
  [{ type: "silence", params: { duration: duration } }]
73
89
  end
74
90
 
75
- def tts_payload(sentence, language='en-US', gender='male')
76
- [{ "type": 'tts', "params": { "text": sentence, "language": language, "gender": gender } }]
91
+ def tts_payload(text, language=Relay::DEFAULT_LANGUAGE, gender=Relay::DEFAULT_GENDER)
92
+ [{ "type": 'tts', "params": { "text": text, "language": language, "gender": gender } }]
77
93
  end
78
94
  end
79
95
  end
@@ -79,7 +79,7 @@ module Signalwire::Relay
79
79
  block.call(event, success) if block_given?
80
80
  logger.error "Relay command failed with code #{code} and message: #{message}" unless success
81
81
  else
82
- logger.error 'Unknown Relay command failure, result code not found'
82
+ logger.error("Relay error occurred, code #{event.error_code}: #{event.error_message}") if event.error?
83
83
  block.call(event, :failure) if block_given?
84
84
  end
85
85
  else
@@ -100,7 +100,7 @@ module Signalwire::Relay
100
100
  return if contexts.include?(context)
101
101
  receive_command = {
102
102
  protocol: @protocol,
103
- method: 'call.receive',
103
+ method: 'signalwire.receive',
104
104
  params: {
105
105
  context: context
106
106
  }
@@ -121,7 +121,11 @@ module Signalwire::Relay
121
121
  @session.on :connected do |event|
122
122
  logger.debug 'Relay client connected'
123
123
  broadcast :connecting, event
124
- protocol_setup
124
+ if event.error?
125
+ logger.error("Error setting up Blade connection")
126
+ else
127
+ protocol_setup
128
+ end
125
129
  end
126
130
  end
127
131
 
@@ -149,6 +153,7 @@ module Signalwire::Relay
149
153
  @session.subscribe(notification_request) do
150
154
  logger.debug "Subscribed to notifications for #{protocol}"
151
155
  @connected = true
156
+ @contexts = Concurrent::Array.new
152
157
  broadcast :ready, self
153
158
  end
154
159
  end
@@ -5,6 +5,8 @@ module Signalwire::Relay
5
5
  COMMAND_TIMEOUT = 30
6
6
  DEFAULT_CALL_TIMEOUT = 30
7
7
  PING_TIMEOUT = 5
8
+ DEFAULT_LANGUAGE = 'en-US'
9
+ DEFAULT_GENDER = 'female'
8
10
 
9
11
  module CallState
10
12
  NONE = 'none'
@@ -104,17 +106,17 @@ module Signalwire::Relay
104
106
  end
105
107
 
106
108
  module ComponentMethod
107
- ANSWER = 'call.answer'
108
- CONNECT = 'call.connect'
109
- DIAL = 'call.begin' # BEGIN is a reserved word
110
- HANGUP = 'call.end' # END is a reserved word
111
- PLAY = 'call.play'
112
- PROMPT = 'call.play_and_collect'
113
- RECORD = 'call.record'
114
- SEND_FAX = 'call.send_fax'
115
- RECEIVE_FAX = 'call.receive_fax'
116
- TAP = 'call.tap'
117
- DETECT = 'call.detect'
109
+ ANSWER = 'calling.answer'
110
+ CONNECT = 'calling.connect'
111
+ DIAL = 'calling.begin' # BEGIN is a reserved word
112
+ HANGUP = 'calling.end' # END is a reserved word
113
+ PLAY = 'calling.play'
114
+ PROMPT = 'calling.play_and_collect'
115
+ RECORD = 'calling.record'
116
+ SEND_FAX = 'calling.send_fax'
117
+ RECEIVE_FAX = 'calling.receive_fax'
118
+ TAP = 'calling.tap'
119
+ DETECT = 'calling.detect'
118
120
  end
119
121
 
120
122
  module CommonState
@@ -47,6 +47,11 @@ module Signalwire::Relay
47
47
  def run
48
48
  logger.info "Starting up #{self.class}"
49
49
  setup
50
+
51
+ client.on :ready do
52
+ setup_contexts
53
+ end
54
+
50
55
  client.once :ready do
51
56
  setup_receive_listeners
52
57
  setup_all_events_listener
@@ -70,13 +75,19 @@ module Signalwire::Relay
70
75
  private
71
76
 
72
77
  def setup_receive_listeners
73
- self.class.contexts.each do |cxt|
74
- client.calling.receive context: cxt do |call|
78
+ self.class.contexts.each do |ctx|
79
+ client.calling.receive context: ctx do |call|
75
80
  on_incoming_call(call)
76
81
  end
77
82
  end
78
83
  end
79
84
 
85
+ def setup_contexts
86
+ self.class.contexts.each do |ctx|
87
+ @client.setup_context(ctx)
88
+ end
89
+ end
90
+
80
91
  def setup_task_listeners
81
92
  client.on :task do |task|
82
93
  on_task(task)
@@ -3,7 +3,7 @@
3
3
  module Signalwire::REST
4
4
  class Client < Twilio::REST::Client
5
5
  def initialize(username = nil, password = nil, account_sid = nil, region = nil, http_client = Twilio::HTTP::Client.new, **args)
6
- host = args.delete(:SIGNALWIRE_HOST)
6
+ host = args.delete(:signalwire_space_url)
7
7
 
8
8
  unless host.nil?
9
9
  Signalwire::Sdk.configure do |config|
@@ -12,7 +12,7 @@ module Twilio
12
12
  'SignalWire Space URL is not configured. Enter your SignalWire Space domain via the '\
13
13
  'SIGNALWIRE_HOST environment variable, or hostname in the configuration.')
14
14
 
15
- @base_url = "https://#{@host}/api/laml"
15
+ @base_url = "https://#{@host}"
16
16
  @port = 443
17
17
 
18
18
  # Versions
@@ -14,7 +14,7 @@ module Twilio
14
14
  'SIGNALWIRE_HOST or SIGNALWIRE_API_HOSTNAME environment variables, '\
15
15
  'or hostname in the configuration.')
16
16
 
17
- @base_url = "https://#{@host}/api/laml"
17
+ @base_url = "https://#{@host}"
18
18
  @port = 443
19
19
 
20
20
  # Versions
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Signalwire
4
- VERSION = '2.1.2'
4
+ VERSION = '2.1.3'
5
5
  end
@@ -22,6 +22,8 @@ Gem::Specification.new do |spec|
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ['lib']
24
24
 
25
+ spec.required_ruby_version = '>= 2.0'
26
+
25
27
  spec.add_development_dependency 'bundler', '~> 1.16'
26
28
  spec.add_development_dependency 'bundler-audit', '~> 0.6.1'
27
29
  spec.add_development_dependency 'guard-rspec', '~> 4.7.3'
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.1.2
4
+ version: 2.1.3
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-08-02 00:00:00.000000000 Z
11
+ date: 2019-08-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -350,15 +350,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
350
350
  requirements:
351
351
  - - ">="
352
352
  - !ruby/object:Gem::Version
353
- version: '0'
353
+ version: '2.0'
354
354
  required_rubygems_version: !ruby/object:Gem::Requirement
355
355
  requirements:
356
356
  - - ">="
357
357
  - !ruby/object:Gem::Version
358
358
  version: '0'
359
359
  requirements: []
360
- rubyforge_project:
361
- rubygems_version: 2.5.2.3
360
+ rubygems_version: 3.0.3
362
361
  signing_key:
363
362
  specification_version: 4
364
363
  summary: Ruby client for Signalwire