ballou_sms_gateway 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ spec/fixtures/user_details.yml
data/.rspec ADDED
@@ -0,0 +1,5 @@
1
+ --color
2
+ -fs
3
+ -Ilib
4
+ -Ispec
5
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ballou_sms_gateway.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/Readme.md ADDED
@@ -0,0 +1,80 @@
1
+ # Ballou SMS Gateway
2
+
3
+ Ruby bindings for [Ballou's SMS Gateway](http://www.ballou.se/tj%C3%A4nster/sms-verktyg).
4
+
5
+ Follow me on [Twitter](http://twitter.com/linusoleander) or [Github](https://github.com/oleander/) for more info and updates.
6
+
7
+ ## How to use
8
+
9
+ ### Send a message
10
+
11
+ ``` ruby
12
+ BallouSmsGateway.new.username("u").password("p").from("Github").to("070XXXXXXX").message("Hello world!").send!
13
+ ```
14
+
15
+ ### Send a message to multiply receivers
16
+
17
+ ``` ruby
18
+ BallouSmsGateway.new.username("u").password("p").from("Github").to("070XXXXXXX", "070YYYYYYY").message("Hello world!").send!
19
+ ```
20
+
21
+ ### Send a very long message
22
+
23
+ Add the `long` method to the chain to send up to *918* characters.
24
+
25
+ ``` ruby
26
+ BallouSmsGateway.new.username("u").password("p").from("Github").to("070XXXXXXX").message("A very long message ...").long.send!
27
+ ```
28
+
29
+ ### Options
30
+
31
+ The list below is a set of methods that can be chained, like above. **Order doesn't matter.**
32
+
33
+ - **id** (String) (CR) (Optimal) A unique ID for the text message. Used for statics. Default is a [UUID string](http://en.wikipedia.org/wiki/Universally_unique_identifier).
34
+ - **username** (String) (UN) Ballou username.
35
+ - **password** (String) (PW) Ballou password.
36
+ - **from** (String) (O) Who is the SMS from? Up to 10 character using text or up to 15 character using only numbers.
37
+ - **to** (String or Array< String >) (D) SMS receiver(s). May begin with a plus sign, otherwise just integers.
38
+ - **message** (String) (M) Message to be send. Max 160 character, if the `long` flag isn't set.
39
+ - **long** (No argument) (LONGSMS) Makes it possible to send a long message, up to *918* character.
40
+ - **request_id** (String) (RI) (Optimal) Default is a [UUID string](http://en.wikipedia.org/wiki/Universally_unique_identifier).
41
+
42
+ Take a look at the [official (swedish) site](http://www.ballou.se/exempel/) for more information.
43
+
44
+ ### The send! method
45
+
46
+ When you're done buildning your query the final thing todo is to apply the `send!` method.
47
+ It'll fire the request or raise an error if something was wrong.
48
+
49
+ The `send!` method returns a request object with the following methods.
50
+
51
+ - **id** (String) A unique ID generated Ballou.
52
+ - **request_id** (String) Request ID defined by you using the `request_id` method, or an auto-generated UUID string.
53
+ - **sms_id** (String) ID defined by you using the `id` method, or an auto-generated UUID string.
54
+ - **to** (String) Receiver specified by you using the `to` method.
55
+ - **send?** (Boolean) Was the SMS send?
56
+ - **valid?** (Boolean) Alias for `send?`.
57
+ - **error** (Fixnum) Error code. `0` if everything went okay.
58
+ - **status** (Fixnum) Status code. `-1` means that the SMS was added to Ballou's queue.
59
+ - **message** (String) A message from Ballou. This is set when a request goes wrong.
60
+
61
+ Here are some custom states that might be useful to know about.
62
+
63
+ When a request goes wrong, like `404`, `500` and so on, the `status` method is set to `-2`.
64
+ This, in most cases, means that you should take a look at the `error` status code for more information.
65
+ Error `7` means that the request resulted in a non `2xx` response. This should not happend unless Ballou goes down or in someway changes the API.
66
+ Take a look at the `message` method for more information.
67
+
68
+ For *even* more information and status codes, visit the [official site](http://www.ballou.se/exempel/).
69
+
70
+ ## How to install
71
+
72
+ [sudo] gem install ballou_sms_gateway
73
+
74
+ ## Requirements
75
+
76
+ *Ballou SMS gateway* is tested in *OS X 10.7.2* using Ruby *1.9.2*.
77
+
78
+ ## License
79
+
80
+ *Ballou SMS gateway* is released under the *MIT license*.
@@ -0,0 +1,25 @@
1
+ Gem::Specification.new do |gem|
2
+ gem.authors = ["Linus Oleander"]
3
+ gem.email = ["linus@oleander.nu"]
4
+ gem.description = %q{Ruby bindings for Ballou's (ballou.se) SMS Gateway.}
5
+ gem.summary = %q{Ruby bindings for Ballou's (ballou.se) SMS Gateway.}
6
+ gem.homepage = "https://github.com/oleander/ballou-sms-gateway"
7
+
8
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
9
+ gem.files = `git ls-files`.split("\n")
10
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
11
+ gem.name = "ballou_sms_gateway"
12
+ gem.require_paths = ["lib"]
13
+ gem.version = "1.0.0"
14
+
15
+ gem.add_dependency("rest-client", "~> 1.6.7")
16
+ gem.add_dependency("uuid", "~> 2.3.4")
17
+ gem.add_dependency("nokogiri", "~> 1.5.0")
18
+ gem.add_dependency("acts_as_chain", "~> 1.0.1")
19
+
20
+ gem.add_development_dependency("vcr")
21
+ gem.add_development_dependency("rspec")
22
+ gem.add_development_dependency("webmock")
23
+
24
+ gem.required_ruby_version = "~> 1.9.0"
25
+ end
@@ -0,0 +1,24 @@
1
+ module BallouSmsGatewayModule
2
+ class Request
3
+ attr_reader :id, :to, :sms_id, :request_id, :message
4
+ def initialize(args)
5
+ args.keys.each { |name| instance_variable_set "@" + name.to_s, args[name] }
6
+ end
7
+ #
8
+ # @return Boolean Did everything went okay?
9
+ #
10
+ def send?
11
+ error == 0
12
+ end
13
+
14
+ def status
15
+ @status ? @status.to_i : -2
16
+ end
17
+
18
+ def error
19
+ @error.to_i
20
+ end
21
+
22
+ alias_method :valid?, :send?
23
+ end
24
+ end
@@ -0,0 +1,153 @@
1
+ require "uuid"
2
+ require "rest-client"
3
+ require "uri"
4
+ require "cgi"
5
+ require "acts_as_chain"
6
+ require "nokogiri"
7
+ require "iconv"
8
+ require "ballou_sms_gateway/request"
9
+
10
+ class BallouSmsGateway
11
+ acts_as_chain :username, :password, :id, :request_id, :message
12
+
13
+ def initialize
14
+ #
15
+ # @UN Username
16
+ # @PW Password
17
+ # @O Sender
18
+ # @RI Request id
19
+ # @CR SMS id
20
+ # @D Receiver
21
+ # @LONGSMS Is this a long sms?
22
+ # @M Message
23
+ #
24
+ @url = %w{
25
+ http://sms2.ballou.se/http/get/SendSms.php?
26
+ UN=%s&
27
+ PW=%s&
28
+ CR=%s&
29
+ RI=%s&
30
+ O=%s&
31
+ D=%s&
32
+ LONGSMS=%s&
33
+ M=%s
34
+ }.join
35
+
36
+ @id = UUID.new.generate
37
+ @long = false
38
+ @request_id = UUID.new.generate
39
+ @error_message = nil
40
+ end
41
+
42
+ def long
43
+ tap { @long = true }
44
+ end
45
+
46
+ #
47
+ # Sends the message. Raises error if message is to long or if @send and @from isn't set.
48
+ #
49
+ def send!
50
+ if @message.length > 160 and not @long
51
+ raise "Message is to long, #{@message.length} characters."
52
+ end
53
+
54
+ [:from, :to, :password, :username].each do |method|
55
+ var = instance_variable_get("@#{method}")
56
+ unless var
57
+ raise "You need to specify #{method}, using the ##{method} method."
58
+ end
59
+ end
60
+
61
+ defaults = {
62
+ sms_id: @id,
63
+ request_id: @request_id
64
+ }
65
+
66
+ doc = Nokogiri::XML(do_request!)
67
+ if response = doc.at_css("response message")
68
+ BallouSmsGatewayModule::Request.new({
69
+ id: response.attr("id"),
70
+ message: response.text,
71
+ to: response.attr("to_msisdn"),
72
+ status: response.attr("status"),
73
+ error: response.attr("error")
74
+ }.merge(defaults))
75
+ elsif response = doc.at_css("ballou_sms_response error")
76
+ BallouSmsGatewayModule::Request.new({
77
+ to: @to,
78
+ status: -2,
79
+ error: response.attr("code"),
80
+ message: response.text,
81
+ }.merge(defaults))
82
+ else
83
+ BallouSmsGatewayModule::Request.new({
84
+ to: @to,
85
+ status: -2,
86
+ error: 7,
87
+ message: @error_message
88
+ }.merge(defaults))
89
+ end
90
+ end
91
+
92
+ #
93
+ # @to A list of phonenumbers. Can contain 0-9 and the "+" sign.
94
+ # @return BallouSmsGateway
95
+ def to(*to)
96
+ to.flatten.each do |number|
97
+ unless number.to_s.match(/^\+?[0-9]{4,}$/)
98
+ raise "Invalid receiver."
99
+ end
100
+ end
101
+
102
+ @to = to.flatten.map { |number| number }.join(",")
103
+ return self
104
+ end
105
+
106
+ #
107
+ # @from String Sender. Max length when only numbers are submitet; 15, otherwise; 10
108
+ # @return BallouSmsGateway
109
+ #
110
+ def from(from)
111
+ if from.to_s.length.zero?
112
+ raise "Sender is invalid, to short."
113
+ end
114
+
115
+ # Max length 15 for integers and 10 for chars
116
+ if from.match(/^[0-9]+$/)
117
+ if from.length > 15
118
+ raise "Sender is invalid, to long."
119
+ end
120
+ elsif from.length > 10
121
+ raise "Sender is invalid, to long."
122
+ end
123
+
124
+ @from = from
125
+ return self
126
+ end
127
+
128
+ private
129
+ def url
130
+ @url % [
131
+ @username,
132
+ @password,
133
+ @id,
134
+ @request_id,
135
+ @from,
136
+ @to,
137
+ @long,
138
+ @message
139
+ ].map{|v| URI::escape(to_latin_1(v))}
140
+ end
141
+
142
+ def do_request!
143
+ data = RestClient.get(url)
144
+ rescue RestClient::Exception
145
+ @error_message = $!.message
146
+ ensure
147
+ data || ""
148
+ end
149
+
150
+ def to_latin_1(string)
151
+ Iconv.conv("ISO-8859-1", "UTF-8", string.to_s)
152
+ end
153
+ end
@@ -0,0 +1,213 @@
1
+ describe BallouSmsGateway do
2
+ let(:long_message) { "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut a" }
3
+ let(:message) { "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostr" }
4
+ let(:gateway) { BallouSmsGateway.new }
5
+ let(:from) { "Person A" }
6
+ let(:to) { "0702211444" }
7
+ let(:id) { "858426d0-e17c-012e-9cc9-58b035fcfcff" }
8
+ let(:request_id) { "345b9360-e17c-012e-9c99-58b035fcfcff" }
9
+
10
+ describe "#message" do
11
+ before(:each) do
12
+ RestClient.should_receive(:get).any_number_of_times
13
+ end
14
+
15
+ it "should raise an error if message is to long" do
16
+ lambda {
17
+ gateway.message(long_message).send!
18
+ }.should raise_error("Message is to long, 201 characters.")
19
+ end
20
+
21
+ it "should not raise error if message is to long, if #long is used" do
22
+ lambda {
23
+ gateway.long.message(long_message).send!
24
+ }.should_not raise_error("Message is to long, 201 characters.")
25
+ end
26
+ end
27
+
28
+ describe "#send!" do
29
+ before(:each) do
30
+ RestClient.should_receive(:get).any_number_of_times
31
+ end
32
+
33
+ it "should raise error if we're trying to send a non valid message" do
34
+ lambda {
35
+ gateway.message(message).send!
36
+ }.should raise_error("You need to specify from, using the #from method.")
37
+
38
+ lambda {
39
+ gateway.from(from).message(message).send!
40
+ }.should raise_error("You need to specify to, using the #to method.")
41
+
42
+ lambda {
43
+ gateway.from(from).to(to).message(message).send!
44
+ }.should raise_error("You need to specify password, using the #password method.")
45
+
46
+ lambda {
47
+ gateway.from(from).to(to).message(message).send!
48
+ }.should raise_error("You need to specify password, using the #password method.")
49
+
50
+ lambda {
51
+ gateway.from(from).to(to).password("password").message(message).send!
52
+ }.should raise_error("You need to specify username, using the #username method.")
53
+ end
54
+ end
55
+
56
+ describe "#to" do
57
+ before(:each) do
58
+ RestClient.should_receive(:get).any_number_of_times
59
+ end
60
+
61
+ it "should fail duo to invalid phonenumber" do
62
+ ["invalid", "070-123-123", "070invalid", ["invalid"], "070+220022"].each do |number|
63
+ lambda {
64
+ gateway.to(number)
65
+ }.should raise_error("Invalid receiver.")
66
+ end
67
+ end
68
+
69
+ it "should not fail" do
70
+ ["070123123", ["070229393", "+070203993"], "8372928384"].each do |number|
71
+ lambda {
72
+ gateway.to(*number)
73
+ }.should_not raise_error
74
+ end
75
+ end
76
+ end
77
+
78
+ describe "#from" do
79
+ it "should fail, it's to long - or short" do
80
+ ["aaaaaaaaaaaa", "12345678910111213141516", ""].each do |number|
81
+ lambda {
82
+ gateway.from(number)
83
+ }.should raise_error(RuntimeError)
84
+ end
85
+ end
86
+
87
+ it "should not fail" do
88
+ ["aaaaaaaaaa", "123456789123456", "a", "1"].each do |number|
89
+ lambda {
90
+ gateway.from(number)
91
+ }.should_not raise_error
92
+ end
93
+ end
94
+
95
+ end
96
+
97
+ describe "#request_id and #id" do
98
+ it "should be possible to pass id" do
99
+ stub_request(:get, /.*/).to_return(status: 200)
100
+ request = gateway.
101
+ password(USER["password"]).
102
+ username(USER["username"]).
103
+ from("BallouSms").
104
+ to(USER["phone"]).
105
+ id("my_custom_id").
106
+ request_id(request_id).
107
+ message("This is an example").
108
+ send!
109
+ a_request(:get, /CR=my_custom_id/).should have_been_made.once
110
+ end
111
+
112
+ it "should be possible to pass request_id" do
113
+ stub_request(:get, /.*/).to_return(status: 200)
114
+ request = gateway.
115
+ password(USER["password"]).
116
+ username(USER["username"]).
117
+ from("BallouSms").
118
+ to(USER["phone"]).
119
+ id(id).
120
+ request_id("my_custom_request_id").
121
+ message("This is an example").
122
+ send!
123
+ a_request(:get, /RI=my_custom_request_id/).should have_been_made.once
124
+ end
125
+ end
126
+
127
+ describe "request" do
128
+ use_vcr_cassette "valid-request"
129
+
130
+ it "should be possible to send a message" do
131
+ request = gateway.
132
+ password(USER["password"]).
133
+ username(USER["username"]).
134
+ from("BallouSms").
135
+ to(USER["phone"]).
136
+ id(id).
137
+ request_id(request_id).
138
+ message("This is an example").
139
+ send!
140
+
141
+ request.id.should eq("219578214912")
142
+ request.sms_id.should eq(id)
143
+ request.request_id.should eq(request_id)
144
+ request.to.should eq(USER["phone"])
145
+ request.status.should eq(-1)
146
+ request.error.should eq(0)
147
+ request.message.should be_empty
148
+ request.should be_send
149
+ end
150
+
151
+ it "should send message to invalid receiver" do
152
+ request = gateway.
153
+ password(USER["password"]).
154
+ username(USER["username"]).
155
+ from("BallouSms").
156
+ to("07011").
157
+ id(id).
158
+ request_id(request_id).
159
+ message("This is an example").
160
+ send!
161
+
162
+ request.to.should eq("07011")
163
+ request.status.should eq(-2)
164
+ request.sms_id.should eq(id)
165
+ request.request_id.should eq(request_id)
166
+ request.error.should eq(3)
167
+ request.should_not be_send
168
+ end
169
+
170
+ it "should be able to handle request errors" do
171
+ stub_request(:get, /.*/).to_return(status: 404)
172
+ request = gateway.
173
+ password(USER["password"]).
174
+ username(USER["username"]).
175
+ from("BallouSms").
176
+ to(USER["phone"]).
177
+ id(id).
178
+ request_id(request_id).
179
+ message("This is an example").
180
+ send!
181
+
182
+ request.to.should eq(USER["phone"])
183
+ request.status.should eq(-2)
184
+ request.sms_id.should eq(id)
185
+ request.request_id.should eq(request_id)
186
+ request.error.should eq(7)
187
+ request.should_not be_send
188
+ request.message.should eq("404 Resource Not Found")
189
+ end
190
+ end
191
+
192
+ describe "invalid request" do
193
+ use_vcr_cassette "invalid-request"
194
+
195
+ it "should be able to handle error messages" do
196
+ request = gateway.
197
+ password("invalid").
198
+ username("invalid").
199
+ from("BallouSms").
200
+ to(USER["phone"]).
201
+ id(id).
202
+ request_id(request_id).
203
+ message("This is an example").
204
+ send!
205
+
206
+ request.should_not be_valid
207
+ request.should_not be_send
208
+ request.error.should eq(2)
209
+ request.status.should eq(-2)
210
+ request.message.should eq("Authentication failed or IP rejected")
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,32 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :get
5
+ uri: http://sms2.ballou.se:80/http/get/SendSms.php?CR=858426d0-e17c-012e-9cc9-58b035fcfcff&D=<phone>&LONGSMS=false&M=This%20is%20an%20example&O=BallouSms&PW=invalid&RI=345b9360-e17c-012e-9c99-58b035fcfcff&UN=invalid
6
+ body:
7
+ headers:
8
+ accept:
9
+ - "*/*; q=0.5, application/xml"
10
+ accept-encoding:
11
+ - gzip, deflate
12
+ response: !ruby/struct:VCR::Response
13
+ status: !ruby/struct:VCR::ResponseStatus
14
+ code: 200
15
+ message: OK
16
+ headers:
17
+ date:
18
+ - Wed, 26 Oct 2011 11:08:23 GMT
19
+ server:
20
+ - Apache
21
+ content-length:
22
+ - "277"
23
+ content-type:
24
+ - text/xml
25
+ body: |
26
+ <?xml version="1.0" encoding="ISO-8859-1"?>
27
+ <!DOCTYPE ballou_sms_response PUBLIC "-//ballou//SMS Response DTD//EN" "http://sms2.ballou.se/dtd/ballou_sms_response.dtd">
28
+ <ballou_sms_response>
29
+ <error code="2">Authentication failed or IP rejected</error>
30
+ </ballou_sms_response>
31
+
32
+ http_version: "1.1"
@@ -0,0 +1,218 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :get
5
+ uri: http://sms2.ballou.se:80/http/get/SendSms.php?CR=345b9360-e17c-012e-9c99-58b035fcfcff&D=<phone>&LONGSMS=false&M=This%20is%20an%20example&O=BallouSms&PW=<password>&RI=345b9840-e17c-012e-9c9a-58b035fcfcff&UN=<username>
6
+ body:
7
+ headers:
8
+ accept:
9
+ - "*/*; q=0.5, application/xml"
10
+ accept-encoding:
11
+ - gzip, deflate
12
+ response: !ruby/struct:VCR::Response
13
+ status: !ruby/struct:VCR::ResponseStatus
14
+ code: 200
15
+ message: OK
16
+ headers:
17
+ date:
18
+ - Tue, 25 Oct 2011 21:14:08 GMT
19
+ server:
20
+ - Apache
21
+ content-length:
22
+ - "326"
23
+ content-type:
24
+ - text/xml
25
+ body: |
26
+ <?xml version="1.0" encoding="ISO-8859-1"?>
27
+ <!DOCTYPE ballou_sms_response PUBLIC "-//ballou//SMS Response DTD//EN" "http://sms2.ballou.se/dtd/ballou_sms_response.dtd">
28
+ <ballou_sms_response>
29
+ <response type="status"><message id="219577248823" to_msisdn="<phone>" status="-1" error="0"/></response>
30
+ </ballou_sms_response>
31
+
32
+ http_version: "1.1"
33
+ - !ruby/struct:VCR::HTTPInteraction
34
+ request: !ruby/struct:VCR::Request
35
+ method: :get
36
+ uri: http://sms2.ballou.se:80/http/get/SendSms.php?CR=377ff250-e17c-012e-9ca9-58b035fcfcff&D=<phone>&LONGSMS=false&M=This%20is%20an%20example&O=BallouSms&PW=<password>&RI=377ff770-e17c-012e-9caa-58b035fcfcff&UN=<username>
37
+ body:
38
+ headers:
39
+ accept:
40
+ - "*/*; q=0.5, application/xml"
41
+ accept-encoding:
42
+ - gzip, deflate
43
+ response: !ruby/struct:VCR::Response
44
+ status: !ruby/struct:VCR::ResponseStatus
45
+ code: 200
46
+ message: OK
47
+ headers:
48
+ date:
49
+ - Tue, 25 Oct 2011 21:14:13 GMT
50
+ server:
51
+ - Apache
52
+ content-length:
53
+ - "326"
54
+ content-type:
55
+ - text/xml
56
+ body: |
57
+ <?xml version="1.0" encoding="ISO-8859-1"?>
58
+ <!DOCTYPE ballou_sms_response PUBLIC "-//ballou//SMS Response DTD//EN" "http://sms2.ballou.se/dtd/ballou_sms_response.dtd">
59
+ <ballou_sms_response>
60
+ <response type="status"><message id="219577253825" to_msisdn="<phone>" status="-1" error="0"/></response>
61
+ </ballou_sms_response>
62
+
63
+ http_version: "1.1"
64
+ - !ruby/struct:VCR::HTTPInteraction
65
+ request: !ruby/struct:VCR::Request
66
+ method: :get
67
+ uri: http://sms2.ballou.se:80/http/get/SendSms.php?CR=4460ef30-e17c-012e-9cb9-58b035fcfcff&D=<phone>&LONGSMS=false&M=This%20is%20an%20example&O=BallouSms&PW=<password>&RI=4460f640-e17c-012e-9cba-58b035fcfcff&UN=<username>
68
+ body:
69
+ headers:
70
+ accept:
71
+ - "*/*; q=0.5, application/xml"
72
+ accept-encoding:
73
+ - gzip, deflate
74
+ response: !ruby/struct:VCR::Response
75
+ status: !ruby/struct:VCR::ResponseStatus
76
+ code: 200
77
+ message: OK
78
+ headers:
79
+ date:
80
+ - Tue, 25 Oct 2011 21:14:35 GMT
81
+ server:
82
+ - Apache
83
+ content-length:
84
+ - "326"
85
+ content-type:
86
+ - text/xml
87
+ body: |
88
+ <?xml version="1.0" encoding="ISO-8859-1"?>
89
+ <!DOCTYPE ballou_sms_response PUBLIC "-//ballou//SMS Response DTD//EN" "http://sms2.ballou.se/dtd/ballou_sms_response.dtd">
90
+ <ballou_sms_response>
91
+ <response type="status"><message id="219577275827" to_msisdn="<phone>" status="-1" error="0"/></response>
92
+ </ballou_sms_response>
93
+
94
+ http_version: "1.1"
95
+ - !ruby/struct:VCR::HTTPInteraction
96
+ request: !ruby/struct:VCR::Request
97
+ method: :get
98
+ uri: http://sms2.ballou.se:80/http/get/SendSms.php?CR=858426d0-e17c-012e-9cc9-58b035fcfcff&D=<phone>&LONGSMS=false&M=This%20is%20an%20example&O=BallouSms&PW=<password>&RI=85842bf0-e17c-012e-9cca-58b035fcfcff&UN=<username>
99
+ body:
100
+ headers:
101
+ accept:
102
+ - "*/*; q=0.5, application/xml"
103
+ accept-encoding:
104
+ - gzip, deflate
105
+ response: !ruby/struct:VCR::Response
106
+ status: !ruby/struct:VCR::ResponseStatus
107
+ code: 200
108
+ message: OK
109
+ headers:
110
+ date:
111
+ - Tue, 25 Oct 2011 21:16:24 GMT
112
+ server:
113
+ - Apache
114
+ content-length:
115
+ - "326"
116
+ content-type:
117
+ - text/xml
118
+ body: |
119
+ <?xml version="1.0" encoding="ISO-8859-1"?>
120
+ <!DOCTYPE ballou_sms_response PUBLIC "-//ballou//SMS Response DTD//EN" "http://sms2.ballou.se/dtd/ballou_sms_response.dtd">
121
+ <ballou_sms_response>
122
+ <response type="status"><message id="219577384846" to_msisdn="<phone>" status="-1" error="0"/></response>
123
+ </ballou_sms_response>
124
+
125
+ http_version: "1.1"
126
+ - !ruby/struct:VCR::HTTPInteraction
127
+ request: !ruby/struct:VCR::Request
128
+ method: :get
129
+ uri: http://sms2.ballou.se:80/http/get/SendSms.php?CR=858426d0-e17c-012e-9cc9-58b035fcfcff&D=<phone>&LONGSMS=false&M=This%20is%20an%20example&O=BallouSms&PW=<password>&RI=345b9360-e17c-012e-9c99-58b035fcfcff&UN=<username>
130
+ body:
131
+ headers:
132
+ accept:
133
+ - "*/*; q=0.5, application/xml"
134
+ accept-encoding:
135
+ - gzip, deflate
136
+ response: !ruby/struct:VCR::Response
137
+ status: !ruby/struct:VCR::ResponseStatus
138
+ code: 200
139
+ message: OK
140
+ headers:
141
+ date:
142
+ - Tue, 25 Oct 2011 21:30:14 GMT
143
+ server:
144
+ - Apache
145
+ content-length:
146
+ - "326"
147
+ content-type:
148
+ - text/xml
149
+ body: |
150
+ <?xml version="1.0" encoding="ISO-8859-1"?>
151
+ <!DOCTYPE ballou_sms_response PUBLIC "-//ballou//SMS Response DTD//EN" "http://sms2.ballou.se/dtd/ballou_sms_response.dtd">
152
+ <ballou_sms_response>
153
+ <response type="status"><message id="219578214912" to_msisdn="<phone>" status="-1" error="0"/></response>
154
+ </ballou_sms_response>
155
+
156
+ http_version: "1.1"
157
+ - !ruby/struct:VCR::HTTPInteraction
158
+ request: !ruby/struct:VCR::Request
159
+ method: :get
160
+ uri: http://sms2.ballou.se:80/http/get/SendSms.php?CR=858426d0-e17c-012e-9cc9-58b035fcfcff&D=07011&LONGSMS=false&M=This%20is%20an%20example&O=BallouSms&PW=<password>&RI=345b9360-e17c-012e-9c99-58b035fcfcff&UN=<username>
161
+ body:
162
+ headers:
163
+ accept:
164
+ - "*/*; q=0.5, application/xml"
165
+ accept-encoding:
166
+ - gzip, deflate
167
+ response: !ruby/struct:VCR::Response
168
+ status: !ruby/struct:VCR::ResponseStatus
169
+ code: 200
170
+ message: OK
171
+ headers:
172
+ date:
173
+ - Tue, 25 Oct 2011 21:47:08 GMT
174
+ server:
175
+ - Apache
176
+ content-length:
177
+ - "291"
178
+ content-type:
179
+ - text/xml
180
+ body: |
181
+ <?xml version="1.0" encoding="ISO-8859-1"?>
182
+ <!DOCTYPE ballou_sms_response PUBLIC "-//ballou//SMS Response DTD//EN" "http://sms2.ballou.se/dtd/ballou_sms_response.dtd">
183
+ <ballou_sms_response>
184
+ <response type="status"><message to_msisdn="07011" error="3"/></response>
185
+ </ballou_sms_response>
186
+
187
+ http_version: "1.1"
188
+ - !ruby/struct:VCR::HTTPInteraction
189
+ request: !ruby/struct:VCR::Request
190
+ method: :get
191
+ uri: http://sms2.ballou.se:80/http/get/SendSms.php?CR=URI::escape(@id)&D=@to&LONGSMS=@long&M=CGI::escape(@message)&O=@from&PW=URI::escape(@password)&RI=URI::escape(@request_id)&UN=URI::escape(@username)
192
+ body:
193
+ headers:
194
+ accept:
195
+ - "*/*; q=0.5, application/xml"
196
+ accept-encoding:
197
+ - gzip, deflate
198
+ response: !ruby/struct:VCR::Response
199
+ status: !ruby/struct:VCR::ResponseStatus
200
+ code: 200
201
+ message: OK
202
+ headers:
203
+ date:
204
+ - Tue, 25 Oct 2011 22:11:30 GMT
205
+ server:
206
+ - Apache
207
+ content-length:
208
+ - "277"
209
+ content-type:
210
+ - text/xml
211
+ body: |
212
+ <?xml version="1.0" encoding="ISO-8859-1"?>
213
+ <!DOCTYPE ballou_sms_response PUBLIC "-//ballou//SMS Response DTD//EN" "http://sms2.ballou.se/dtd/ballou_sms_response.dtd">
214
+ <ballou_sms_response>
215
+ <error code="2">Authentication failed or IP rejected</error>
216
+ </ballou_sms_response>
217
+
218
+ http_version: "1.1"
@@ -0,0 +1,25 @@
1
+ require "rspec"
2
+ require "webmock/rspec"
3
+ require "movies"
4
+ require "vcr"
5
+ require "ballou_sms_gateway"
6
+
7
+ USER = YAML.load_file "./spec/fixtures/user_details.yml"
8
+
9
+ RSpec.configure do |config|
10
+ config.mock_with :rspec
11
+ config.extend VCR::RSpec::Macros
12
+ end
13
+
14
+ VCR.config do |c|
15
+ c.cassette_library_dir = "spec/fixtures/vcr_cassettes"
16
+ c.stub_with :webmock
17
+ c.default_cassette_options = {
18
+ record: :new_episodes
19
+ }
20
+ c.allow_http_connections_when_no_cassette = false
21
+
22
+ USER.keys.each do |key|
23
+ c.filter_sensitive_data("<#{key}>") { USER[key].to_s }
24
+ end
25
+ end
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ballou_sms_gateway
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 1.0.0
6
+ platform: ruby
7
+ authors:
8
+ - Linus Oleander
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-10-26 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rest-client
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 1.6.7
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: uuid
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: 2.3.4
35
+ type: :runtime
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: nokogiri
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.5.0
46
+ type: :runtime
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: acts_as_chain
50
+ prerelease: false
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ version: 1.0.1
57
+ type: :runtime
58
+ version_requirements: *id004
59
+ - !ruby/object:Gem::Dependency
60
+ name: vcr
61
+ prerelease: false
62
+ requirement: &id005 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ type: :development
69
+ version_requirements: *id005
70
+ - !ruby/object:Gem::Dependency
71
+ name: rspec
72
+ prerelease: false
73
+ requirement: &id006 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ type: :development
80
+ version_requirements: *id006
81
+ - !ruby/object:Gem::Dependency
82
+ name: webmock
83
+ prerelease: false
84
+ requirement: &id007 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: "0"
90
+ type: :development
91
+ version_requirements: *id007
92
+ description: Ruby bindings for Ballou's (ballou.se) SMS Gateway.
93
+ email:
94
+ - linus@oleander.nu
95
+ executables: []
96
+
97
+ extensions: []
98
+
99
+ extra_rdoc_files: []
100
+
101
+ files:
102
+ - .gitignore
103
+ - .rspec
104
+ - Gemfile
105
+ - Rakefile
106
+ - Readme.md
107
+ - ballou_sms_gateway.gemspec
108
+ - lib/ballou_sms_gateway.rb
109
+ - lib/ballou_sms_gateway/request.rb
110
+ - spec/ballou_sms_gateway_spec.rb
111
+ - spec/fixtures/vcr_cassettes/invalid-request.yml
112
+ - spec/fixtures/vcr_cassettes/valid-request.yml
113
+ - spec/spec_helper.rb
114
+ homepage: https://github.com/oleander/ballou-sms-gateway
115
+ licenses: []
116
+
117
+ post_install_message:
118
+ rdoc_options: []
119
+
120
+ require_paths:
121
+ - lib
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ~>
126
+ - !ruby/object:Gem::Version
127
+ version: 1.9.0
128
+ required_rubygems_version: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: "0"
134
+ requirements: []
135
+
136
+ rubyforge_project:
137
+ rubygems_version: 1.8.8
138
+ signing_key:
139
+ specification_version: 3
140
+ summary: Ruby bindings for Ballou's (ballou.se) SMS Gateway.
141
+ test_files:
142
+ - spec/ballou_sms_gateway_spec.rb
143
+ - spec/fixtures/vcr_cassettes/invalid-request.yml
144
+ - spec/fixtures/vcr_cassettes/valid-request.yml
145
+ - spec/spec_helper.rb