mote_sms 1.3.0.rc1 → 1.3.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.
- checksums.yaml +4 -4
- data/README.md +8 -0
- data/Rakefile +3 -3
- data/lib/mote_sms/message.rb +4 -6
- data/lib/mote_sms/number.rb +10 -8
- data/lib/mote_sms/number_list.rb +3 -5
- data/lib/mote_sms/transports/action_mailer_transport.rb +4 -4
- data/lib/mote_sms/transports/http_client.rb +7 -5
- data/lib/mote_sms/transports/mobile_technics_transport.rb +10 -9
- data/lib/mote_sms/transports/swisscom_transport.rb +12 -9
- data/lib/mote_sms/transports/test_transport.rb +1 -3
- data/lib/mote_sms/transports/twilio_transport.rb +78 -0
- data/lib/mote_sms/transports.rb +1 -1
- data/lib/mote_sms/version.rb +1 -1
- data/lib/mote_sms.rb +1 -1
- data/mote_sms.gemspec +6 -5
- data/spec/mote_sms/message_spec.rb +20 -20
- data/spec/mote_sms/number_list_spec.rb +3 -3
- data/spec/mote_sms/transports/action_mailer_transport_spec.rb +8 -7
- data/spec/mote_sms/transports/http_client_spec.rb +6 -5
- data/spec/mote_sms/transports/mobile_technics_transport_spec.rb +20 -20
- data/spec/mote_sms/transports/swisscom_transport_spec.rb +68 -0
- data/spec/mote_sms/transports/test_transport_spec.rb +3 -3
- data/spec/mote_sms/transports/twilio_transport_spec.rb +57 -0
- data/spec/mote_sms_spec.rb +5 -5
- metadata +24 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1284a153ac39d7eb140b1c735ca4762ab3a80cce
|
4
|
+
data.tar.gz: 4067f946a3ea39defa735deb9ed18a0c9840dddb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a0e5cf3ede57059c8c623593b4a5a430043a3a66051506c6394d0cb674029964d3dcc6da8cef0ddf4c88207b240fb9334e501006b38f1d00ca261733432f101
|
7
|
+
data.tar.gz: 060de67ac2c10da73dc52aa78181d7d29e62b8e0a9ca0fd3063aef9ca45ea8a751186bb00519a6e144f6e0e84ba4ca544b29b33e53bd1dfb4ba6515a93c00d8c
|
data/README.md
CHANGED
@@ -33,6 +33,14 @@ end
|
|
33
33
|
sms.deliver_now # OR: deliver_later
|
34
34
|
```
|
35
35
|
|
36
|
+
## TwilioTransport
|
37
|
+
Include the gem 'twilio-ruby in your Gemfile'
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
# Transport configuration
|
41
|
+
MoteSMS.transport = MoteSMS::TwilioTransport.new 'twilio sid', 'twilio token', 'from number'
|
42
|
+
```
|
43
|
+
|
36
44
|
## Contributing
|
37
45
|
|
38
46
|
1. Fork it
|
data/Rakefile
CHANGED
data/lib/mote_sms/message.rb
CHANGED
@@ -2,13 +2,11 @@ require 'mote_sms/number'
|
|
2
2
|
require 'mote_sms/number_list'
|
3
3
|
|
4
4
|
module MoteSMS
|
5
|
-
|
6
5
|
# Represents an SMS message, currently only provides the
|
7
6
|
# tools to build new messages, not parse incoming messages or
|
8
7
|
# similar stuff.
|
9
8
|
#
|
10
9
|
class Message
|
11
|
-
|
12
10
|
# The transport instance to use, if not defined
|
13
11
|
# falls back to use global MoteSMS.transport instance.
|
14
12
|
attr_accessor :transport
|
@@ -76,14 +74,14 @@ module MoteSMS
|
|
76
74
|
#
|
77
75
|
# Returns nothing.
|
78
76
|
def to=(*args)
|
79
|
-
@to = MoteSMS::NumberList.new.push(
|
77
|
+
@to = MoteSMS::NumberList.new.push(args)
|
80
78
|
end
|
81
79
|
|
82
80
|
# Public: Returns NumberList for this message.
|
83
81
|
#
|
84
82
|
# Returns NumberList instance.
|
85
83
|
def to(*numbers)
|
86
|
-
@to.push(
|
84
|
+
@to.push(numbers) unless numbers.empty?
|
87
85
|
@to
|
88
86
|
end
|
89
87
|
|
@@ -112,8 +110,8 @@ module MoteSMS
|
|
112
110
|
end
|
113
111
|
|
114
112
|
def deliver_later(options = {})
|
115
|
-
|
116
|
-
DeliveryJob.set(options).perform_later @from.to_s, @to.normalized_numbers, @body, options
|
113
|
+
Kernel.warn 'options[:transport] is not supported in Message#deliveer_later' if options.delete(:transport)
|
114
|
+
DeliveryJob.set(options).perform_later @from.to_s.presence, @to.normalized_numbers, @body, options
|
117
115
|
end
|
118
116
|
end
|
119
117
|
end
|
data/lib/mote_sms/number.rb
CHANGED
@@ -1,17 +1,19 @@
|
|
1
1
|
require 'phony'
|
2
2
|
|
3
3
|
module MoteSMS
|
4
|
-
|
5
4
|
# MoteSMS::Number handles all the number parsing and formatting
|
6
5
|
# issues, also a number is immutable.
|
7
6
|
class Number
|
8
|
-
|
9
7
|
# Support both Phony 1.7 and 2.x
|
10
|
-
PhonyError =
|
8
|
+
PhonyError = begin
|
9
|
+
Phony::NormalizationError
|
10
|
+
rescue
|
11
|
+
Class.new(ArgumentError)
|
12
|
+
end
|
11
13
|
|
12
14
|
# Access the E164 normalized value of the number.
|
13
15
|
attr_reader :number
|
14
|
-
alias
|
16
|
+
alias to_number number
|
15
17
|
|
16
18
|
def initialize(value, options = {})
|
17
19
|
@options = options || {}
|
@@ -40,7 +42,10 @@ module MoteSMS
|
|
40
42
|
# adds the country code if missing.
|
41
43
|
#
|
42
44
|
def parse_raw_number
|
43
|
-
|
45
|
+
if vanity?
|
46
|
+
@number = @raw_number.gsub(/[^A-Z0-9]/i, '').upcase.strip
|
47
|
+
raise ArgumentError, "Invalid vanity number #{@raw_number}" if @number.length.zero? || @number.length > 11
|
48
|
+
else
|
44
49
|
raise ArgumentError, "Unable to parse #{@raw_number} as number" unless @raw_number.to_s =~ /\A[\d\.\/\-\s\(\)\+]+\z/
|
45
50
|
cc = @options[:cc]
|
46
51
|
normalized = Phony.normalize(@raw_number)
|
@@ -48,9 +53,6 @@ module MoteSMS
|
|
48
53
|
raise ArgumentError, "Wrong national destination code #{@raw_number}" unless Phony.plausible?(normalized, @options)
|
49
54
|
|
50
55
|
@number = Phony.normalize normalized
|
51
|
-
else
|
52
|
-
@number = @raw_number.gsub(/[^A-Z0-9]/i, '').upcase.strip
|
53
|
-
raise ArgumentError, "Invalid vanity number #{@raw_number}" if @number.length == 0 || @number.length > 11
|
54
56
|
end
|
55
57
|
rescue PhonyError => e
|
56
58
|
raise ArgumentError, "Phony: #{e}"
|
data/lib/mote_sms/number_list.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'mote_sms/number'
|
2
2
|
|
3
3
|
module MoteSMS
|
4
|
-
|
5
4
|
# List of Number instances, which transparantly is able to add
|
6
5
|
# new Number instances from strings, or whatever.
|
7
6
|
#
|
@@ -16,7 +15,6 @@ module MoteSMS
|
|
16
15
|
# # => ['41791231212', '41441231212', '08001231212']
|
17
16
|
#
|
18
17
|
class NumberList
|
19
|
-
|
20
18
|
# Load ruby enumerable support.
|
21
19
|
include ::Enumerable
|
22
20
|
|
@@ -32,13 +30,13 @@ module MoteSMS
|
|
32
30
|
def length
|
33
31
|
numbers.length
|
34
32
|
end
|
35
|
-
alias
|
33
|
+
alias size length
|
36
34
|
|
37
35
|
# Public: Conform to arrayish behavior.
|
38
36
|
def empty?
|
39
37
|
numbers.empty?
|
40
38
|
end
|
41
|
-
alias
|
39
|
+
alias blank? empty?
|
42
40
|
|
43
41
|
# Public: Add number to internal list, use duck typing to detect if
|
44
42
|
# it appears to be a number instance or not. So everything which does
|
@@ -48,7 +46,7 @@ module MoteSMS
|
|
48
46
|
#
|
49
47
|
# Returns nothing.
|
50
48
|
def <<(number)
|
51
|
-
|
49
|
+
push(number)
|
52
50
|
end
|
53
51
|
|
54
52
|
# Public: Add multiple numbers, with optional options hash which can
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'action_mailer'
|
2
2
|
|
3
3
|
module MoteSMS
|
4
|
-
|
5
4
|
# Internal: ActionMailer class to forward SMS to recipient.
|
6
5
|
class ActionMailerSMSMailer < ::ActionMailer::Base
|
7
6
|
def forward_sms(recipient, sms)
|
@@ -23,7 +22,6 @@ module MoteSMS
|
|
23
22
|
# MoteSMS.transport = MoteSMS::ActionMailerTransport.new ->(msg) { "#{msg.from}@example.com" }
|
24
23
|
#
|
25
24
|
class ActionMailerTransport
|
26
|
-
|
27
25
|
# Public: Read/change the recipient used when delivering the message.
|
28
26
|
# Also accepts a Proc.
|
29
27
|
attr_accessor :recipient
|
@@ -40,9 +38,11 @@ module MoteSMS
|
|
40
38
|
# currently ignored.
|
41
39
|
#
|
42
40
|
# Returns nothing.
|
43
|
-
def deliver(message,
|
44
|
-
to =
|
41
|
+
def deliver(message, _options = {})
|
42
|
+
to = recipient.respond_to?(:call) ? recipient.call(message) : recipient
|
45
43
|
ActionMailerSMSMailer.forward_sms(to, message).deliver_now
|
44
|
+
|
45
|
+
message.to
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
@@ -12,11 +12,11 @@ module Transports
|
|
12
12
|
CERTS_PATH = File.expand_path File.join(File.dirname(__FILE__), '..', 'ssl_certs')
|
13
13
|
|
14
14
|
def self.ssl_options
|
15
|
-
@ssl_options ||=
|
15
|
+
@ssl_options ||= lambda do |http|
|
16
16
|
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
17
17
|
http.verify_depth = 9
|
18
|
-
http.cert_store =
|
19
|
-
|
18
|
+
http.cert_store = default_cert_store
|
19
|
+
end
|
20
20
|
end
|
21
21
|
|
22
22
|
def self.default_cert_store
|
@@ -48,7 +48,8 @@ module Transports
|
|
48
48
|
if enable_fingerprint
|
49
49
|
@fingerprint = ENV.fetch(
|
50
50
|
"MOTE_SMS_#{@endpoint.host.to_s.upcase.gsub(/[\.-]/, '_')}_FINGERPRINT",
|
51
|
-
self.class.fingerprint_host(@endpoint.host)
|
51
|
+
self.class.fingerprint_host(@endpoint.host)
|
52
|
+
)
|
52
53
|
end
|
53
54
|
end
|
54
55
|
|
@@ -79,7 +80,8 @@ module Transports
|
|
79
80
|
|
80
81
|
logger.error(
|
81
82
|
format('[Transports::HttpClient] failed to verify %s fingerprint (ACTUAL: %s, EXPECTED: %s)',
|
82
|
-
endpoint, digest, fingerprint)
|
83
|
+
endpoint, digest, fingerprint)
|
84
|
+
)
|
83
85
|
false
|
84
86
|
end
|
85
87
|
|
@@ -6,7 +6,6 @@ require 'logger'
|
|
6
6
|
require 'mote_sms/transports/http_client'
|
7
7
|
|
8
8
|
module MoteSMS
|
9
|
-
|
10
9
|
# MoteSMS::MobileTechnicsTransport provides the implementation to
|
11
10
|
# send messages using nth.ch bulk SMS HTTP/S API. Each customer has
|
12
11
|
# custom endpoint (with port) and username/password.
|
@@ -56,8 +55,8 @@ module MoteSMS
|
|
56
55
|
# logger - The Logger instance, should at least respond to #debug, #error.
|
57
56
|
#
|
58
57
|
# Returns nothing.
|
59
|
-
|
60
|
-
|
58
|
+
class << self
|
59
|
+
attr_writer :logger
|
61
60
|
end
|
62
61
|
|
63
62
|
# Public: Create a new instance using specified endpoint, username
|
@@ -78,9 +77,9 @@ module MoteSMS
|
|
78
77
|
@options = self.class.defaults.merge(options)
|
79
78
|
|
80
79
|
@http_client = Transports::HttpClient.new(endpoint,
|
81
|
-
|
82
|
-
|
83
|
-
|
80
|
+
proxy_address: @options[:proxy_address],
|
81
|
+
proxy_port: @options[:proxy_port],
|
82
|
+
ssl: @options[:ssl])
|
84
83
|
end
|
85
84
|
|
86
85
|
# Public: Delivers message using mobile technics HTTP/S API.
|
@@ -105,6 +104,8 @@ module MoteSMS
|
|
105
104
|
raise ServiceError, "unable to deliver message to all recipients (CAUSE: #{resp.body.strip})" unless resp.body.split("\n").all? { |l| l =~ /Result_code: 00/ }
|
106
105
|
|
107
106
|
resp['X-Nth-SmsId'].split(',')
|
107
|
+
|
108
|
+
message.to
|
108
109
|
end
|
109
110
|
|
110
111
|
private
|
@@ -117,9 +118,9 @@ module MoteSMS
|
|
117
118
|
#
|
118
119
|
# Returns Array with params.
|
119
120
|
def post_params(message, options)
|
120
|
-
params = options.reject { |key,
|
121
|
-
params.merge! username:
|
122
|
-
password:
|
121
|
+
params = options.reject { |key, _v| [:proxy_address, :proxy_port, :ssl].include?(key) }
|
122
|
+
params.merge! username: username,
|
123
|
+
password: password,
|
123
124
|
origin: message.from ? message.from.to_number : params[:origin],
|
124
125
|
text: message.body,
|
125
126
|
:'call-number' => prepare_numbers(message.to)
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'phony'
|
2
2
|
require 'logger'
|
3
|
+
require 'json'
|
3
4
|
|
4
5
|
require 'mote_sms/transports/http_client'
|
5
6
|
|
6
7
|
module MoteSMS
|
7
|
-
|
8
8
|
# MoteSMS::MobileTechnicsTransport provides the implementation to
|
9
9
|
# send messages using nth.ch bulk SMS HTTP/S API. Each customer has
|
10
10
|
# custom endpoint (with port) and username/password.
|
@@ -60,9 +60,9 @@ module MoteSMS
|
|
60
60
|
@options = options
|
61
61
|
|
62
62
|
@http_client = Transports::HttpClient.new(endpoint,
|
63
|
-
|
64
|
-
|
65
|
-
|
63
|
+
proxy_address: options[:proxy_address],
|
64
|
+
proxy_port: options[:proxy_port],
|
65
|
+
ssl: options[:ssl])
|
66
66
|
end
|
67
67
|
|
68
68
|
# Public: Delivers message using mobile technics HTTP/S API.
|
@@ -71,11 +71,11 @@ module MoteSMS
|
|
71
71
|
# options - The Hash with service specific options.
|
72
72
|
#
|
73
73
|
# Returns Array with sender ids.
|
74
|
-
def deliver(message,
|
75
|
-
raise
|
74
|
+
def deliver(message, _options = {})
|
75
|
+
raise ServiceError, "too many recipients, max. is #{MAX_RECIPIENT} (current: #{message.to.length})" if message.to.length > MAX_RECIPIENT
|
76
76
|
|
77
77
|
# Prepare request
|
78
|
-
request = Net::HTTP::Post.new(
|
78
|
+
request = Net::HTTP::Post.new('/messaging/v1/sms').tap do |request|
|
79
79
|
request.body = post_params(message)
|
80
80
|
request.content_type = 'application/json; charset=utf-8'
|
81
81
|
request['Accept'] = 'application/json; charset=utf-8'
|
@@ -86,17 +86,20 @@ module MoteSMS
|
|
86
86
|
self.class.logger.debug "curl -X#{request.method} '#{endpoint}' -d '#{request.body}'"
|
87
87
|
|
88
88
|
# Perform request
|
89
|
-
resp =
|
89
|
+
resp = http_client.request(request)
|
90
90
|
|
91
91
|
# Handle errors
|
92
92
|
raise ServiceError, "endpoint did respond with #{resp.code} and #{resp.body}" unless resp.code.to_i == 201
|
93
93
|
self.class.logger.debug resp.body
|
94
|
+
|
95
|
+
# Return numbers message send to
|
96
|
+
message.to
|
94
97
|
end
|
95
98
|
|
96
99
|
private
|
97
100
|
|
98
101
|
def post_params(message)
|
99
|
-
{ to: prepare_numbers(message.to), text: message.body }
|
102
|
+
{ to: prepare_numbers(message.to), text: message.body }.to_json
|
100
103
|
end
|
101
104
|
|
102
105
|
def prepare_numbers(number_list)
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module MoteSMS
|
2
|
-
|
3
2
|
# Public: Provide access to global array of delivered
|
4
3
|
# messages, this can be used in testing to assert sent
|
5
4
|
# SMS messages, test their contents, recipients etc.
|
@@ -26,14 +25,13 @@ module MoteSMS
|
|
26
25
|
# end
|
27
26
|
#
|
28
27
|
module TestTransport
|
29
|
-
|
30
28
|
# Public: Appends supplied message to global deliveries array.
|
31
29
|
#
|
32
30
|
# message - The MoteSMS::Message instance to deliver.
|
33
31
|
# options - The Hash with additional, transport specific options.
|
34
32
|
#
|
35
33
|
# Returns nothing.
|
36
|
-
def self.deliver(message,
|
34
|
+
def self.deliver(message, _options = {})
|
37
35
|
MoteSMS.deliveries << message
|
38
36
|
end
|
39
37
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'phony'
|
2
|
+
require 'logger'
|
3
|
+
require 'twilio-ruby'
|
4
|
+
|
5
|
+
module MoteSMS
|
6
|
+
# MoteSMS::TwilioTransport provides the implementation to
|
7
|
+
# send messages using the Twilio Api https://github.com/twilio/twilio-ruby
|
8
|
+
#
|
9
|
+
# Examples:
|
10
|
+
#
|
11
|
+
# MoteSMS.transport = MoteSMS::TwilioTransport.new 'sid', 'token', 'from_number'
|
12
|
+
# sms = MoteSMS::Message.new do
|
13
|
+
# to 'to_number'
|
14
|
+
# body 'my cool text'
|
15
|
+
# end
|
16
|
+
# sms.deliver_now
|
17
|
+
# # => <Twilio::REST::Message>
|
18
|
+
#
|
19
|
+
class TwilioTransport
|
20
|
+
# Maximum recipients allowed by API
|
21
|
+
MAX_RECIPIENT = 1
|
22
|
+
|
23
|
+
# Custom exception subclass.
|
24
|
+
ServiceError = Class.new(::Exception)
|
25
|
+
|
26
|
+
attr_reader :from_number, :client
|
27
|
+
|
28
|
+
# Public: Create a new instance using specified endpoint, api_key
|
29
|
+
# and password.
|
30
|
+
#
|
31
|
+
# account_sid - The twilio account sid
|
32
|
+
# auth_token - The twilio api token
|
33
|
+
# from_number - The phone number to send from (mandatory on initialize or send message)
|
34
|
+
#
|
35
|
+
# Returns a new instance.
|
36
|
+
def initialize(account_sid, auth_token, from_number = nil)
|
37
|
+
@from_number = from_number
|
38
|
+
|
39
|
+
@client = Twilio::REST::Client.new account_sid, auth_token
|
40
|
+
end
|
41
|
+
|
42
|
+
# Public: Delivers message using mobile technics HTTP/S API.
|
43
|
+
#
|
44
|
+
# message - The MoteSMS::Message instance to send.
|
45
|
+
# options - The Hash with service specific options.
|
46
|
+
#
|
47
|
+
# Returns Array with sender ids.
|
48
|
+
def deliver(message, _options = {})
|
49
|
+
raise ArgumentError, "too many recipients, max. is #{MAX_RECIPIENT}" if message.to.length > MAX_RECIPIENT
|
50
|
+
|
51
|
+
from = message.from.present? ? message.from.to_s : from_number
|
52
|
+
|
53
|
+
raise ArgumentError, 'no from number given on new message or the transport given' if from.empty?
|
54
|
+
|
55
|
+
from = Phony.format(Phony.normalize(from), format: :international_absolute, spaces: '')
|
56
|
+
|
57
|
+
messages = prepare_numbers(message.to).map do |n|
|
58
|
+
@client.messages.create(
|
59
|
+
from: from,
|
60
|
+
to: n,
|
61
|
+
body: message.body
|
62
|
+
)
|
63
|
+
end
|
64
|
+
numbers = messages.map do |result|
|
65
|
+
result.try(:to)
|
66
|
+
end
|
67
|
+
NumberList.new.push numbers.compact
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def prepare_numbers(number_list)
|
73
|
+
number_list.normalized_numbers.map do |n|
|
74
|
+
Phony.format(Phony.normalize(n), format: :international_absolute, spaces: '')
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/mote_sms/transports.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module MoteSMS
|
2
|
-
|
3
2
|
# All transports live within mote_sms/transports, though should be
|
4
3
|
# available in ruby as `MoteSMS::<Some>Transport`.
|
5
4
|
autoload :SslTransport, 'mote_sms/transports/concerns/ssl_transport'
|
@@ -7,4 +6,5 @@ module MoteSMS
|
|
7
6
|
autoload :MobileTechnicsTransport, 'mote_sms/transports/mobile_technics_transport'
|
8
7
|
autoload :ActionMailerTransport, 'mote_sms/transports/action_mailer_transport'
|
9
8
|
autoload :SwisscomTransport, 'mote_sms/transports/swisscom_transport'
|
9
|
+
autoload :TwilioTransport, 'mote_sms/transports/twilio_transport'
|
10
10
|
end
|
data/lib/mote_sms/version.rb
CHANGED
data/lib/mote_sms.rb
CHANGED
data/mote_sms.gemspec
CHANGED
@@ -5,17 +5,17 @@ Gem::Specification.new do |gem|
|
|
5
5
|
gem.name = 'mote_sms'
|
6
6
|
gem.authors = ['Lukas Westermann', 'Loris Gavillet']
|
7
7
|
gem.email = ['lukas.westermann@at-point.ch', 'loris@at-point.ch']
|
8
|
-
gem.summary =
|
9
|
-
gem.description =
|
8
|
+
gem.summary = 'Deliver SMS using Swisscom / MobileTechnics REST API.'
|
9
|
+
gem.description = 'Unofficial ruby adapter for Swisscom and MobileTechnics Bulk SMS APIs.
|
10
10
|
Tries to mimick mail API, so users can switch e.g. ActionMailer
|
11
|
-
with this SMS provider.
|
11
|
+
with this SMS provider.'
|
12
12
|
gem.homepage = 'https://github.com/at-point/mote_sms'
|
13
13
|
|
14
|
-
gem.files = %w
|
14
|
+
gem.files = %w(.gitignore Gemfile Rakefile README.md mote_sms.gemspec) + Dir['**/*.{rb,pem}']
|
15
15
|
gem.bindir = 'exe'
|
16
16
|
gem.executables = gem.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
-
gem.require_paths = %w
|
18
|
+
gem.require_paths = %w(lib)
|
19
19
|
gem.version = MoteSMS::VERSION
|
20
20
|
|
21
21
|
gem.required_ruby_version = '>= 2.0'
|
@@ -28,4 +28,5 @@ Gem::Specification.new do |gem|
|
|
28
28
|
gem.add_development_dependency 'webmock', ['~> 1.8.0']
|
29
29
|
gem.add_development_dependency 'actionmailer', ['>= 4.2', '< 6']
|
30
30
|
gem.add_development_dependency 'activejob', ['>= 4.2', '< 6']
|
31
|
+
gem.add_development_dependency 'twilio-ruby', ['>= 4.11.0']
|
31
32
|
end
|
@@ -10,62 +10,62 @@ describe MoteSMS::Message do
|
|
10
10
|
body 'This is the SMS content'
|
11
11
|
end
|
12
12
|
expect(msg.from.number).to be == 'SENDER'
|
13
|
-
expect(msg.to.normalized_numbers).to be == %w
|
13
|
+
expect(msg.to.normalized_numbers).to be == %w(41791231212)
|
14
14
|
expect(msg.body).to be == 'This is the SMS content'
|
15
15
|
end
|
16
16
|
|
17
17
|
context '#to' do
|
18
18
|
it 'behaves as accessor' do
|
19
19
|
subject.to = '41791231212'
|
20
|
-
expect(subject.to.normalized_numbers).to be == %w
|
20
|
+
expect(subject.to.normalized_numbers).to be == %w(41791231212)
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'behaves as array' do
|
24
24
|
subject.to << '41791231212'
|
25
25
|
subject.to << '41797775544'
|
26
|
-
expect(subject.to.normalized_numbers).to be == %w
|
26
|
+
expect(subject.to.normalized_numbers).to be == %w(41791231212 41797775544)
|
27
27
|
end
|
28
28
|
|
29
29
|
it 'normalizes numbers' do
|
30
30
|
subject.to = '+41 79 123 12 12'
|
31
|
-
expect(subject.to.normalized_numbers).to be == %w
|
31
|
+
expect(subject.to.normalized_numbers).to be == %w(41791231212)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
context
|
35
|
+
context '#deliver' do
|
36
36
|
subject { described_class.new }
|
37
37
|
|
38
|
-
it
|
38
|
+
it 'delegates to deliver_now and deprecates it' do
|
39
39
|
expect(subject).to receive(:deliver_now)
|
40
40
|
expect(Kernel).to receive(:warn).with('Message#deliver is deprecated and will be removed from MoteSMS. Please use #deliver_now')
|
41
41
|
subject.deliver
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
context
|
46
|
-
let(:transport) { double(
|
47
|
-
subject
|
45
|
+
context '#deliver_now' do
|
46
|
+
let(:transport) { double('Some Transport') }
|
47
|
+
subject do
|
48
48
|
expect(Kernel).to receive(:warn).with('Message#new(transport) is deprecated and will be removed from MoteSMS')
|
49
49
|
described_class.new(transport)
|
50
|
-
|
50
|
+
end
|
51
51
|
|
52
|
-
it
|
52
|
+
it 'sends messages to transport' do
|
53
53
|
expect(transport).to receive(:deliver).with(subject, {})
|
54
54
|
subject.deliver_now
|
55
55
|
end
|
56
56
|
|
57
|
-
it
|
58
|
-
expect(transport).to receive(:deliver).with(subject, serviceid:
|
59
|
-
subject.deliver_now serviceid:
|
57
|
+
it 'can pass additional attributes to transport' do
|
58
|
+
expect(transport).to receive(:deliver).with(subject, serviceid: 'myapplication')
|
59
|
+
subject.deliver_now serviceid: 'myapplication'
|
60
60
|
end
|
61
61
|
|
62
|
-
it
|
62
|
+
it 'can override per message transport using :transport option and it deprecates it' do
|
63
63
|
expect(transport).to_not receive(:deliver)
|
64
64
|
expect(Kernel).to receive(:warn).with('options[:transport] in Message#deliver_now is deprecated and will be removed from MoteSMS')
|
65
65
|
subject.deliver_now transport: double(deliver: true)
|
66
66
|
end
|
67
67
|
|
68
|
-
it
|
68
|
+
it 'uses global MoteSMS.transport if no per message transport defined' do
|
69
69
|
message = described_class.new
|
70
70
|
expect(transport).to receive(:deliver).with(message, {})
|
71
71
|
expect(MoteSMS).to receive(:transport) { transport }
|
@@ -73,7 +73,7 @@ describe MoteSMS::Message do
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
|
-
context
|
76
|
+
context '#deliver_later' do
|
77
77
|
before { MoteSMS.transport = MoteSMS::TestTransport }
|
78
78
|
after { MoteSMS.transport = nil }
|
79
79
|
|
@@ -85,13 +85,13 @@ describe MoteSMS::Message do
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
-
it
|
88
|
+
it 'can not override per message transport using :transport option and it deprecates it' do
|
89
89
|
expect(Kernel).to receive(:warn).with('options[:transport] is not supported in Message#deliveer_later')
|
90
|
-
expect(MoteSMS::DeliveryJob).to_not receive(:perform_later)
|
91
90
|
subject.deliver_later transport: double(deliver: true)
|
91
|
+
expect(ActiveJob::Base.queue_adapter.enqueued_jobs.size).to eq 1
|
92
92
|
end
|
93
93
|
|
94
|
-
it
|
94
|
+
it 'queues the delivery in the DeliveryJob' do
|
95
95
|
subject.deliver_later
|
96
96
|
job = ActiveJob::Base.queue_adapter.enqueued_jobs.first
|
97
97
|
expect(job[:job]).to eq MoteSMS::DeliveryJob
|
@@ -18,16 +18,16 @@ describe MoteSMS::NumberList do
|
|
18
18
|
|
19
19
|
it 'can add numbers by string' do
|
20
20
|
subject << '+41 79 111 22 33'
|
21
|
-
expect(subject.normalized_numbers).to be == %w
|
21
|
+
expect(subject.normalized_numbers).to be == %w(41791112233)
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'can multiple numbers using push' do
|
25
25
|
subject.push '+41 79 111 22 33', '+41 44 111 22 33'
|
26
|
-
expect(subject.normalized_numbers).to be == %w
|
26
|
+
expect(subject.normalized_numbers).to be == %w(41791112233 41441112233)
|
27
27
|
end
|
28
28
|
|
29
29
|
it 'can push multiple numbers with adding country codes' do
|
30
30
|
subject.push '079 111 22 33', '0041 44 111 22 33', cc: '41', ndc: /(44|79)/
|
31
|
-
expect(subject.normalized_numbers).to be == %w
|
31
|
+
expect(subject.normalized_numbers).to be == %w(41791112233 41441112233)
|
32
32
|
end
|
33
33
|
end
|
@@ -3,13 +3,14 @@ require 'mote_sms/message'
|
|
3
3
|
require 'mote_sms/transports/action_mailer_transport'
|
4
4
|
|
5
5
|
describe MoteSMS::ActionMailerTransport do
|
6
|
-
subject { described_class.new
|
7
|
-
let(:message)
|
6
|
+
subject { described_class.new 'sms@example.com' }
|
7
|
+
let(:message) do
|
8
|
+
MoteSMS::Message.new do
|
8
9
|
from 'Sender'
|
9
10
|
to '+41 79 123 12 12'
|
10
11
|
body 'This is the SMS content'
|
11
12
|
end
|
12
|
-
|
13
|
+
end
|
13
14
|
let(:email) { ActionMailer::Base.deliveries.last }
|
14
15
|
|
15
16
|
before do
|
@@ -19,9 +20,9 @@ describe MoteSMS::ActionMailerTransport do
|
|
19
20
|
|
20
21
|
it 'sends SMS as e-mail' do
|
21
22
|
subject.deliver message
|
22
|
-
expect(email.to).to be == [
|
23
|
-
expect(email.from).to be == [
|
24
|
-
expect(email.subject).to be ==
|
25
|
-
expect(email.body).to be ==
|
23
|
+
expect(email.to).to be == ['sms@example.com']
|
24
|
+
expect(email.from).to be == ['sms@example.com']
|
25
|
+
expect(email.subject).to be == 'SMS to +41 79 123 12 12'
|
26
|
+
expect(email.body).to be == 'This is the SMS content'
|
26
27
|
end
|
27
28
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'mote_sms/version'
|
2
3
|
require 'mote_sms/transports/http_client'
|
3
4
|
|
4
5
|
describe Transports::HttpClient do
|
@@ -73,11 +74,11 @@ describe Transports::HttpClient do
|
|
73
74
|
context '#request' do
|
74
75
|
let(:request) { Net::HTTP::Get.new('/') }
|
75
76
|
|
76
|
-
before
|
77
|
-
stub_request(:get,
|
78
|
-
with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' =>
|
79
|
-
to_return(status: 200, body:
|
80
|
-
|
77
|
+
before(:each) do
|
78
|
+
stub_request(:get, 'https://example.org/')
|
79
|
+
.with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => "Ruby/mote_sms #{MoteSMS::VERSION}" })
|
80
|
+
.to_return(status: 200, body: '', headers: {})
|
81
|
+
end
|
81
82
|
|
82
83
|
it 'submits a request and overrides the UA' do
|
83
84
|
response = subject.request(request)
|
@@ -7,34 +7,34 @@ require 'mote_sms/transports/mobile_technics_transport'
|
|
7
7
|
describe MoteSMS::MobileTechnicsTransport do
|
8
8
|
before do
|
9
9
|
@logger = described_class.logger
|
10
|
-
described_class.logger = double(
|
10
|
+
described_class.logger = double('logger', debug: true, info: true, error: true)
|
11
11
|
end
|
12
12
|
|
13
13
|
after do
|
14
14
|
described_class.logger = @logger
|
15
15
|
end
|
16
16
|
|
17
|
-
subject { described_class.new(endpoint,
|
17
|
+
subject { described_class.new(endpoint, 'example', '123456') }
|
18
18
|
|
19
|
-
let(:endpoint) {
|
20
|
-
let(:message)
|
19
|
+
let(:endpoint) { 'http://test.nth.ch' }
|
20
|
+
let(:message) do
|
21
21
|
MoteSMS::Message.new do
|
22
22
|
to '0041 079 123 12 12'
|
23
23
|
from 'SENDER'
|
24
24
|
body 'Hello World, with äöü.'
|
25
25
|
end
|
26
|
-
|
26
|
+
end
|
27
27
|
|
28
|
-
let(:success)
|
29
|
-
{ body:
|
30
|
-
|
28
|
+
let(:success) do
|
29
|
+
{ body: 'Result_code: 00, Message OK', status: 200, headers: { 'X-Nth-SmsId' => '43797917' } }
|
30
|
+
end
|
31
31
|
|
32
|
-
context
|
33
|
-
it
|
32
|
+
context '#deliver' do
|
33
|
+
it 'sends POST to endpoint with URL encoded body' do
|
34
34
|
stub_request(:post, endpoint).with do |req|
|
35
35
|
params = CGI.parse(req.body)
|
36
|
-
expect(params['username']).to be == %w
|
37
|
-
expect(params['password']).to be == %w
|
36
|
+
expect(params['username']).to be == %w(example)
|
37
|
+
expect(params['password']).to be == %w(123456)
|
38
38
|
expect(params['text']).to be == ['Hello World, with äöü.']
|
39
39
|
expect(params['call-number']).to be == ['0041791231212']
|
40
40
|
end.to_return(success)
|
@@ -51,17 +51,17 @@ describe MoteSMS::MobileTechnicsTransport do
|
|
51
51
|
|
52
52
|
it 'raises exception if required parameter is missing' do
|
53
53
|
stub_request(:post, endpoint).to_return(body: 'Result_code: 02, call-number')
|
54
|
-
expect { subject.deliver message }.to raise_error(
|
54
|
+
expect { subject.deliver message }.to raise_error(described_class::ServiceError)
|
55
55
|
end
|
56
56
|
|
57
57
|
it 'raises exception if status code is not 200' do
|
58
58
|
stub_request(:post, endpoint).to_return(status: 500)
|
59
|
-
expect { subject.deliver message }.to raise_error(
|
59
|
+
expect { subject.deliver message }.to raise_error(described_class::ServiceError)
|
60
60
|
end
|
61
61
|
|
62
|
-
it 'returns message
|
62
|
+
it 'returns message delivered numbers' do
|
63
63
|
stub_request(:post, endpoint).to_return(success)
|
64
|
-
expect(subject.deliver(message)).to
|
64
|
+
expect(subject.deliver(message).normalized_numbers).to eq(['41791231212'])
|
65
65
|
end
|
66
66
|
|
67
67
|
it 'logs curl compatible output' do
|
@@ -74,7 +74,7 @@ describe MoteSMS::MobileTechnicsTransport do
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
-
context
|
77
|
+
context '#options' do
|
78
78
|
it 'can be passed in as last item in the constructor' do
|
79
79
|
transport = described_class.new endpoint, 'user', 'pass', allow_adaption: false, validity: 30
|
80
80
|
expect(transport.options[:allow_adaption]).to be_falsey
|
@@ -83,8 +83,8 @@ describe MoteSMS::MobileTechnicsTransport do
|
|
83
83
|
end
|
84
84
|
|
85
85
|
it 'should be exposed as hash' do
|
86
|
-
subject.options[:messageid] =
|
87
|
-
expect(subject.options[:messageid]).to be ==
|
86
|
+
subject.options[:messageid] = 'test'
|
87
|
+
expect(subject.options[:messageid]).to be == 'test'
|
88
88
|
end
|
89
89
|
|
90
90
|
it 'overrides settings from #defaults' do
|
@@ -103,7 +103,7 @@ describe MoteSMS::MobileTechnicsTransport do
|
|
103
103
|
end
|
104
104
|
|
105
105
|
it 'evaluates Procs & lambdas' do
|
106
|
-
subject.options[:messageid] =
|
106
|
+
subject.options[:messageid] = proc { 'test' }
|
107
107
|
|
108
108
|
stub_request(:post, endpoint).with(body: hash_including('messageid' => 'test')).to_return(success)
|
109
109
|
subject.deliver message
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'cgi'
|
4
|
+
require 'mote_sms/message'
|
5
|
+
require 'mote_sms/transports/swisscom_transport'
|
6
|
+
|
7
|
+
describe MoteSMS::SwisscomTransport do
|
8
|
+
before do
|
9
|
+
@logger = described_class.logger
|
10
|
+
described_class.logger = double('logger', debug: true, info: true, error: true)
|
11
|
+
end
|
12
|
+
|
13
|
+
after do
|
14
|
+
described_class.logger = @logger
|
15
|
+
end
|
16
|
+
|
17
|
+
subject { described_class.new(endpoint, 'example', '123456') }
|
18
|
+
|
19
|
+
let(:endpoint) { 'https://api.example.com' }
|
20
|
+
let(:message) do
|
21
|
+
MoteSMS::Message.new do
|
22
|
+
to '0041 079 123 12 12'
|
23
|
+
from 'SENDER'
|
24
|
+
body 'Hello World, with äöü.'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
let(:success) do
|
29
|
+
{ body: 'OK', status: 201 }
|
30
|
+
end
|
31
|
+
|
32
|
+
context '#deliver' do
|
33
|
+
it 'sends POST to endpoint with JSON body and Client ID' do
|
34
|
+
stub_request(:post, "#{endpoint}/messaging/v1/sms").with do |req|
|
35
|
+
params = JSON.load(req.body)
|
36
|
+
expect(params['text']).to eq 'Hello World, with äöü.'
|
37
|
+
expect(params['to']).to eq '+41791231212'
|
38
|
+
end.to_return(success)
|
39
|
+
expect(subject.deliver(message).normalized_numbers).to eq(['41791231212'])
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'raises error when trying to send to multiple recipients' do
|
43
|
+
message.to << '+41 79 333 44 55'
|
44
|
+
message.to << '+41 78 111 22 33'
|
45
|
+
|
46
|
+
expect { subject.deliver message }.to raise_error(described_class::ServiceError, /too many recipients/)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'raises exception if status code is not 201' do
|
50
|
+
stub_request(:post, "#{endpoint}/messaging/v1/sms").to_return(status: 500)
|
51
|
+
expect { subject.deliver message }.to raise_error(described_class::ServiceError)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'returns truthy on success' do
|
55
|
+
stub_request(:post, "#{endpoint}/messaging/v1/sms").to_return(success)
|
56
|
+
expect(subject.deliver(message)).to be_truthy
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'logs curl compatible output' do
|
60
|
+
io = StringIO.new
|
61
|
+
described_class.logger = Logger.new(io)
|
62
|
+
stub_request(:post, "#{endpoint}/messaging/v1/sms").to_return(success)
|
63
|
+
subject.deliver message
|
64
|
+
io.rewind
|
65
|
+
expect(io.read).to include('curl -XPOST \'https://api.example.com\' -d \'{')
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -10,8 +10,8 @@ describe MoteSMS::TestTransport do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'appends deliveries' do
|
13
|
-
subject.deliver
|
14
|
-
subject.deliver
|
15
|
-
expect(MoteSMS.deliveries).to be == %w
|
13
|
+
subject.deliver 'firstMessage'
|
14
|
+
subject.deliver 'secondMessage'
|
15
|
+
expect(MoteSMS.deliveries).to be == %w(firstMessage secondMessage)
|
16
16
|
end
|
17
17
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'twilio-ruby'
|
3
|
+
require 'mote_sms/transports/twilio_transport'
|
4
|
+
require 'mote_sms/message'
|
5
|
+
|
6
|
+
describe MoteSMS::TwilioTransport do
|
7
|
+
subject do
|
8
|
+
client = double(Twilio::REST::Client)
|
9
|
+
expect(client).to receive(:messages).at_least(:once) { results }
|
10
|
+
expect(Twilio::REST::Client).to receive(:new).with('account', '123456') { client }
|
11
|
+
described_class.new('account', '123456', '41791110011')
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:message) do
|
15
|
+
MoteSMS::Message.new do
|
16
|
+
to '+41790001122'
|
17
|
+
body 'Hello World'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:result) do
|
22
|
+
Twilio::REST::Message.new('/SMS', subject.client, from: '+41791110011', to: '41790001122', body: 'Hello World')
|
23
|
+
end
|
24
|
+
let(:results) do
|
25
|
+
Twilio::REST::Messages.new('/SMS', subject.client)
|
26
|
+
end
|
27
|
+
|
28
|
+
let(:message) do
|
29
|
+
MoteSMS::Message.new do
|
30
|
+
to '+41790001122'
|
31
|
+
body 'Hello World'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context '#deliver' do
|
36
|
+
it 'send message' do
|
37
|
+
expect(subject.client.messages).to receive(:create).with(
|
38
|
+
from: '+41791110011',
|
39
|
+
to: '+41790001122',
|
40
|
+
body: 'Hello World'
|
41
|
+
).at_least(:once) { result }
|
42
|
+
|
43
|
+
expect(subject.deliver(message).normalized_numbers).to eq(['41790001122'])
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'uses the number from the message' do
|
47
|
+
message.from = '41791110033'
|
48
|
+
expect(subject.client.messages).to receive(:create).with(
|
49
|
+
from: '+41791110033',
|
50
|
+
to: '+41790001122',
|
51
|
+
body: 'Hello World'
|
52
|
+
).at_least(:once) { result }
|
53
|
+
|
54
|
+
expect(subject.deliver(message).normalized_numbers).to eq(['41790001122'])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/spec/mote_sms_spec.rb
CHANGED
@@ -8,21 +8,21 @@ describe MoteSMS do
|
|
8
8
|
expect(subject::VERSION).to match /\d/
|
9
9
|
end
|
10
10
|
|
11
|
-
context
|
11
|
+
context 'transport' do
|
12
12
|
before { @current_transport = subject.transport }
|
13
13
|
after { subject.transport = @current_transport }
|
14
|
-
let(:transport) { double(
|
14
|
+
let(:transport) { double('transport') }
|
15
15
|
|
16
|
-
it
|
16
|
+
it 'has no default transport' do
|
17
17
|
expect(subject.transport).to be_nil
|
18
18
|
end
|
19
19
|
|
20
|
-
it
|
20
|
+
it 'can change global transport' do
|
21
21
|
subject.transport = transport
|
22
22
|
expect(subject.transport).to be == transport
|
23
23
|
end
|
24
24
|
|
25
|
-
context
|
25
|
+
context '#deliver' do
|
26
26
|
it 'delivers quick and dirty using global transport' do
|
27
27
|
expect(transport).to receive(:deliver).with(kind_of(MoteSMS::Message), {})
|
28
28
|
subject.transport = transport
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mote_sms
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.0
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lukas Westermann
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-09-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: phony
|
@@ -133,6 +133,20 @@ dependencies:
|
|
133
133
|
- - "<"
|
134
134
|
- !ruby/object:Gem::Version
|
135
135
|
version: '6'
|
136
|
+
- !ruby/object:Gem::Dependency
|
137
|
+
name: twilio-ruby
|
138
|
+
requirement: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
140
|
+
- - ">="
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: 4.11.0
|
143
|
+
type: :development
|
144
|
+
prerelease: false
|
145
|
+
version_requirements: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - ">="
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: 4.11.0
|
136
150
|
description: |-
|
137
151
|
Unofficial ruby adapter for Swisscom and MobileTechnics Bulk SMS APIs.
|
138
152
|
Tries to mimick mail API, so users can switch e.g. ActionMailer
|
@@ -164,6 +178,7 @@ files:
|
|
164
178
|
- lib/mote_sms/transports/mobile_technics_transport.rb
|
165
179
|
- lib/mote_sms/transports/swisscom_transport.rb
|
166
180
|
- lib/mote_sms/transports/test_transport.rb
|
181
|
+
- lib/mote_sms/transports/twilio_transport.rb
|
167
182
|
- lib/mote_sms/version.rb
|
168
183
|
- mote_sms.gemspec
|
169
184
|
- spec/mote_sms/delivery_job_spec.rb
|
@@ -173,7 +188,9 @@ files:
|
|
173
188
|
- spec/mote_sms/transports/action_mailer_transport_spec.rb
|
174
189
|
- spec/mote_sms/transports/http_client_spec.rb
|
175
190
|
- spec/mote_sms/transports/mobile_technics_transport_spec.rb
|
191
|
+
- spec/mote_sms/transports/swisscom_transport_spec.rb
|
176
192
|
- spec/mote_sms/transports/test_transport_spec.rb
|
193
|
+
- spec/mote_sms/transports/twilio_transport_spec.rb
|
177
194
|
- spec/mote_sms_spec.rb
|
178
195
|
- spec/spec_helper.rb
|
179
196
|
homepage: https://github.com/at-point/mote_sms
|
@@ -190,9 +207,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
190
207
|
version: '2.0'
|
191
208
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
192
209
|
requirements:
|
193
|
-
- - "
|
210
|
+
- - ">="
|
194
211
|
- !ruby/object:Gem::Version
|
195
|
-
version:
|
212
|
+
version: '0'
|
196
213
|
requirements: []
|
197
214
|
rubyforge_project:
|
198
215
|
rubygems_version: 2.5.1
|
@@ -207,6 +224,9 @@ test_files:
|
|
207
224
|
- spec/mote_sms/transports/action_mailer_transport_spec.rb
|
208
225
|
- spec/mote_sms/transports/http_client_spec.rb
|
209
226
|
- spec/mote_sms/transports/mobile_technics_transport_spec.rb
|
227
|
+
- spec/mote_sms/transports/swisscom_transport_spec.rb
|
210
228
|
- spec/mote_sms/transports/test_transport_spec.rb
|
229
|
+
- spec/mote_sms/transports/twilio_transport_spec.rb
|
211
230
|
- spec/mote_sms_spec.rb
|
212
231
|
- spec/spec_helper.rb
|
232
|
+
has_rdoc:
|