mote_sms 1.3.0.rc1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|