mollie-sms 0.1.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.
- data/LICENSE +20 -0
- data/README +7 -0
- data/lib/mollie/sms.rb +139 -0
- data/spec/sms_spec.rb +241 -0
- data/spec/spec_helper.rb +58 -0
- metadata +89 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Eloy Duran, Fingertips <eloy@fngtps.com>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
20
|
+
|
data/README
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
A Ruby client that allows you to send SMS messages via http://mollie.nl.
|
2
|
+
|
3
|
+
It does only what we need, for our app, at this point in time. Which means that
|
4
|
+
connects to the webservice via SSL, and only sends a message to one recipient
|
5
|
+
at a time.
|
6
|
+
|
7
|
+
Patches are accepted.
|
data/lib/mollie/sms.rb
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
require "digest/md5"
|
2
|
+
require "uri"
|
3
|
+
require "net/https"
|
4
|
+
|
5
|
+
begin
|
6
|
+
require "rubygems"
|
7
|
+
rescue LoadError
|
8
|
+
end
|
9
|
+
require "active_support"
|
10
|
+
|
11
|
+
module Mollie
|
12
|
+
class SMS
|
13
|
+
GATEWAY_URI = URI.parse("https://secure.mollie.nl/xml/sms")
|
14
|
+
|
15
|
+
GATEWAYS = {
|
16
|
+
'basic' => '2',
|
17
|
+
'business' => '4',
|
18
|
+
'business+' => '1',
|
19
|
+
'landline' => '8'
|
20
|
+
}
|
21
|
+
|
22
|
+
class StandardError < ::StandardError; end
|
23
|
+
class ValidationError < StandardError; end
|
24
|
+
class MissingRequiredParam < StandardError; end
|
25
|
+
|
26
|
+
REQUIRED_PARAMS = %w{ username md5_password originator gateway charset type recipients message }
|
27
|
+
|
28
|
+
class << self
|
29
|
+
attr_accessor :username, :password, :originator, :charset, :type, :gateway
|
30
|
+
|
31
|
+
def password=(password)
|
32
|
+
@password = Digest::MD5.hexdigest(password)
|
33
|
+
end
|
34
|
+
|
35
|
+
def default_params
|
36
|
+
{
|
37
|
+
'username' => @username,
|
38
|
+
'md5_password' => @password,
|
39
|
+
'originator' => @originator,
|
40
|
+
'gateway' => @gateway,
|
41
|
+
'charset' => @charset,
|
42
|
+
'type' => @type
|
43
|
+
}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
self.charset = 'UTF-8'
|
48
|
+
self.type = 'normal'
|
49
|
+
self.gateway = GATEWAYS['basic']
|
50
|
+
|
51
|
+
attr_reader :params
|
52
|
+
|
53
|
+
def initialize(telephone_number = nil, body = nil, extra_params = {})
|
54
|
+
@params = self.class.default_params.merge(extra_params)
|
55
|
+
self.telephone_number = telephone_number if telephone_number
|
56
|
+
self.body = body if body
|
57
|
+
end
|
58
|
+
|
59
|
+
def telephone_number
|
60
|
+
@params['recipients']
|
61
|
+
end
|
62
|
+
|
63
|
+
def telephone_number=(telephone_number)
|
64
|
+
@params['recipients'] = telephone_number
|
65
|
+
end
|
66
|
+
|
67
|
+
def body
|
68
|
+
@params['message']
|
69
|
+
end
|
70
|
+
|
71
|
+
def body=(body)
|
72
|
+
@params['message'] = body
|
73
|
+
end
|
74
|
+
|
75
|
+
def inspect
|
76
|
+
"#<#{self.class.name} from: <#{@params['originator']}> to: <#{telephone_number}> body: \"#{body}\" >"
|
77
|
+
end
|
78
|
+
|
79
|
+
def deliver
|
80
|
+
validate_params!
|
81
|
+
|
82
|
+
post = Net::HTTP::Post.new(GATEWAY_URI.path)
|
83
|
+
post.form_data = params
|
84
|
+
request = Net::HTTP.new(GATEWAY_URI.host, GATEWAY_URI.port)
|
85
|
+
request.use_ssl = true
|
86
|
+
request.start do |http|
|
87
|
+
response = http.request(post)
|
88
|
+
Response.new(response)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def validate_params!
|
93
|
+
params.slice(*REQUIRED_PARAMS).each do |key, value|
|
94
|
+
raise MissingRequiredParam, "The required parameter `#{key}' is missing." if value.blank?
|
95
|
+
end
|
96
|
+
|
97
|
+
originator = params['originator']
|
98
|
+
if originator =~ /^\d+$/
|
99
|
+
if originator.size > 14
|
100
|
+
raise ValidationError, "Originator may have a maximimun of 14 numerical characters."
|
101
|
+
end
|
102
|
+
elsif originator.size > 11
|
103
|
+
raise ValidationError, "Originator may have a maximimun of 11 alphanumerical characters."
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
class Response
|
108
|
+
attr_reader :http_response
|
109
|
+
|
110
|
+
def initialize(http_response)
|
111
|
+
@http_response = http_response
|
112
|
+
end
|
113
|
+
|
114
|
+
def params
|
115
|
+
@params ||= http_failure? ? {} : Hash.from_xml(@http_response.read_body)['response']['item']
|
116
|
+
end
|
117
|
+
|
118
|
+
def result_code
|
119
|
+
(http_failure? ? @http_response.code : params['resultcode']).to_i
|
120
|
+
end
|
121
|
+
|
122
|
+
def message
|
123
|
+
http_failure? ? "[HTTP: #{@http_response.code}] #{@http_response.message}" : params['resultmessage']
|
124
|
+
end
|
125
|
+
|
126
|
+
def success?
|
127
|
+
!http_failure? && params['success'] == 'true'
|
128
|
+
end
|
129
|
+
|
130
|
+
def http_failure?
|
131
|
+
!@http_response.is_a?(Net::HTTPSuccess)
|
132
|
+
end
|
133
|
+
|
134
|
+
def inspect
|
135
|
+
"#<#{self.class.name} #{ success? ? 'succeeded' : 'failed' } (#{result_code}) `#{message}'>"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
data/spec/sms_spec.rb
ADDED
@@ -0,0 +1,241 @@
|
|
1
|
+
require File.expand_path("../spec_helper", __FILE__)
|
2
|
+
require "mollie/sms"
|
3
|
+
|
4
|
+
Mollie::SMS.username = 'AstroRadio'
|
5
|
+
Mollie::SMS.password = 'secret'
|
6
|
+
Mollie::SMS.originator = 'Astro INC'
|
7
|
+
|
8
|
+
describe "Mollie::SMS" do
|
9
|
+
it "holds the gateway uri" do
|
10
|
+
Mollie::SMS::GATEWAY_URI.should == URI.parse("https://secure.mollie.nl/xml/sms")
|
11
|
+
end
|
12
|
+
|
13
|
+
it "holds the service username" do
|
14
|
+
Mollie::SMS.username.should == 'AstroRadio'
|
15
|
+
end
|
16
|
+
|
17
|
+
it "holds the service password as a MD5 hashed version" do
|
18
|
+
Mollie::SMS.password.should == Digest::MD5.hexdigest('secret')
|
19
|
+
end
|
20
|
+
|
21
|
+
it "holds the originator" do
|
22
|
+
Mollie::SMS.originator.should == 'Astro INC'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "returns the default charset" do
|
26
|
+
Mollie::SMS.charset.should == 'UTF-8'
|
27
|
+
end
|
28
|
+
|
29
|
+
it "returns the default message type" do
|
30
|
+
Mollie::SMS.type.should == 'normal'
|
31
|
+
end
|
32
|
+
|
33
|
+
it "holds a list of available gateways" do
|
34
|
+
Mollie::SMS::GATEWAYS['basic'].should == '2'
|
35
|
+
Mollie::SMS::GATEWAYS['business'].should == '4'
|
36
|
+
Mollie::SMS::GATEWAYS['business+'].should == '1'
|
37
|
+
Mollie::SMS::GATEWAYS['landline'].should == '8'
|
38
|
+
end
|
39
|
+
|
40
|
+
it "returns the default gateway to use" do
|
41
|
+
Mollie::SMS.gateway.should == Mollie::SMS::GATEWAYS['basic']
|
42
|
+
end
|
43
|
+
|
44
|
+
it "returns a hash of default params for a request" do
|
45
|
+
Mollie::SMS.default_params.should == {
|
46
|
+
'username' => 'AstroRadio',
|
47
|
+
'md5_password' => Digest::MD5.hexdigest('secret'),
|
48
|
+
'originator' => 'Astro INC',
|
49
|
+
'gateway' => '2',
|
50
|
+
'charset' => 'UTF-8',
|
51
|
+
'type' => 'normal'
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
it "initializes, optionally, with a telephone number, body, and params" do
|
56
|
+
sms1 = Mollie::SMS.new
|
57
|
+
sms1.telephone_number = '+31612345678'
|
58
|
+
sms1.body = "The stars tell me you will have chicken noodle soup for breakfast."
|
59
|
+
|
60
|
+
sms2 = Mollie::SMS.new('+31612345678', "The stars tell me you will have chicken noodle soup for breakfast.", 'originator' => 'Eloy')
|
61
|
+
sms2.params['originator'].should == 'Eloy'
|
62
|
+
|
63
|
+
[sms1, sms2].each do |sms|
|
64
|
+
sms.telephone_number.should == '+31612345678'
|
65
|
+
sms.body.should == "The stars tell me you will have chicken noodle soup for breakfast."
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "A Mollie::SMS instance" do
|
71
|
+
before do
|
72
|
+
@sms = Mollie::SMS.new
|
73
|
+
@sms.telephone_number = '+31612345678'
|
74
|
+
@sms.body = "The stars tell me you will have chicken noodle soup for breakfast."
|
75
|
+
end
|
76
|
+
|
77
|
+
it "returns the phone number" do
|
78
|
+
@sms.telephone_number.should == '+31612345678'
|
79
|
+
end
|
80
|
+
|
81
|
+
it "returns the message body" do
|
82
|
+
@sms.body.should == "The stars tell me you will have chicken noodle soup for breakfast."
|
83
|
+
end
|
84
|
+
|
85
|
+
it "returns the request params with all string keys and values" do
|
86
|
+
params = Mollie::SMS.default_params.merge(
|
87
|
+
'recipients' => '+31612345678',
|
88
|
+
'message' => "The stars tell me you will have chicken noodle soup for breakfast."
|
89
|
+
)
|
90
|
+
@sms.params.should == params
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "When sending a Mollie::SMS message" do
|
95
|
+
before do
|
96
|
+
@sms = Mollie::SMS.new
|
97
|
+
@sms.telephone_number = '+31612345678'
|
98
|
+
@sms.body = "The stars tell me you will have chicken noodle soup for breakfast."
|
99
|
+
end
|
100
|
+
|
101
|
+
after do
|
102
|
+
Net::HTTP.reset!
|
103
|
+
end
|
104
|
+
|
105
|
+
it "posts the post body to the gateway" do
|
106
|
+
@sms.stubs(:params).returns('a key' => 'a value')
|
107
|
+
@sms.stubs(:validate_params!)
|
108
|
+
@sms.deliver
|
109
|
+
|
110
|
+
request, post = Net::HTTP.posted
|
111
|
+
request.should.use_ssl
|
112
|
+
request.host.should == Mollie::SMS::GATEWAY_URI.host
|
113
|
+
request.port.should == Mollie::SMS::GATEWAY_URI.port
|
114
|
+
post.path.should == Mollie::SMS::GATEWAY_URI.path
|
115
|
+
post.body.should == "a%20key=a%20value"
|
116
|
+
end
|
117
|
+
|
118
|
+
it "returns a Mollie::SMS::Response object, with the Net::HTTP response" do
|
119
|
+
Net::HTTP.stubbed_response = Net::HTTPOK.new('1.1', '200', 'OK')
|
120
|
+
Net::HTTP.stubbed_response.stubs(:read_body).returns(SUCCESS_BODY)
|
121
|
+
response = @sms.deliver
|
122
|
+
response.should.be.instance_of Mollie::SMS::Response
|
123
|
+
response.http_response.should == Net::HTTP.stubbed_response
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "A Mollie::SMS::Response instance, for a succeeded request" do
|
128
|
+
before do
|
129
|
+
@http_response = Net::HTTPOK.new('1.1', '200', 'OK')
|
130
|
+
@http_response.stubs(:read_body).returns(SUCCESS_BODY)
|
131
|
+
@http_response.add_field('Content-type', 'application/xml')
|
132
|
+
@response = Mollie::SMS::Response.new(@http_response)
|
133
|
+
end
|
134
|
+
|
135
|
+
it "returns the Net::HTTP response object" do
|
136
|
+
@response.http_response.should == @http_response
|
137
|
+
end
|
138
|
+
|
139
|
+
it "returns the response body as a hash" do
|
140
|
+
@response.params.should == Hash.from_xml(SUCCESS_BODY)['response']['item']
|
141
|
+
end
|
142
|
+
|
143
|
+
it "returns whether or not it was a success" do
|
144
|
+
@response.should.be.success
|
145
|
+
|
146
|
+
@response.stubs(:params).returns('success' => 'false')
|
147
|
+
@response.should.not.be.success
|
148
|
+
end
|
149
|
+
|
150
|
+
it "returns the result code" do
|
151
|
+
@response.result_code.should == 10
|
152
|
+
end
|
153
|
+
|
154
|
+
it "returns the message corresponding to the result code" do
|
155
|
+
@response.message.should == "Message successfully sent."
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe "A Mollie::SMS::Response instance, for a request that failed at the gateway" do
|
160
|
+
before do
|
161
|
+
@http_response = Net::HTTPOK.new('1.1', '200', 'OK')
|
162
|
+
@http_response.stubs(:read_body).returns(FAILURE_BODY)
|
163
|
+
@http_response.add_field('Content-type', 'application/xml')
|
164
|
+
@response = Mollie::SMS::Response.new(@http_response)
|
165
|
+
end
|
166
|
+
|
167
|
+
it "returns that the request was not a success" do
|
168
|
+
@response.should.not.be.success
|
169
|
+
end
|
170
|
+
|
171
|
+
it "returns that this is a *not* HTTP failure" do
|
172
|
+
@response.should.not.be.http_failure
|
173
|
+
end
|
174
|
+
|
175
|
+
it "returns the result_code" do
|
176
|
+
@response.result_code.should == 20
|
177
|
+
end
|
178
|
+
|
179
|
+
it "returns the message corresponding to the result code" do
|
180
|
+
@response.message.should == "No username given."
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe "A Mollie::SMS::Response instance, for a failed HTTP request" do
|
185
|
+
before do
|
186
|
+
@http_response = Net::HTTPBadRequest.new('1.1', '400', 'Bad request')
|
187
|
+
@response = Mollie::SMS::Response.new(@http_response)
|
188
|
+
end
|
189
|
+
|
190
|
+
it "returns an empty hash as the params" do
|
191
|
+
@response.params.should == {}
|
192
|
+
end
|
193
|
+
|
194
|
+
it "returns that the request was not a success" do
|
195
|
+
@response.should.not.be.success
|
196
|
+
end
|
197
|
+
|
198
|
+
it "returns that this is a HTTP failure" do
|
199
|
+
@response.should.be.http_failure
|
200
|
+
end
|
201
|
+
|
202
|
+
it "returns the HTTP response code as the result_code" do
|
203
|
+
@response.result_code.should == 400
|
204
|
+
end
|
205
|
+
|
206
|
+
it "returns the HTTP error message as the message" do
|
207
|
+
@response.message.should == "[HTTP: 400] Bad request"
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
describe "Mollie::SMS, concerning validation" do
|
212
|
+
before do
|
213
|
+
@sms = Mollie::SMS.new
|
214
|
+
@sms.telephone_number = '+31612345678'
|
215
|
+
@sms.body = "The stars tell me you will have chicken noodle soup for breakfast."
|
216
|
+
end
|
217
|
+
|
218
|
+
it "accepts an originator of upto 14 numbers" do
|
219
|
+
@sms.params['originator'] = "00000000001111"
|
220
|
+
lambda { @sms.deliver }.should.not.raise
|
221
|
+
end
|
222
|
+
|
223
|
+
it "does not accept an originator string with more than 14 numbers" do
|
224
|
+
@sms.params['originator'] = "000000000011112"
|
225
|
+
lambda do
|
226
|
+
@sms.deliver
|
227
|
+
end.should.raise(Mollie::SMS::ValidationError, "Originator may have a maximimun of 14 numerical characters.")
|
228
|
+
end
|
229
|
+
|
230
|
+
it "accepts an originator of upto 11 alphanumerical characters" do
|
231
|
+
@sms.params['originator'] = "0123456789A"
|
232
|
+
lambda { @sms.deliver }.should.not.raise
|
233
|
+
end
|
234
|
+
|
235
|
+
it "does not accept an originator string with more than 11 alphanumerical characters" do
|
236
|
+
@sms.params['originator'] = "0123456789AB"
|
237
|
+
lambda do
|
238
|
+
@sms.deliver
|
239
|
+
end.should.raise(Mollie::SMS::ValidationError, "Originator may have a maximimun of 11 alphanumerical characters.")
|
240
|
+
end
|
241
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bacon"
|
3
|
+
require "mocha"
|
4
|
+
|
5
|
+
$:.unshift File.expand_path("../../lib", __FILE__)
|
6
|
+
|
7
|
+
Bacon.summary_on_exit
|
8
|
+
|
9
|
+
module Net
|
10
|
+
class HTTP
|
11
|
+
class << self
|
12
|
+
attr_accessor :posted, :stubbed_response
|
13
|
+
|
14
|
+
def reset!
|
15
|
+
@posted = nil
|
16
|
+
@stubbed_response = nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def host
|
21
|
+
@address
|
22
|
+
end
|
23
|
+
|
24
|
+
def start
|
25
|
+
yield self
|
26
|
+
end
|
27
|
+
|
28
|
+
def request(request)
|
29
|
+
self.class.posted = [self, request]
|
30
|
+
self.class.stubbed_response
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class ResponseStub
|
36
|
+
end
|
37
|
+
|
38
|
+
SUCCESS_BODY = %{
|
39
|
+
<?xml version="1.0" ?>
|
40
|
+
<response>
|
41
|
+
<item type="sms">
|
42
|
+
<recipients>1</recipients>
|
43
|
+
<success>true</success>
|
44
|
+
<resultcode>10</resultcode>
|
45
|
+
<resultmessage>Message successfully sent.</resultmessage>
|
46
|
+
</item>
|
47
|
+
</response>}
|
48
|
+
|
49
|
+
FAILURE_BODY = %{
|
50
|
+
<?xml version="1.0"?>
|
51
|
+
<response>
|
52
|
+
<item type="sms">
|
53
|
+
<recipients>1</recipients>
|
54
|
+
<success>false</success>
|
55
|
+
<resultcode>20</resultcode>
|
56
|
+
<resultmessage>No username given.</resultmessage>
|
57
|
+
</item>
|
58
|
+
</response>}
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mollie-sms
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Eloy Duran
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-08-02 00:00:00 +02:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: activesupport
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 19
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 3
|
33
|
+
- 8
|
34
|
+
version: 2.3.8
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
description: Send SMS text messages via the Mollie.nl SMS gateway.
|
38
|
+
email:
|
39
|
+
- eloy@fngtps.com
|
40
|
+
executables: []
|
41
|
+
|
42
|
+
extensions: []
|
43
|
+
|
44
|
+
extra_rdoc_files:
|
45
|
+
- LICENSE
|
46
|
+
- README
|
47
|
+
files:
|
48
|
+
- LICENSE
|
49
|
+
- README
|
50
|
+
- lib/mollie/sms.rb
|
51
|
+
- spec/sms_spec.rb
|
52
|
+
- spec/spec_helper.rb
|
53
|
+
has_rdoc: true
|
54
|
+
homepage: http://github.com/Fingertips/Mollie-SMS
|
55
|
+
licenses: []
|
56
|
+
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options:
|
59
|
+
- --charset=UTF-8
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
hash: 3
|
68
|
+
segments:
|
69
|
+
- 0
|
70
|
+
version: "0"
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
hash: 3
|
77
|
+
segments:
|
78
|
+
- 0
|
79
|
+
version: "0"
|
80
|
+
requirements: []
|
81
|
+
|
82
|
+
rubyforge_project:
|
83
|
+
rubygems_version: 1.3.7
|
84
|
+
signing_key:
|
85
|
+
specification_version: 3
|
86
|
+
summary: Send SMS text messages via the Mollie.nl SMS gateway.
|
87
|
+
test_files:
|
88
|
+
- spec/sms_spec.rb
|
89
|
+
- spec/spec_helper.rb
|