sms_broker 1.0.2 → 1.0.3
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.
- checksums.yaml +4 -4
- data/lib/sms_broker.rb +5 -0
- data/lib/sms_broker/client/nexmo.rb +18 -0
- data/lib/sms_broker/client/response/error.rb +1 -0
- data/lib/sms_broker/client/response/nexmo_voice_error.rb +21 -0
- data/lib/sms_broker/client/response/nexmo_voice_success.rb +33 -0
- data/lib/sms_broker/client/response/voice_success.rb +31 -0
- data/lib/sms_broker/client/twilio.rb +8 -0
- data/lib/sms_broker/exceptions/not_implemented.rb +7 -0
- data/lib/sms_broker/service.rb +6 -0
- data/lib/sms_broker/version.rb +1 -1
- data/lib/sms_broker/voice_message_sender.rb +90 -0
- data/spec/sms_broker/nexmo_voice_spec.rb +79 -0
- data/spec/sms_broker/real_call_spec.rb +13 -0
- data/spec/support/nexmo_helpers.rb +64 -0
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a4b480fcb3af10834e7dcceab54bb7a11a638fa
|
4
|
+
data.tar.gz: c092ef5cc010867c9defb38a62c4597546d057da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8572edd992371e259eac5aec974a67b346c6f231fd9ca9965b8f9dfe529837b744fbe3981f3ded4de331b6fa4b75e5c92cd478f372a62718620ecee02a7292ff
|
7
|
+
data.tar.gz: 1d32ba4504a1c751ec8e341a57f945166080116459209aecfb8df1435466e9ddb03b6c66521be5111b8b9e5748af45f68103ddcef79f63960eed2cf588f8aa64
|
data/lib/sms_broker.rb
CHANGED
@@ -3,6 +3,7 @@ require 'compel'
|
|
3
3
|
require 'twilio-ruby'
|
4
4
|
require 'sms_broker/client/response/error'
|
5
5
|
require 'sms_broker/client/response/success'
|
6
|
+
require 'sms_broker/client/response/voice_success'
|
6
7
|
require 'sms_broker/configuration'
|
7
8
|
require 'sms_broker/service'
|
8
9
|
|
@@ -18,4 +19,8 @@ module SmsBroker
|
|
18
19
|
def message(body)
|
19
20
|
service.message(body)
|
20
21
|
end
|
22
|
+
|
23
|
+
def voice_message(body)
|
24
|
+
service.voice_message(body)
|
25
|
+
end
|
21
26
|
end
|
@@ -21,6 +21,20 @@ module SmsBroker
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
+
def send_voice_message(message)
|
25
|
+
response = client.initiate_tts_call \
|
26
|
+
text: message[:text],
|
27
|
+
from: message[:from],
|
28
|
+
to: serialize_to_number(message[:to]),
|
29
|
+
lg: message[:lang]
|
30
|
+
|
31
|
+
if voice_success_response?(response)
|
32
|
+
Response::NexmoVoiceSuccess.new(response)
|
33
|
+
else
|
34
|
+
Response::NexmoVoiceError.new(response)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
24
38
|
private
|
25
39
|
|
26
40
|
def success_response?(response)
|
@@ -28,6 +42,10 @@ module SmsBroker
|
|
28
42
|
# right now only one message per call
|
29
43
|
!response['messages'].empty? && response['messages'][0]['status'] == '0'
|
30
44
|
end
|
45
|
+
|
46
|
+
def voice_success_response?(response)
|
47
|
+
response['status'] == '0'
|
48
|
+
end
|
31
49
|
end
|
32
50
|
end
|
33
51
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module SmsBroker
|
2
|
+
module Client
|
3
|
+
module Response
|
4
|
+
class NexmoVoiceError < Error
|
5
|
+
def initialize(nexmo_response)
|
6
|
+
super :nexmo, nexmo_response, serialize_error_response(nexmo_response)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def serialize_error_response(nexmo_response)
|
12
|
+
errors = {}.tap do |hash|
|
13
|
+
hash[nexmo_response['status']] = nexmo_response['error']
|
14
|
+
end
|
15
|
+
|
16
|
+
errors
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module SmsBroker
|
2
|
+
module Client
|
3
|
+
module Response
|
4
|
+
class NexmoVoiceSuccess < VoiceSuccess
|
5
|
+
def initialize(nexmo_response)
|
6
|
+
super :nexmo, nexmo_response, serialize(nexmo_response)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def serialize(response)
|
12
|
+
{
|
13
|
+
call_id: response['call_id'],
|
14
|
+
to: response['to'],
|
15
|
+
raw: response_to_hash(response)
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def response_to_hash(response)
|
20
|
+
attributes = %w(
|
21
|
+
call_id to status error_text
|
22
|
+
)
|
23
|
+
|
24
|
+
{}.tap do |hash|
|
25
|
+
attributes.each do |attr|
|
26
|
+
hash[attr.to_sym] = response[attr]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module SmsBroker
|
2
|
+
module Client
|
3
|
+
module Response
|
4
|
+
class VoiceSuccess
|
5
|
+
attr_reader :raw,
|
6
|
+
:service,
|
7
|
+
:serialized
|
8
|
+
|
9
|
+
def initialize(service, response, serialized)
|
10
|
+
@raw = response
|
11
|
+
@service = service
|
12
|
+
@serialized = serialized
|
13
|
+
end
|
14
|
+
|
15
|
+
def success?
|
16
|
+
true
|
17
|
+
end
|
18
|
+
|
19
|
+
def to
|
20
|
+
serialized[:to]
|
21
|
+
end
|
22
|
+
|
23
|
+
def call_id
|
24
|
+
serialized[:call_id]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
require 'sms_broker/client/response/nexmo_voice_success'
|
@@ -24,6 +24,14 @@ module SmsBroker
|
|
24
24
|
Response::TwilioError.new(exception)
|
25
25
|
end
|
26
26
|
|
27
|
+
def send_voice_message(_message)
|
28
|
+
message = 'twillio voice message integration is not implemented'
|
29
|
+
exception = \
|
30
|
+
Exceptions::NotImplemented.new(message)
|
31
|
+
|
32
|
+
raise exception
|
33
|
+
end
|
34
|
+
|
27
35
|
private
|
28
36
|
|
29
37
|
def success_response?(response)
|
data/lib/sms_broker/service.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
require 'sms_broker/message_sender'
|
2
|
+
require 'sms_broker/voice_message_sender'
|
2
3
|
require 'sms_broker/client/base'
|
3
4
|
require 'sms_broker/client/nexmo'
|
4
5
|
require 'sms_broker/client/twilio'
|
5
6
|
require 'sms_broker/exceptions/invalid_service'
|
7
|
+
require 'sms_broker/exceptions/not_implemented'
|
6
8
|
|
7
9
|
module SmsBroker
|
8
10
|
CLIENTS = {
|
@@ -40,5 +42,9 @@ module SmsBroker
|
|
40
42
|
def message(message)
|
41
43
|
MessageSender.new(client).message(message)
|
42
44
|
end
|
45
|
+
|
46
|
+
def voice_message(message) #could have another params like lang
|
47
|
+
VoiceMessageSender.new(client).message(message)
|
48
|
+
end
|
43
49
|
end
|
44
50
|
end
|
data/lib/sms_broker/version.rb
CHANGED
@@ -0,0 +1,90 @@
|
|
1
|
+
module SmsBroker
|
2
|
+
class VoiceMessageSender
|
3
|
+
attr_reader :client,
|
4
|
+
:errors
|
5
|
+
|
6
|
+
def initialize(client)
|
7
|
+
@client = client
|
8
|
+
end
|
9
|
+
|
10
|
+
def to(number)
|
11
|
+
@voice_message_to = number
|
12
|
+
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def message(text)
|
17
|
+
@voice_message_text = text
|
18
|
+
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def with(options)
|
23
|
+
@voice_message_options = options
|
24
|
+
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def deliver
|
29
|
+
unless valid?
|
30
|
+
return Client::Response::Error.new(client.name, errors, errors)
|
31
|
+
end
|
32
|
+
|
33
|
+
response = client.send_voice_message(build_message)
|
34
|
+
|
35
|
+
if should_try_with_phone_number?(response)
|
36
|
+
return client.send_voice_message(build_message(:phone_number))
|
37
|
+
end
|
38
|
+
|
39
|
+
response
|
40
|
+
end
|
41
|
+
|
42
|
+
def valid?
|
43
|
+
options = @voice_message_options || {}
|
44
|
+
|
45
|
+
schema = {
|
46
|
+
message: Compel.string.required.max_length(140),
|
47
|
+
to: Compel.string.required,
|
48
|
+
lang: Compel.string
|
49
|
+
}
|
50
|
+
|
51
|
+
object = {
|
52
|
+
message: @voice_message_text,
|
53
|
+
to: @voice_message_to,
|
54
|
+
lang: options[:lang]
|
55
|
+
}
|
56
|
+
|
57
|
+
result = Compel.hash.keys(schema).validate(object)
|
58
|
+
|
59
|
+
@errors = result.errors
|
60
|
+
|
61
|
+
result.valid?
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def build_message(from = :sender_id)
|
67
|
+
{
|
68
|
+
text: @voice_message_text,
|
69
|
+
from: get_sender(from),
|
70
|
+
to: @voice_message_to
|
71
|
+
}.merge!(@voice_message_options || {})
|
72
|
+
end
|
73
|
+
|
74
|
+
def get_sender(from)
|
75
|
+
if client.sender_id && from == :sender_id
|
76
|
+
client.sender_id
|
77
|
+
else
|
78
|
+
return client.phone_number if client.phone_number.start_with?('+')
|
79
|
+
|
80
|
+
"+#{client.phone_number}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def should_try_with_phone_number?(response)
|
85
|
+
response.is_a?(Client::Response::Error) &&
|
86
|
+
response.invalid_sender_id? &&
|
87
|
+
client.sender_id
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'pry'
|
2
|
+
|
3
|
+
describe SmsBroker do
|
4
|
+
context 'Nexmo', :focus do
|
5
|
+
context '#send_message' do
|
6
|
+
let(:voice_message) { 'Hello World' }
|
7
|
+
let(:from_phone) { '+447476543210' }
|
8
|
+
let(:sender_id) { 'SenderID' }
|
9
|
+
let(:lang) { 'en-GB' }
|
10
|
+
let(:to_phone) { '+447491234567' }
|
11
|
+
let(:api_secret) { 'api_secret' }
|
12
|
+
let(:api_key) { 'api_key' }
|
13
|
+
|
14
|
+
before(:each) do
|
15
|
+
SmsBroker.clear_setup
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'valid', :focus do
|
19
|
+
it 'should send voice message with success' do
|
20
|
+
SmsBroker.setup do |config|
|
21
|
+
config.nexmo_setup \
|
22
|
+
phone_number: from_phone,
|
23
|
+
sender_id: sender_id,
|
24
|
+
secret: api_secret,
|
25
|
+
key: api_key
|
26
|
+
end
|
27
|
+
|
28
|
+
stub_nexmo_create_voice_message_success(sender_id, to_phone, voice_message, lang)
|
29
|
+
|
30
|
+
response = SmsBroker
|
31
|
+
.voice_message(voice_message)
|
32
|
+
.to(to_phone)
|
33
|
+
.with(lang: lang)
|
34
|
+
.deliver
|
35
|
+
|
36
|
+
expect(response.service).to eq(:nexmo)
|
37
|
+
expect(response.success?).to eq(true)
|
38
|
+
expect(response.call_id).not_to eq(nil)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'invalid' do
|
43
|
+
it 'should return error for invalid credentials' do
|
44
|
+
SmsBroker.setup do |config|
|
45
|
+
config.nexmo_setup \
|
46
|
+
phone_number: from_phone,
|
47
|
+
secret: 'invalid',
|
48
|
+
key: 'invalid'
|
49
|
+
end
|
50
|
+
|
51
|
+
stub_nexmo_create_voice_message_invalid_credentials \
|
52
|
+
from_phone, to_phone, voice_message
|
53
|
+
|
54
|
+
response = SmsBroker.voice_message(voice_message).to(to_phone).deliver
|
55
|
+
|
56
|
+
expect(response.success?).to eq(false)
|
57
|
+
expect(response.serialized.length).to be > 0
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should return error an unknown error' do
|
61
|
+
SmsBroker.setup do |config|
|
62
|
+
config.nexmo_setup \
|
63
|
+
phone_number: from_phone,
|
64
|
+
secret: api_secret,
|
65
|
+
key: api_key
|
66
|
+
end
|
67
|
+
|
68
|
+
stub_nexmo_create_voice_message_unknown_error \
|
69
|
+
from_phone, to_phone, voice_message
|
70
|
+
|
71
|
+
response = SmsBroker.voice_message(voice_message).to(to_phone).deliver
|
72
|
+
|
73
|
+
expect(response.success?).to eq(false)
|
74
|
+
expect(response.serialized.length).to be > 0
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
describe SmsBroker do
|
2
2
|
context 'SmsBroker' do
|
3
3
|
let(:text_message) { 'Hello World' }
|
4
|
+
let(:voice_text_message) { 'This is a voice message test, please ignore' }
|
4
5
|
|
5
6
|
context 'Valid real calls' do
|
6
7
|
before(:all) do
|
@@ -47,6 +48,18 @@ describe SmsBroker do
|
|
47
48
|
end
|
48
49
|
end
|
49
50
|
|
51
|
+
context 'Nexmo voice call', :real_deal do
|
52
|
+
it 'should successfuly send the voice message' do
|
53
|
+
voice_message = \
|
54
|
+
SmsBroker
|
55
|
+
.service(:nexmo)
|
56
|
+
.voice_message(voice_text_message)
|
57
|
+
.to(ENV['REAL_PHONE_NUMBER'])
|
58
|
+
|
59
|
+
expect(voice_message.deliver.success?).to eq true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
50
63
|
context 'Twillio' do
|
51
64
|
it 'should successfuly send message' do
|
52
65
|
message = \
|
@@ -13,6 +13,18 @@ module NexmoHelpers
|
|
13
13
|
)
|
14
14
|
end
|
15
15
|
|
16
|
+
def stub_nexmo_create_voice_message(request_body, response_body)
|
17
|
+
stub_request(:post, 'https://api.nexmo.com/tts/json')
|
18
|
+
.with(body: request_body)
|
19
|
+
.to_return(
|
20
|
+
status: 200,
|
21
|
+
body: response_body.to_json,
|
22
|
+
headers: {
|
23
|
+
'Content-Type' => 'application/json'
|
24
|
+
}
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
16
28
|
def build_request_body(from, to, message)
|
17
29
|
{
|
18
30
|
to: to,
|
@@ -23,6 +35,16 @@ module NexmoHelpers
|
|
23
35
|
}
|
24
36
|
end
|
25
37
|
|
38
|
+
def build_voice_request_body(from, to, message, lang = nil)
|
39
|
+
{
|
40
|
+
to: to,
|
41
|
+
from: from,
|
42
|
+
text: message,
|
43
|
+
api_key: 'api_key',
|
44
|
+
api_secret: 'api_secret'
|
45
|
+
}.merge(lg: lang)
|
46
|
+
end
|
47
|
+
|
26
48
|
def stub_nexmo_create_message_invalid_sender_id_request(sender_id, to, message)
|
27
49
|
request_body = build_request_body(sender_id, to, message)
|
28
50
|
|
@@ -94,4 +116,46 @@ module NexmoHelpers
|
|
94
116
|
|
95
117
|
stub_nexmo_create_message(request_body, response_body)
|
96
118
|
end
|
119
|
+
|
120
|
+
def stub_nexmo_create_voice_message_success(from, to, message, lang)
|
121
|
+
request_body = build_voice_request_body(from, to, message, lang)
|
122
|
+
|
123
|
+
response_body = {
|
124
|
+
'call_id': '1',
|
125
|
+
'to': to,
|
126
|
+
'status': '0',
|
127
|
+
'error_text': ''
|
128
|
+
}
|
129
|
+
|
130
|
+
stub_nexmo_create_voice_message(request_body, response_body)
|
131
|
+
end
|
132
|
+
|
133
|
+
def stub_nexmo_create_voice_message_invalid_credentials(from, to, message)
|
134
|
+
request_body = build_voice_request_body(from, to, message)
|
135
|
+
request_body.merge! \
|
136
|
+
api_key: 'invalid',
|
137
|
+
api_secret: 'invalid'
|
138
|
+
|
139
|
+
response_body = {
|
140
|
+
'call_id': '1',
|
141
|
+
'to': to,
|
142
|
+
'status': '4',
|
143
|
+
'error_text': 'Invalid credentials'
|
144
|
+
}
|
145
|
+
|
146
|
+
stub_nexmo_create_voice_message(request_body, response_body)
|
147
|
+
end
|
148
|
+
|
149
|
+
def stub_nexmo_create_voice_message_unknown_error(from, to, message)
|
150
|
+
request_body = build_voice_request_body(from, to, message)
|
151
|
+
|
152
|
+
response_body = {
|
153
|
+
'call_id': '1',
|
154
|
+
'to': to,
|
155
|
+
'status': '5',
|
156
|
+
'error_text': 'An error has occurred in the Nexmo platform while processing this request'
|
157
|
+
}
|
158
|
+
|
159
|
+
stub_nexmo_create_voice_message(request_body, response_body)
|
160
|
+
end
|
97
161
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sms_broker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Streetbees Dev Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nexmo
|
@@ -128,19 +128,25 @@ files:
|
|
128
128
|
- lib/sms_broker/client/response/error.rb
|
129
129
|
- lib/sms_broker/client/response/nexmo_error.rb
|
130
130
|
- lib/sms_broker/client/response/nexmo_success.rb
|
131
|
+
- lib/sms_broker/client/response/nexmo_voice_error.rb
|
132
|
+
- lib/sms_broker/client/response/nexmo_voice_success.rb
|
131
133
|
- lib/sms_broker/client/response/success.rb
|
132
134
|
- lib/sms_broker/client/response/twilio_error.rb
|
133
135
|
- lib/sms_broker/client/response/twilio_success.rb
|
136
|
+
- lib/sms_broker/client/response/voice_success.rb
|
134
137
|
- lib/sms_broker/client/twilio.rb
|
135
138
|
- lib/sms_broker/configuration.rb
|
136
139
|
- lib/sms_broker/exceptions/invalid_service.rb
|
137
140
|
- lib/sms_broker/exceptions/invalid_setup.rb
|
141
|
+
- lib/sms_broker/exceptions/not_implemented.rb
|
138
142
|
- lib/sms_broker/message_sender.rb
|
139
143
|
- lib/sms_broker/service.rb
|
140
144
|
- lib/sms_broker/setup.rb
|
141
145
|
- lib/sms_broker/version.rb
|
146
|
+
- lib/sms_broker/voice_message_sender.rb
|
142
147
|
- sms_broker.gemspec
|
143
148
|
- spec/sms_broker/nexmo_spec.rb
|
149
|
+
- spec/sms_broker/nexmo_voice_spec.rb
|
144
150
|
- spec/sms_broker/real_call_spec.rb
|
145
151
|
- spec/sms_broker/setup_spec.rb
|
146
152
|
- spec/sms_broker/sms_broker_spec.rb
|
@@ -174,6 +180,7 @@ specification_version: 4
|
|
174
180
|
summary: Sms Broker
|
175
181
|
test_files:
|
176
182
|
- spec/sms_broker/nexmo_spec.rb
|
183
|
+
- spec/sms_broker/nexmo_voice_spec.rb
|
177
184
|
- spec/sms_broker/real_call_spec.rb
|
178
185
|
- spec/sms_broker/setup_spec.rb
|
179
186
|
- spec/sms_broker/sms_broker_spec.rb
|