signalwire 2.3.3 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +10 -0
- data/.github/workflows/ci.yml +25 -0
- data/CHANGELOG.md +11 -1
- data/README.md +4 -3
- data/lib/signalwire/blade/connection.rb +22 -13
- data/lib/signalwire/blade/message/connect.rb +2 -1
- data/lib/signalwire/relay/calling/action/connect_action.rb +1 -1
- data/lib/signalwire/relay/calling/action/detect_action.rb +1 -1
- data/lib/signalwire/relay/calling/action/fax_action.rb +1 -1
- data/lib/signalwire/relay/calling/action/play_action.rb +1 -1
- data/lib/signalwire/relay/calling/action/prompt_action.rb +1 -1
- data/lib/signalwire/relay/calling/action/record_action.rb +1 -1
- data/lib/signalwire/relay/calling/action/send_digits_action.rb +1 -1
- data/lib/signalwire/relay/calling/action/tap_action.rb +1 -1
- data/lib/signalwire/relay/calling/call.rb +4 -2
- data/lib/signalwire/relay/calling/component/record.rb +1 -1
- data/lib/signalwire/sdk.rb +1 -0
- data/lib/signalwire/version.rb +1 -1
- data/lib/signalwire/webhook/validate_request.rb +56 -0
- data/lib/signalwire.rb +1 -0
- data/signalwire.gemspec +3 -3
- metadata +16 -14
- data/.drone.yml +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2041c5f950f029c9b9d7d6aab709868d0d6ff19eab4fe288171d145ec310b996
|
4
|
+
data.tar.gz: 7f00185024b6fbdd22d9bf21af089cc29fdecfce59ffec43ab861d8252b96ba6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 130c9720b336190492e270d82e54b7958f44f3e0523fc41a24f6721ddc0ff22c00e0bb87317cee256fb92a233177433161c5d1536bdbe487344b8d7ae7a1263f
|
7
|
+
data.tar.gz: cdb660adf6bbced09c63d4bbd331dd35c7d7697fcf4d9675b4ac783889e8604efcd720b827998fb548cf304253f4522666e9c366a8abb1bed5cd6b7f5ffbc9ec
|
@@ -0,0 +1,25 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ "main" ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ "main" ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
name: Test
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
strategy:
|
14
|
+
fail-fast: false
|
15
|
+
matrix:
|
16
|
+
ruby-version: ['2.6', '2.7', '3.0', '3.1', '3.2']
|
17
|
+
steps:
|
18
|
+
- uses: actions/checkout@v4
|
19
|
+
- name: Set up Ruby
|
20
|
+
uses: ruby/setup-ruby@v1
|
21
|
+
with:
|
22
|
+
ruby-version: ${{ matrix.ruby-version }}
|
23
|
+
bundler-cache: true
|
24
|
+
- name: Run tests
|
25
|
+
run: bundle exec rspec
|
data/CHANGELOG.md
CHANGED
@@ -3,7 +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
|
-
## [Unreleased]
|
6
|
+
## [Unreleased]
|
7
|
+
|
8
|
+
## [2.4.0] - 2023-
|
9
|
+
### Added
|
10
|
+
- Add Webhook `ValidateRequest`
|
11
|
+
|
12
|
+
## [2.3.4] - 2020-09-09
|
13
|
+
### Fixed
|
14
|
+
- Correctly ignore non-call events and clear handlers on call end
|
15
|
+
- Async method arguments fixed
|
16
|
+
- Fix ping race condition
|
7
17
|
|
8
18
|
## [2.3.3] - 2020-03-09
|
9
19
|
### Fixed
|
data/README.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# SignalWire Ruby
|
2
2
|
|
3
3
|
|
4
|
-
[![
|
4
|
+
[![CI](https://github.com/signalwire/signalwire-ruby/actions/workflows/ci.yml/badge.svg)](https://github.com/signalwire/signalwire-ruby/actions/workflows/ci.yml)
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/signalwire.svg)](https://badge.fury.io/rb/signalwire)
|
5
6
|
|
6
7
|
The Relay SDK for Ruby enables Ruby developers to connect and use SignalWire's Relay APIs within their own Ruby code. Our Relay SDK allows developers to build or add robust and innovative communication services to their applications.
|
7
8
|
|
@@ -34,5 +35,5 @@ Relay SDK forRuby follows Semantic Versioning 2.0 as defined at <http://semver.o
|
|
34
35
|
|
35
36
|
## License
|
36
37
|
|
37
|
-
Relay SDK for Ruby is copyright © 2018-
|
38
|
-
[SignalWire](http://signalwire.com). It is free software, and may be redistributed under the terms specified in the [MIT-LICENSE](https://github.com//signalwire/signalwire-ruby/blob/master/LICENSE) file.
|
38
|
+
Relay SDK for Ruby is copyright © 2018-2023
|
39
|
+
[SignalWire](http://signalwire.com). It is free software, and may be redistributed under the terms specified in the [MIT-LICENSE](https://github.com//signalwire/signalwire-ruby/blob/master/LICENSE) file.
|
@@ -4,6 +4,7 @@ require 'has_guarded_handlers'
|
|
4
4
|
require 'eventmachine'
|
5
5
|
require 'faye/websocket'
|
6
6
|
require 'json'
|
7
|
+
require 'concurrent-ruby'
|
7
8
|
|
8
9
|
module Signalwire::Blade
|
9
10
|
class Connection
|
@@ -22,10 +23,14 @@ module Signalwire::Blade
|
|
22
23
|
@log_traffic = options.fetch(:log_traffic, true)
|
23
24
|
@authentication = options.fetch(:authentication, nil)
|
24
25
|
|
26
|
+
|
27
|
+
|
25
28
|
@inbound_queue = EM::Queue.new
|
26
29
|
@outbound_queue = EM::Queue.new
|
27
30
|
|
31
|
+
@pong = Concurrent::AtomicBoolean.new
|
28
32
|
@keep_alive_timer = nil
|
33
|
+
@ping_is_sent = Concurrent::AtomicBoolean.new
|
29
34
|
|
30
35
|
@shutdown_list = []
|
31
36
|
end
|
@@ -48,6 +53,7 @@ module Signalwire::Blade
|
|
48
53
|
|
49
54
|
def main_loop!
|
50
55
|
EM.run do
|
56
|
+
logger.info "CREATING SOCKET"
|
51
57
|
@ws = Faye::WebSocket::Client.new(@url)
|
52
58
|
|
53
59
|
@ws.on(:open) { |event| broadcast :started, event }
|
@@ -71,7 +77,7 @@ module Signalwire::Blade
|
|
71
77
|
begin
|
72
78
|
@connected = true
|
73
79
|
myreq = connect_request
|
74
|
-
@pong
|
80
|
+
@pong.make_false
|
75
81
|
|
76
82
|
write_command(myreq) do |event|
|
77
83
|
@session_id = event.dig(:result, :sessionid) unless @session_id
|
@@ -131,7 +137,9 @@ module Signalwire::Blade
|
|
131
137
|
end
|
132
138
|
|
133
139
|
def ping(&block)
|
134
|
-
|
140
|
+
ping_cmd = Ping.new
|
141
|
+
block_given? ? write_command(ping_cmd, &block) : write_command(ping_cmd)
|
142
|
+
ping_cmd
|
135
143
|
end
|
136
144
|
|
137
145
|
def subscribe(params, &block)
|
@@ -150,7 +158,6 @@ module Signalwire::Blade
|
|
150
158
|
end
|
151
159
|
|
152
160
|
def disconnect!
|
153
|
-
# logger.info 'Stopping Blade event loop'
|
154
161
|
clear_connections
|
155
162
|
EM.stop
|
156
163
|
end
|
@@ -183,19 +190,21 @@ module Signalwire::Blade
|
|
183
190
|
end
|
184
191
|
|
185
192
|
def keep_alive
|
186
|
-
@
|
187
|
-
|
188
|
-
|
189
|
-
|
193
|
+
if @ping_is_sent.false?
|
194
|
+
ping do
|
195
|
+
@pong.make_true
|
196
|
+
end
|
197
|
+
@ping_is_sent.make_true
|
198
|
+
else
|
199
|
+
if @pong.false?
|
200
|
+
logger.error "KEEPALIVE: Ping failed"
|
201
|
+
reconnect! if connected?
|
202
|
+
end
|
203
|
+
@ping_is_sent.make_false
|
190
204
|
end
|
191
205
|
|
192
206
|
@keep_alive_timer = EventMachine::Timer.new(Signalwire::Relay::PING_TIMEOUT) do
|
193
|
-
|
194
|
-
logger.error "Ping failed"
|
195
|
-
reconnect! if connected?
|
196
|
-
else
|
197
|
-
keep_alive
|
198
|
-
end
|
207
|
+
keep_alive
|
199
208
|
end
|
200
209
|
end
|
201
210
|
|
@@ -45,7 +45,7 @@ module Signalwire::Relay::Calling
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def setup_call_event_handlers
|
48
|
-
@client.on(:event, proc { |evt| call_match_event(evt) }) do |event|
|
48
|
+
@call_event_handler = @client.on(:event, proc { |evt| call_match_event(evt) }) do |event|
|
49
49
|
case event.event_type
|
50
50
|
when 'calling.call.connect'
|
51
51
|
change_connect_state(event.call_params[:connect_state])
|
@@ -81,7 +81,8 @@ module Signalwire::Relay::Calling
|
|
81
81
|
end
|
82
82
|
|
83
83
|
def call_match_event(event)
|
84
|
-
event.event_type
|
84
|
+
event.event_type &&
|
85
|
+
event.event_type.match(/calling\.call/) &&
|
85
86
|
!event.event_type.match(/receive/) &&
|
86
87
|
(event.call_id == id || event.call_params[:tag] == tag)
|
87
88
|
end
|
@@ -316,6 +317,7 @@ module Signalwire::Relay::Calling
|
|
316
317
|
end
|
317
318
|
|
318
319
|
def finish_call(params)
|
320
|
+
@client.unregister_handler(:event, @call_event_handler)
|
319
321
|
terminate_components(params)
|
320
322
|
client.calling.end_call(id)
|
321
323
|
@busy = true if params[:reason] == Relay::DisconnectReason::BUSY
|
data/lib/signalwire/sdk.rb
CHANGED
data/lib/signalwire/version.rb
CHANGED
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'openssl'
|
4
|
+
|
5
|
+
module Signalwire::Webhook
|
6
|
+
class ValidateRequest
|
7
|
+
attr_reader :private_key
|
8
|
+
|
9
|
+
def initialize(private_key)
|
10
|
+
@private_key = private_key
|
11
|
+
raise ArgumentError, 'Private key is required' if @private_key.nil?
|
12
|
+
end
|
13
|
+
|
14
|
+
def validate(url, raw_body, header)
|
15
|
+
return false if header.nil? || url.nil?
|
16
|
+
|
17
|
+
# compatibility validation for POST parameters of x-www-form-urlencoded requests
|
18
|
+
if raw_body.is_a?(Hash)
|
19
|
+
return validate_with_compatibility_api(url, raw_body, header)
|
20
|
+
end
|
21
|
+
|
22
|
+
# relay json validation
|
23
|
+
payload = url + raw_body
|
24
|
+
expected_signature = compute_signature(payload)
|
25
|
+
valid = secure_compare(expected_signature, header)
|
26
|
+
|
27
|
+
return true if valid
|
28
|
+
|
29
|
+
# fallback compatibilty json validation
|
30
|
+
validate_with_compatibility_api(url, raw_body, header)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def validate_with_compatibility_api(url, params, signature)
|
36
|
+
validator = Twilio::Security::RequestValidator.new(private_key)
|
37
|
+
validator.validate(url, params, signature)
|
38
|
+
end
|
39
|
+
|
40
|
+
def compute_signature(payload)
|
41
|
+
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), private_key, payload)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Constant time string comparison, from ActiveSupport
|
45
|
+
def secure_compare(a, b)
|
46
|
+
return false if a.nil? || b.nil?
|
47
|
+
return false unless a.bytesize == b.bytesize
|
48
|
+
|
49
|
+
l = a.unpack "C#{a.bytesize}"
|
50
|
+
|
51
|
+
res = 0
|
52
|
+
b.each_byte { |byte| res |= byte ^ l.shift }
|
53
|
+
res == 0
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/signalwire.rb
CHANGED
data/signalwire.gemspec
CHANGED
@@ -27,17 +27,17 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.add_development_dependency 'bundler', '~> 2.1'
|
28
28
|
spec.add_development_dependency 'bundler-audit', '~> 0.6'
|
29
29
|
spec.add_development_dependency 'guard-rspec', '~> 4.7'
|
30
|
-
spec.add_development_dependency 'rake', '~>
|
30
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
31
31
|
spec.add_development_dependency 'rdoc', '~> 6.1'
|
32
32
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
33
33
|
spec.add_development_dependency 'rubocop', '~> 0.67'
|
34
34
|
spec.add_development_dependency 'ruby-prof', '~> 0.17'
|
35
35
|
spec.add_development_dependency 'simplecov', '~> 0.16'
|
36
|
-
spec.add_development_dependency 'vcr', '~>
|
36
|
+
spec.add_development_dependency 'vcr', '~> 5.0'
|
37
37
|
spec.add_development_dependency 'webmock', '~> 3.5'
|
38
38
|
|
39
39
|
spec.add_dependency 'twilio-ruby', '~> 5.0'
|
40
|
-
spec.add_dependency 'faye-websocket', '~> 0.
|
40
|
+
spec.add_dependency 'faye-websocket', '~> 0.11'
|
41
41
|
spec.add_dependency 'concurrent-ruby', '~> 1.1'
|
42
42
|
spec.add_dependency 'has-guarded-handlers', '~> 1.6.3'
|
43
43
|
spec.add_dependency 'logger', '~> 1.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.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- SignalWire Team
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '13.0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '13.0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rdoc
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,14 +142,14 @@ dependencies:
|
|
142
142
|
requirements:
|
143
143
|
- - "~>"
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: '
|
145
|
+
version: '5.0'
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
150
|
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: '
|
152
|
+
version: '5.0'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: webmock
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -184,14 +184,14 @@ dependencies:
|
|
184
184
|
requirements:
|
185
185
|
- - "~>"
|
186
186
|
- !ruby/object:Gem::Version
|
187
|
-
version: '0.
|
187
|
+
version: '0.11'
|
188
188
|
type: :runtime
|
189
189
|
prerelease: false
|
190
190
|
version_requirements: !ruby/object:Gem::Requirement
|
191
191
|
requirements:
|
192
192
|
- - "~>"
|
193
193
|
- !ruby/object:Gem::Version
|
194
|
-
version: '0.
|
194
|
+
version: '0.11'
|
195
195
|
- !ruby/object:Gem::Dependency
|
196
196
|
name: concurrent-ruby
|
197
197
|
requirement: !ruby/object:Gem::Requirement
|
@@ -234,7 +234,7 @@ dependencies:
|
|
234
234
|
- - "~>"
|
235
235
|
- !ruby/object:Gem::Version
|
236
236
|
version: '1.3'
|
237
|
-
description:
|
237
|
+
description:
|
238
238
|
email:
|
239
239
|
- open.source@signalwire.com
|
240
240
|
executables: []
|
@@ -242,7 +242,8 @@ extensions: []
|
|
242
242
|
extra_rdoc_files: []
|
243
243
|
files:
|
244
244
|
- ".document"
|
245
|
-
- ".
|
245
|
+
- ".github/dependabot.yml"
|
246
|
+
- ".github/workflows/ci.yml"
|
246
247
|
- ".gitignore"
|
247
248
|
- ".rspec"
|
248
249
|
- ".rubocop.yml"
|
@@ -350,12 +351,13 @@ files:
|
|
350
351
|
- lib/signalwire/sdk/twilio_set_host.rb
|
351
352
|
- lib/signalwire/sdk/voice_response.rb
|
352
353
|
- lib/signalwire/version.rb
|
354
|
+
- lib/signalwire/webhook/validate_request.rb
|
353
355
|
- signalwire.gemspec
|
354
356
|
homepage: https://github.com/signalwire/signalwire-ruby
|
355
357
|
licenses:
|
356
358
|
- MIT
|
357
359
|
metadata: {}
|
358
|
-
post_install_message:
|
360
|
+
post_install_message:
|
359
361
|
rdoc_options: []
|
360
362
|
require_paths:
|
361
363
|
- lib
|
@@ -370,8 +372,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
370
372
|
- !ruby/object:Gem::Version
|
371
373
|
version: '0'
|
372
374
|
requirements: []
|
373
|
-
rubygems_version: 3.
|
374
|
-
signing_key:
|
375
|
+
rubygems_version: 3.4.7
|
376
|
+
signing_key:
|
375
377
|
specification_version: 4
|
376
378
|
summary: Ruby client for Signalwire
|
377
379
|
test_files: []
|