sms_broker 1.0.0 → 1.0.2
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/.rubocop.yml +16 -0
- data/.travis.yml +3 -0
- data/Gemfile +1 -0
- data/Rakefile +1 -1
- data/lib/sms_broker/client/base.rb +7 -8
- data/lib/sms_broker/client/nexmo.rb +6 -17
- data/lib/sms_broker/client/response/error.rb +1 -5
- data/lib/sms_broker/client/response/nexmo_error.rb +1 -5
- data/lib/sms_broker/client/response/nexmo_success.rb +13 -13
- data/lib/sms_broker/client/response/success.rb +0 -4
- data/lib/sms_broker/client/response/twilio_error.rb +5 -9
- data/lib/sms_broker/client/response/twilio_success.rb +14 -19
- data/lib/sms_broker/client/twilio.rb +16 -31
- data/lib/sms_broker/configuration.rb +9 -13
- data/lib/sms_broker/exceptions/invalid_service.rb +0 -3
- data/lib/sms_broker/exceptions/invalid_setup.rb +0 -4
- data/lib/sms_broker/message_sender.rb +14 -15
- data/lib/sms_broker/service.rb +3 -9
- data/lib/sms_broker/setup.rb +8 -12
- data/lib/sms_broker/version.rb +1 -3
- data/lib/sms_broker.rb +2 -6
- data/spec/sms_broker/nexmo_spec.rb +41 -37
- data/spec/sms_broker/real_call_spec.rb +63 -0
- data/spec/sms_broker/setup_spec.rb +12 -26
- data/spec/sms_broker/sms_broker_spec.rb +19 -93
- data/spec/sms_broker/twilio_spec.rb +35 -56
- data/spec/spec_helper.rb +8 -14
- data/spec/support/nexmo_helpers.rb +19 -72
- data/spec/support/vcr_cassettes/twilio/create_invalid_phone_error.yml +61 -0
- data/spec/support/vcr_cassettes/twilio/create_success.yml +68 -0
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed1f6bc1988ca3ab9a96cac009892365ddcf39ef
|
4
|
+
data.tar.gz: c61521552f75df630c6fd9bea3829cc590bffa6f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4b7658d1d99dfa94ef72292f50f813d17ab9e41640c6b351c65b4b71b1a5c2780422923ca00ffe297c44cef357f5a2bb745df944c349edd6e9d3a2dc12b2653
|
7
|
+
data.tar.gz: 8aba81f06d37acbfabb28afd7c4ae3a28b452420c3849b69784573244ee1884c31dfda212c6d583fa3d32a620431f447e48ed57906f68ed870f000dce6bcd4a1
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
Style/MultilineMethodCallIndentation:
|
2
|
+
Enabled: false
|
3
|
+
|
4
|
+
Style/FrozenStringLiteralComment:
|
5
|
+
Enabled: false
|
6
|
+
|
7
|
+
AllCops:
|
8
|
+
TargetRubyVersion: 2.3
|
9
|
+
DisplayCopNames: true
|
10
|
+
Exclude:
|
11
|
+
- 'vendor/**/*'
|
12
|
+
- 'spec/support/*.rb'
|
13
|
+
- '*.gemspec'
|
14
|
+
|
15
|
+
Documentation:
|
16
|
+
Enabled: false
|
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1,24 +1,23 @@
|
|
1
1
|
module SmsBroker
|
2
2
|
module Client
|
3
|
-
|
4
3
|
class Base
|
5
|
-
|
6
4
|
attr_reader :name,
|
7
5
|
:client,
|
8
|
-
:options,
|
9
6
|
:sender_id,
|
10
7
|
:phone_number
|
11
8
|
|
12
|
-
def initialize(name, client)
|
9
|
+
def initialize(name, client, options = {})
|
13
10
|
@name = name
|
14
11
|
@client = client
|
12
|
+
@sender_id = options[:sender_id]
|
13
|
+
@phone_number = options[:phone_number]
|
15
14
|
end
|
16
15
|
|
17
|
-
def
|
18
|
-
|
19
|
-
end
|
16
|
+
def serialize_to_number(number)
|
17
|
+
return number if number.start_with?('+')
|
20
18
|
|
19
|
+
"+#{number}"
|
20
|
+
end
|
21
21
|
end
|
22
|
-
|
23
22
|
end
|
24
23
|
end
|
@@ -1,27 +1,18 @@
|
|
1
1
|
module SmsBroker
|
2
2
|
module Client
|
3
|
-
|
4
3
|
class Nexmo < Base
|
5
|
-
|
6
4
|
def initialize(options)
|
7
|
-
|
8
|
-
|
9
|
-
auth_options = {
|
10
|
-
key: nexmo_options.delete(:key),
|
11
|
-
secret: nexmo_options.delete(:secret)
|
12
|
-
}
|
5
|
+
client = \
|
6
|
+
::Nexmo::Client.new(key: options[:key], secret: options[:secret])
|
13
7
|
|
14
|
-
|
15
|
-
@phone_number = nexmo_options.delete(:phone_number)
|
16
|
-
|
17
|
-
super(:nexmo, ::Nexmo::Client.new(auth_options))
|
8
|
+
super :nexmo, client, options
|
18
9
|
end
|
19
10
|
|
20
11
|
def send_message(message)
|
21
12
|
response = client.send_message \
|
22
13
|
text: message[:text],
|
23
|
-
from:
|
24
|
-
to:
|
14
|
+
from: message[:from],
|
15
|
+
to: serialize_to_number(message[:to])
|
25
16
|
|
26
17
|
if success_response?(response)
|
27
18
|
Response::NexmoSuccess.new(response)
|
@@ -35,10 +26,8 @@ module SmsBroker
|
|
35
26
|
def success_response?(response)
|
36
27
|
# just looking for the first message,
|
37
28
|
# right now only one message per call
|
38
|
-
response['messages'].
|
29
|
+
!response['messages'].empty? && response['messages'][0]['status'] == '0'
|
39
30
|
end
|
40
|
-
|
41
31
|
end
|
42
|
-
|
43
32
|
end
|
44
33
|
end
|
@@ -1,9 +1,7 @@
|
|
1
1
|
module SmsBroker
|
2
2
|
module Client
|
3
3
|
module Response
|
4
|
-
|
5
4
|
class Error
|
6
|
-
|
7
5
|
attr_reader :service,
|
8
6
|
:response,
|
9
7
|
:serialized
|
@@ -19,11 +17,9 @@ module SmsBroker
|
|
19
17
|
end
|
20
18
|
|
21
19
|
def invalid_sender_id?
|
22
|
-
(@serialized[:errors]['sender_id'] ||
|
20
|
+
(@serialized[:errors]['sender_id'] || []).include?('is invalid')
|
23
21
|
end
|
24
|
-
|
25
22
|
end
|
26
|
-
|
27
23
|
end
|
28
24
|
end
|
29
25
|
end
|
@@ -1,10 +1,8 @@
|
|
1
1
|
module SmsBroker
|
2
2
|
module Client
|
3
3
|
module Response
|
4
|
-
|
5
4
|
class NexmoError < Error
|
6
|
-
|
7
|
-
SENDER_ID_NOT_SUPPORTED = '15'
|
5
|
+
SENDER_ID_NOT_SUPPORTED = '15'.freeze
|
8
6
|
|
9
7
|
def initialize(nexmo_response)
|
10
8
|
super :nexmo, nexmo_response, serialize_error_response(nexmo_response)
|
@@ -27,9 +25,7 @@ module SmsBroker
|
|
27
25
|
|
28
26
|
errors
|
29
27
|
end
|
30
|
-
|
31
28
|
end
|
32
|
-
|
33
29
|
end
|
34
30
|
end
|
35
31
|
end
|
@@ -1,9 +1,7 @@
|
|
1
1
|
module SmsBroker
|
2
2
|
module Client
|
3
3
|
module Response
|
4
|
-
|
5
4
|
class NexmoSuccess < Success
|
6
|
-
|
7
5
|
def initialize(nexmo_response)
|
8
6
|
super :nexmo, nexmo_response, serialize(nexmo_response)
|
9
7
|
end
|
@@ -17,21 +15,23 @@ module SmsBroker
|
|
17
15
|
to: single_response['to'],
|
18
16
|
from: single_response['from'],
|
19
17
|
message_id: single_response['message-id'],
|
20
|
-
raw:
|
21
|
-
to: single_response['to'],
|
22
|
-
from: single_response['from'],
|
23
|
-
status: single_response['status'],
|
24
|
-
network: single_response['network'],
|
25
|
-
message_id: single_response['message-id'],
|
26
|
-
client_ref: single_response['client-ref'],
|
27
|
-
remaining_balance: single_response['remaining-balance'],
|
28
|
-
message_price: single_response['message-price']
|
29
|
-
}
|
18
|
+
raw: response_to_hash(single_response)
|
30
19
|
}
|
31
20
|
end
|
32
21
|
|
33
|
-
|
22
|
+
def response_to_hash(response)
|
23
|
+
attributes = %w(
|
24
|
+
to from status network message-id client-ref
|
25
|
+
remaining-balance message-price
|
26
|
+
)
|
34
27
|
|
28
|
+
{}.tap do |hash|
|
29
|
+
attributes.each do |attr|
|
30
|
+
hash[attr.tr('-', '_').to_sym] = response[attr]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -1,10 +1,8 @@
|
|
1
1
|
module SmsBroker
|
2
2
|
module Client
|
3
3
|
module Response
|
4
|
-
|
5
4
|
class TwilioError < Error
|
6
|
-
|
7
|
-
SENDER_ID_NOT_SUPPORTED = '21212'
|
5
|
+
SENDER_ID_NOT_SUPPORTED = '21212'.freeze
|
8
6
|
|
9
7
|
def initialize(twilio_response)
|
10
8
|
super :twilio, twilio_response, serialize(twilio_response)
|
@@ -22,10 +20,10 @@ module SmsBroker
|
|
22
20
|
|
23
21
|
def serialize_response_error(response)
|
24
22
|
errors = {
|
25
|
-
|
23
|
+
response.error_code.to_s => [response.error_message]
|
26
24
|
}
|
27
25
|
|
28
|
-
if
|
26
|
+
if response.error_code.to_s == SENDER_ID_NOT_SUPPORTED
|
29
27
|
errors['sender_id'] = ['is invalid']
|
30
28
|
end
|
31
29
|
|
@@ -34,18 +32,16 @@ module SmsBroker
|
|
34
32
|
|
35
33
|
def serialize_exeception_errors(exception)
|
36
34
|
errors = {
|
37
|
-
|
35
|
+
exception.code.to_s => [exception.message]
|
38
36
|
}
|
39
37
|
|
40
|
-
if
|
38
|
+
if exception.code.to_s == SENDER_ID_NOT_SUPPORTED
|
41
39
|
errors['sender_id'] = ['is invalid']
|
42
40
|
end
|
43
41
|
|
44
42
|
errors
|
45
43
|
end
|
46
|
-
|
47
44
|
end
|
48
|
-
|
49
45
|
end
|
50
46
|
end
|
51
47
|
end
|
@@ -1,9 +1,7 @@
|
|
1
1
|
module SmsBroker
|
2
2
|
module Client
|
3
3
|
module Response
|
4
|
-
|
5
4
|
class TwilioSuccess < Success
|
6
|
-
|
7
5
|
def initialize(twilio_response)
|
8
6
|
super :twilio, twilio_response, serialize(twilio_response)
|
9
7
|
end
|
@@ -15,27 +13,24 @@ module SmsBroker
|
|
15
13
|
to: response.to,
|
16
14
|
from: response.from,
|
17
15
|
message_id: response.sid,
|
18
|
-
raw:
|
19
|
-
to: response.to,
|
20
|
-
sid: response.sid,
|
21
|
-
uri: response.uri,
|
22
|
-
from: response.from,
|
23
|
-
body: response.body,
|
24
|
-
price: response.price,
|
25
|
-
status: response.status,
|
26
|
-
price_unit: response.price_unit,
|
27
|
-
error_code: response.error_code,
|
28
|
-
account_sid: response.account_sid,
|
29
|
-
api_version: response.api_version,
|
30
|
-
date_created: response.date_created,
|
31
|
-
error_message: response.error_message,
|
32
|
-
messaging_service_sid: response.messaging_service_sid
|
33
|
-
}
|
16
|
+
raw: response_to_hash(response)
|
34
17
|
}
|
35
18
|
end
|
36
19
|
|
37
|
-
|
20
|
+
def response_to_hash(response)
|
21
|
+
attributes = %i(
|
22
|
+
to sid uri from body price status price_unit error_code
|
23
|
+
account_sid api_version date_created error_message
|
24
|
+
messaging_service_sid
|
25
|
+
)
|
38
26
|
|
27
|
+
{}.tap do |hash|
|
28
|
+
attributes.each do |attr|
|
29
|
+
hash[attr] = response.send(attr)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
39
34
|
end
|
40
35
|
end
|
41
36
|
end
|
@@ -1,49 +1,34 @@
|
|
1
1
|
module SmsBroker
|
2
2
|
module Client
|
3
|
-
|
4
3
|
class Twilio < Base
|
5
|
-
|
6
4
|
def initialize(options)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
auth_token: twilio_options.delete(:auth_token)
|
12
|
-
}
|
5
|
+
client = ::Twilio::REST::Client.new(
|
6
|
+
options[:account_sid],
|
7
|
+
options[:auth_token]
|
8
|
+
)
|
13
9
|
|
14
|
-
|
15
|
-
@phone_number = twilio_options.delete(:phone_number)
|
16
|
-
|
17
|
-
super \
|
18
|
-
:twilio,
|
19
|
-
::Twilio::REST::Client.new(auth_options[:account_sid], auth_options[:auth_token])
|
10
|
+
super :Twilio, client, options
|
20
11
|
end
|
21
12
|
|
22
13
|
def send_message(message)
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
to: serialize_number(message[:to])
|
14
|
+
response = client.messages.create \
|
15
|
+
body: message[:text],
|
16
|
+
from: message[:from],
|
17
|
+
to: serialize_to_number(message[:to])
|
28
18
|
|
29
|
-
|
30
|
-
|
31
|
-
else
|
32
|
-
Response::TwilioSuccess.new(response)
|
33
|
-
end
|
19
|
+
return Response::TwilioSuccess.new(response) \
|
20
|
+
if success_response?(response)
|
34
21
|
|
35
|
-
|
36
|
-
|
37
|
-
|
22
|
+
Response::TwilioError.new(response)
|
23
|
+
rescue ::Twilio::REST::RequestError => exception
|
24
|
+
Response::TwilioError.new(exception)
|
38
25
|
end
|
39
26
|
|
40
27
|
private
|
41
28
|
|
42
|
-
def
|
43
|
-
|
29
|
+
def success_response?(response)
|
30
|
+
!%w(undelivered failed).include?(response.status)
|
44
31
|
end
|
45
|
-
|
46
32
|
end
|
47
|
-
|
48
33
|
end
|
49
34
|
end
|
@@ -2,55 +2,51 @@ require 'sms_broker/setup'
|
|
2
2
|
require 'sms_broker/exceptions/invalid_setup'
|
3
3
|
|
4
4
|
module SmsBroker
|
5
|
-
|
6
5
|
module Configuration
|
6
|
+
extend self
|
7
7
|
|
8
|
-
|
8
|
+
@configuration = nil
|
9
9
|
|
10
10
|
def default_service
|
11
11
|
configuration[:default_service]
|
12
12
|
end
|
13
13
|
|
14
14
|
def clear_setup
|
15
|
-
|
15
|
+
@configuration = nil
|
16
16
|
end
|
17
17
|
|
18
18
|
def configuration
|
19
19
|
exception = \
|
20
20
|
Exceptions::InvalidSetup.new('setup does not exists')
|
21
21
|
|
22
|
-
|
22
|
+
@configuration || (raise exception)
|
23
23
|
end
|
24
24
|
|
25
|
-
def setup
|
25
|
+
def setup
|
26
26
|
setup = Setup.new
|
27
27
|
yield setup if block_given?
|
28
28
|
|
29
|
-
|
29
|
+
@configuration = setup.options
|
30
30
|
|
31
31
|
setup
|
32
32
|
end
|
33
33
|
|
34
|
-
def setup!
|
34
|
+
def setup!
|
35
35
|
setup = Setup.new
|
36
36
|
yield setup if block_given?
|
37
37
|
|
38
38
|
unless setup.valid?
|
39
39
|
exception = \
|
40
|
-
Exceptions::InvalidSetup.new(
|
40
|
+
Exceptions::InvalidSetup.new("setup is invalid, #{setup.errors}")
|
41
41
|
|
42
42
|
exception.errors = setup.errors
|
43
43
|
|
44
44
|
raise exception
|
45
45
|
end
|
46
46
|
|
47
|
-
|
47
|
+
@configuration = setup.options
|
48
48
|
|
49
49
|
setup
|
50
50
|
end
|
51
|
-
|
52
|
-
extend self
|
53
|
-
|
54
51
|
end
|
55
|
-
|
56
52
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
module SmsBroker
|
2
|
-
|
3
2
|
class MessageSender
|
4
|
-
|
5
3
|
attr_reader :client,
|
6
4
|
:errors
|
7
5
|
|
@@ -28,7 +26,7 @@ module SmsBroker
|
|
28
26
|
|
29
27
|
response = client.send_message(build_message)
|
30
28
|
|
31
|
-
if
|
29
|
+
if should_try_with_phone_number?(response)
|
32
30
|
return client.send_message(build_message(:phone_number))
|
33
31
|
end
|
34
32
|
|
@@ -56,26 +54,27 @@ module SmsBroker
|
|
56
54
|
private
|
57
55
|
|
58
56
|
def build_message(from = :sender_id)
|
59
|
-
sender = \
|
60
|
-
if client.sender_id && from == :sender_id
|
61
|
-
client.sender_id
|
62
|
-
else
|
63
|
-
client.phone_number
|
64
|
-
end
|
65
|
-
|
66
57
|
{
|
67
58
|
text: @message_text,
|
68
|
-
from:
|
59
|
+
from: get_sender(from),
|
69
60
|
to: @message_to
|
70
61
|
}
|
71
62
|
end
|
72
63
|
|
73
|
-
def
|
64
|
+
def get_sender(from)
|
65
|
+
if client.sender_id && from == :sender_id
|
66
|
+
client.sender_id
|
67
|
+
else
|
68
|
+
return client.phone_number if client.phone_number.start_with?('+')
|
69
|
+
|
70
|
+
"+#{client.phone_number}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def should_try_with_phone_number?(response)
|
74
75
|
response.is_a?(Client::Response::Error) &&
|
75
76
|
response.invalid_sender_id? &&
|
76
|
-
|
77
|
+
client.sender_id
|
77
78
|
end
|
78
|
-
|
79
79
|
end
|
80
|
-
|
81
80
|
end
|
data/lib/sms_broker/service.rb
CHANGED
@@ -1,27 +1,23 @@
|
|
1
1
|
require 'sms_broker/message_sender'
|
2
|
-
|
3
2
|
require 'sms_broker/client/base'
|
4
3
|
require 'sms_broker/client/nexmo'
|
5
4
|
require 'sms_broker/client/twilio'
|
6
|
-
|
7
5
|
require 'sms_broker/exceptions/invalid_service'
|
8
6
|
|
9
7
|
module SmsBroker
|
10
|
-
|
11
8
|
CLIENTS = {
|
12
|
-
nexmo:
|
9
|
+
nexmo: Client::Nexmo,
|
13
10
|
twilio: Client::Twilio
|
14
|
-
}
|
11
|
+
}.freeze
|
15
12
|
|
16
13
|
class Service
|
17
|
-
|
18
14
|
def self.get(name)
|
19
15
|
options = service_configuration(name)
|
20
16
|
|
21
17
|
result = Service.validate(name, options)
|
22
18
|
|
23
19
|
unless result.valid?
|
24
|
-
raise Exceptions::InvalidService,
|
20
|
+
raise Exceptions::InvalidService, name.to_sym => result.errors
|
25
21
|
end
|
26
22
|
|
27
23
|
new CLIENTS[name.to_sym].new(options)
|
@@ -44,7 +40,5 @@ module SmsBroker
|
|
44
40
|
def message(message)
|
45
41
|
MessageSender.new(client).message(message)
|
46
42
|
end
|
47
|
-
|
48
43
|
end
|
49
|
-
|
50
44
|
end
|
data/lib/sms_broker/setup.rb
CHANGED
@@ -1,24 +1,22 @@
|
|
1
1
|
module SmsBroker
|
2
|
-
|
3
2
|
class Setup
|
4
|
-
|
5
3
|
attr_reader :options,
|
6
4
|
:errors
|
7
5
|
|
8
6
|
def self.service_validation_schemas
|
9
7
|
{
|
10
|
-
nexmo: Compel.hash.keys(
|
8
|
+
nexmo: Compel.hash.keys(
|
11
9
|
key: Compel.string.required,
|
12
10
|
secret: Compel.string.required,
|
13
11
|
sender_id: Compel.string,
|
14
12
|
phone_number: Compel.string.required
|
15
|
-
|
16
|
-
twilio: Compel.hash.keys(
|
13
|
+
),
|
14
|
+
twilio: Compel.hash.keys(
|
17
15
|
sender_id: Compel.string,
|
18
16
|
auth_token: Compel.string.required,
|
19
17
|
account_sid: Compel.string.required,
|
20
18
|
phone_number: Compel.string.required
|
21
|
-
|
19
|
+
)
|
22
20
|
}
|
23
21
|
end
|
24
22
|
|
@@ -48,10 +46,10 @@ module SmsBroker
|
|
48
46
|
end
|
49
47
|
|
50
48
|
def compel_validation_schema(services_list = [])
|
51
|
-
not_all_services_setup =
|
52
|
-
services_list.all?
|
49
|
+
not_all_services_setup = proc do |services_setups|
|
50
|
+
services_list.all? do |service|
|
53
51
|
services_setups.keys.include?(service.to_sym)
|
54
|
-
|
52
|
+
end
|
55
53
|
end
|
56
54
|
|
57
55
|
services_setups_schema = \
|
@@ -66,7 +64,7 @@ module SmsBroker
|
|
66
64
|
end
|
67
65
|
|
68
66
|
def method_missing(method, args, &block)
|
69
|
-
service =
|
67
|
+
service = method.to_s.split('_setup')[0].dup
|
70
68
|
|
71
69
|
if @options[:services].include?(service)
|
72
70
|
@options[:services_setups][service.to_sym] = args
|
@@ -76,7 +74,5 @@ module SmsBroker
|
|
76
74
|
super
|
77
75
|
end
|
78
76
|
end
|
79
|
-
|
80
77
|
end
|
81
|
-
|
82
78
|
end
|
data/lib/sms_broker/version.rb
CHANGED
data/lib/sms_broker.rb
CHANGED
@@ -1,17 +1,16 @@
|
|
1
1
|
require 'nexmo'
|
2
2
|
require 'compel'
|
3
3
|
require 'twilio-ruby'
|
4
|
-
|
5
4
|
require 'sms_broker/client/response/error'
|
6
5
|
require 'sms_broker/client/response/success'
|
7
|
-
|
8
6
|
require 'sms_broker/configuration'
|
9
7
|
require 'sms_broker/service'
|
10
8
|
|
11
9
|
module SmsBroker
|
12
|
-
|
13
10
|
extend Configuration
|
14
11
|
|
12
|
+
module_function
|
13
|
+
|
15
14
|
def service(name = default_service)
|
16
15
|
Service.get(name)
|
17
16
|
end
|
@@ -19,7 +18,4 @@ module SmsBroker
|
|
19
18
|
def message(body)
|
20
19
|
service.message(body)
|
21
20
|
end
|
22
|
-
|
23
|
-
extend self
|
24
|
-
|
25
21
|
end
|