simsen 0.0.1
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/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +78 -0
- data/Rakefile +7 -0
- data/lib/simsen.rb +81 -0
- data/lib/simsen/base.rb +59 -0
- data/lib/simsen/bulksms_com.rb +75 -0
- data/lib/simsen/version.rb +3 -0
- data/simsen.gemspec +26 -0
- data/spec/simsen/base_spec.rb +69 -0
- data/spec/simsen/bulksms_com_spec.rb +113 -0
- data/spec/simsen/example_gateway_spec.rb +72 -0
- data/spec/simsen_spec.rb +42 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/support/reset_simsen_config.rb +15 -0
- data/spec/support/shoulda_matchers.rb +1 -0
- metadata +154 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Christoph König
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# Simsen
|
2
|
+
|
3
|
+
Add SMS sending capability to your application.
|
4
|
+
A simple wrapper provides basic functionally needed to create a SMS.
|
5
|
+
Also a DSL to setup the gateway and deliver the SMS is applied.
|
6
|
+
Because every provider has a different API this has to be implemented for each gateway that inherit from this wraper.
|
7
|
+
|
8
|
+
Read the [Wiki](https://github.com/SalesLentz/simsen/wiki) for more details.
|
9
|
+
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
gem 'simsen', :git => 'git@github.com:SalesLentz/simsen.git'
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
Implement your own wrapper for your required third-party SMS gateway provider or choose one of the existing implementations.
|
26
|
+
If you're going to implement a new wrapper please refer to our [example](https://github.com/SalesLentz/simsen/blob/master/spec/simsen/example_gateway_spec.rb)
|
27
|
+
|
28
|
+
Selecting and configuring the wrapper is done within the setup block.
|
29
|
+
|
30
|
+
*The following setup options are provided. Please note that a wrapper could use only a subset of them according to the provider API functionality. Please consult the wrapper test or documentation for more information.*
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
Simsen.setup do |config|
|
34
|
+
config.gateway = :example_gateway
|
35
|
+
config.password = 'secret'
|
36
|
+
config.sender = 'Sales-Lentz'
|
37
|
+
config.testmode = :off # or :on
|
38
|
+
config.testmode_strategy = :succeed # or :fail
|
39
|
+
config.username = 'username'
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
After setup is done just create a new SMS and deliver it. This method takes two parameters. First the message you want to send and second the recipients phone number.
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
sms = Simsen.new_sms('A short message', 352000000000)
|
47
|
+
```
|
48
|
+
|
49
|
+
Now you can deliver the SMS by calling `deliver` on the returned object.
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
sms.deliver
|
53
|
+
```
|
54
|
+
|
55
|
+
You can find an example implementation as a ruby script using bundler here: [https://gist.github.com/3750204](https://gist.github.com/3750204)
|
56
|
+
|
57
|
+
|
58
|
+
## Available gateway wrapper
|
59
|
+
|
60
|
+
* `:bulksms_com` - [http://bulksms.de/docs/eapi/submission/send_sms](http://bulksms.de/docs/eapi/submission/send_sms)
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
## Testing
|
65
|
+
|
66
|
+
All tests are written in RSpec, so if you checkout this gem from Github [https://github.com/SalesLentz/simsen](https://github.com/SalesLentz/simsen) you can run the tests with
|
67
|
+
|
68
|
+
$ bundle exec rake
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
## Contributing
|
73
|
+
|
74
|
+
1. Fork it
|
75
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
76
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
77
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
78
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/simsen.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
require 'curb'
|
3
|
+
require 'iconv'
|
4
|
+
require 'simsen/base'
|
5
|
+
require 'simsen/bulksms_com'
|
6
|
+
require 'simsen/version'
|
7
|
+
|
8
|
+
|
9
|
+
module Simsen
|
10
|
+
|
11
|
+
# define the gateway that should be used
|
12
|
+
# currently available gateways are:
|
13
|
+
# ---------------------------------
|
14
|
+
# * :bulksms_com (http://bulksms.de)
|
15
|
+
#
|
16
|
+
mattr_reader :gateway
|
17
|
+
def self.gateway=(value)
|
18
|
+
if value
|
19
|
+
klassname = value.to_s.split("_").map(&:capitalize).join
|
20
|
+
@@gateway = Simsen.const_get(klassname)
|
21
|
+
end
|
22
|
+
self.url = self.gateway::API_URL if self.gateway
|
23
|
+
end
|
24
|
+
@@gateway = nil
|
25
|
+
|
26
|
+
|
27
|
+
# password:
|
28
|
+
# your password for authentication
|
29
|
+
mattr_accessor :password
|
30
|
+
@@password = nil
|
31
|
+
|
32
|
+
|
33
|
+
# sender:
|
34
|
+
# sender id / origin address (if alphanumeric, max 11 characters).
|
35
|
+
mattr_accessor :sender
|
36
|
+
@@sender = nil
|
37
|
+
|
38
|
+
|
39
|
+
# testmode:
|
40
|
+
# enable or disable the api testmode if available
|
41
|
+
# enable testmode with :on, disable it with any other value like :off
|
42
|
+
mattr_reader :testmode
|
43
|
+
def self.testmode=(value)
|
44
|
+
@@testmode = value == :on ? true : false
|
45
|
+
end
|
46
|
+
@@testmode = false
|
47
|
+
|
48
|
+
|
49
|
+
# testmode_strategy:
|
50
|
+
# defines the testmode behavior
|
51
|
+
# :succeed - simulate successful sms sending (default)
|
52
|
+
# :fail - simulate failing sms sending
|
53
|
+
mattr_reader :testmode_strategy
|
54
|
+
def self.testmode_strategy=(value)
|
55
|
+
@@testmode_strategy = value == :succeed ? :succeed : :fail
|
56
|
+
end
|
57
|
+
@@testmode_strategy = :succeed
|
58
|
+
|
59
|
+
|
60
|
+
# url:
|
61
|
+
# API url defined at the selected gateway
|
62
|
+
mattr_accessor :url
|
63
|
+
@@url = nil
|
64
|
+
|
65
|
+
|
66
|
+
# username:
|
67
|
+
# your username for authentication
|
68
|
+
mattr_accessor :username
|
69
|
+
@@username = nil
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
def self.setup
|
74
|
+
yield(self)
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.new_sms(message, phone_number)
|
78
|
+
gateway.new_sms(message, phone_number) if gateway.respond_to?(:new_sms)
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
data/lib/simsen/base.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
module Simsen
|
2
|
+
|
3
|
+
class Base
|
4
|
+
include ActiveModel::Validations
|
5
|
+
include ActiveModel::MassAssignmentSecurity
|
6
|
+
|
7
|
+
attr_accessor :message, :phone_number, :status
|
8
|
+
attr_accessible nil
|
9
|
+
|
10
|
+
validates :message, :phone_number, :presence => true
|
11
|
+
validates :status, :inclusion => { :in => %w(prepared) }
|
12
|
+
|
13
|
+
def self.new_sms(message, phone_number)
|
14
|
+
gateway = self.new_in_prepared_state
|
15
|
+
gateway.message = message
|
16
|
+
gateway.phone_number = phone_number
|
17
|
+
gateway
|
18
|
+
end
|
19
|
+
|
20
|
+
def deliver
|
21
|
+
raise(NotImplementedError, 'You must implement #deliver in a class inherited from Simsen::Base to implement sms delivery for the selected SMS-Gateway')
|
22
|
+
end
|
23
|
+
|
24
|
+
def password
|
25
|
+
Simsen.password
|
26
|
+
end
|
27
|
+
|
28
|
+
def sender
|
29
|
+
Simsen.sender
|
30
|
+
end
|
31
|
+
|
32
|
+
def testmode
|
33
|
+
Simsen.testmode
|
34
|
+
end
|
35
|
+
|
36
|
+
def testmode_strategy
|
37
|
+
Simsen.testmode_strategy
|
38
|
+
end
|
39
|
+
|
40
|
+
def url
|
41
|
+
Simsen.url
|
42
|
+
end
|
43
|
+
|
44
|
+
def username
|
45
|
+
Simsen.username
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
|
52
|
+
def self.new_in_prepared_state
|
53
|
+
gateway = self.new
|
54
|
+
gateway.status = "prepared"
|
55
|
+
gateway
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Simsen
|
2
|
+
|
3
|
+
# refer to http://bulksms.de/docs/eapi/submission/send_sms for more information
|
4
|
+
class BulksmsCom < Base
|
5
|
+
|
6
|
+
# API_URL:
|
7
|
+
# URL pointing to the sms gateway
|
8
|
+
# You can fall back to port 80 if you have firewall-related problems connecting to us
|
9
|
+
# but we recommend that you rather take the time to allow outgoing access to ports 5567 and 7512 via your firewall.
|
10
|
+
# refer to http://bulksms.de/docs/eapi/submission/faq
|
11
|
+
API_URL = 'http://bulksms.de:5567/eapi/submission/send_sms/2/2.0'
|
12
|
+
|
13
|
+
|
14
|
+
# dca:
|
15
|
+
# Data Coding Alphabet: 7bit,8bit or 16bit, default 7bit (normal text message).
|
16
|
+
# For 8bit (ringtones,logos) or 16bit (Unicode), a message containing only hexadecimal octets,
|
17
|
+
# to a maximum of 140 octets (where an octet is e.g. ff), must be submitted
|
18
|
+
# (the UDHI is always set for 8-bit messages). 16-bit is a route-specific feature.
|
19
|
+
mattr_reader :dca
|
20
|
+
@@dca = '7bit'
|
21
|
+
|
22
|
+
|
23
|
+
# msg_class:
|
24
|
+
# 0 (flash SMS), 1, 2 (normal SMS, stored to SIM card), 3 - default 2
|
25
|
+
mattr_reader :msg_class
|
26
|
+
@@msg_class = 2
|
27
|
+
|
28
|
+
|
29
|
+
# test_always_fail:
|
30
|
+
# as for test_always_succeed, but after basic validation, always returns a failure code.
|
31
|
+
mattr_reader :test_always_fail
|
32
|
+
@@test_always_fail = 1
|
33
|
+
|
34
|
+
|
35
|
+
# test_always_succeed:
|
36
|
+
# for testing purposes - if set to 1, does basic validation (username, password, etc) of your submission,
|
37
|
+
# but stops short of actually submitting the messages, and returns a successful status code as if it had
|
38
|
+
# submitted them successfully.
|
39
|
+
mattr_reader :test_always_succeed
|
40
|
+
@@test_always_succeed = 1
|
41
|
+
|
42
|
+
|
43
|
+
# want_report:
|
44
|
+
# refer to http://bulksms.de/docs/eapi/status_reports/http_push for more information about status reports
|
45
|
+
# disable 0 or enable 1 reports, default 1
|
46
|
+
mattr_reader :want_report
|
47
|
+
@@want_report = 1
|
48
|
+
|
49
|
+
|
50
|
+
def deliver
|
51
|
+
Curl.post(url, params_hash) if valid?
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
|
58
|
+
def params_hash
|
59
|
+
converter = Iconv.new('ISO-8859-1//TRANSLIT', 'UTF-8')
|
60
|
+
{
|
61
|
+
:dca => dca,
|
62
|
+
:message => converter.iconv(message),
|
63
|
+
:msg_class => msg_class,
|
64
|
+
:msisdn => phone_number,
|
65
|
+
:password => password,
|
66
|
+
:sender => sender,
|
67
|
+
:test_always_fail => testmode && testmode_strategy == :fail ? test_always_fail : nil,
|
68
|
+
:test_always_succeed => testmode && testmode_strategy == :succeed ? test_always_succeed : nil,
|
69
|
+
:username => username,
|
70
|
+
:want_report => want_report
|
71
|
+
}.delete_if {|key, value| value.to_s.blank? }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
data/simsen.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'simsen/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "simsen"
|
8
|
+
gem.version = Simsen::VERSION
|
9
|
+
gem.authors = ["Christoph König"]
|
10
|
+
gem.email = ["christoph.koenig@sales-lentz.lu"]
|
11
|
+
gem.description = %q{Add SMS sending capability to your application. A simple wrapper provides basic functionally needed to create a SMS. Also a DSL to setup the gateway and deliver the SMS is applied. Because every provider has a different API this has to be implemented for each gateway that inherit from this wraper.}
|
12
|
+
gem.summary = %q{Wrapper dor sending SMS using a third-party gateway API}
|
13
|
+
gem.homepage = "https://github.com/SalesLentz/simsen"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency 'activemodel', '~> 3.0'
|
21
|
+
gem.add_dependency 'curb', '~> 0.8.1'
|
22
|
+
|
23
|
+
gem.add_development_dependency 'rake'
|
24
|
+
gem.add_development_dependency 'rspec'
|
25
|
+
gem.add_development_dependency 'shoulda-matchers'
|
26
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
|
6
|
+
module Simsen
|
7
|
+
|
8
|
+
describe Base do
|
9
|
+
let(:message) { "Lorem ipsum" }
|
10
|
+
let(:phone_number) { "003521234567890" }
|
11
|
+
|
12
|
+
context "validations" do
|
13
|
+
it { should validate_presence_of(:message) }
|
14
|
+
it { should validate_presence_of(:phone_number) }
|
15
|
+
it { should allow_value("prepared").for(:status) }
|
16
|
+
it { should_not allow_value("other").for(:status) }
|
17
|
+
end
|
18
|
+
|
19
|
+
context "mass assignment security" do
|
20
|
+
it { should_not allow_mass_assignment_of(:message) }
|
21
|
+
it { should_not allow_mass_assignment_of(:phone_number) }
|
22
|
+
it { should_not allow_mass_assignment_of(:status) }
|
23
|
+
end
|
24
|
+
|
25
|
+
context "#self.new_sms" do
|
26
|
+
subject { Base.new_sms(message, phone_number) }
|
27
|
+
its(:message) { should eq "Lorem ipsum" }
|
28
|
+
its(:phone_number) { should eq "003521234567890" }
|
29
|
+
its(:status) { should eq "prepared" }
|
30
|
+
it { should be_valid }
|
31
|
+
end
|
32
|
+
|
33
|
+
context "#deliver" do
|
34
|
+
subject { Base.new_sms(message, phone_number) }
|
35
|
+
it "raise error that this method has to be implemented in class inherited from Simsen::Base to implement sms delivery for the selected SMS-Gateway" do
|
36
|
+
expect { subject.deliver }.to raise_error(NotImplementedError, "You must implement #deliver in a class inherited from Simsen::Base to implement sms delivery for the selected SMS-Gateway")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "Simsen setup reader" do
|
41
|
+
let(:gateway) { Base.new }
|
42
|
+
it "#password should return Simsen.password" do
|
43
|
+
Simsen.should_receive(:password).and_return("secret")
|
44
|
+
gateway.password.should eq "secret"
|
45
|
+
end
|
46
|
+
it "#sender should return Simsen.sender" do
|
47
|
+
Simsen.should_receive(:sender).and_return("Sales-Lentz")
|
48
|
+
gateway.sender.should eq "Sales-Lentz"
|
49
|
+
end
|
50
|
+
it "#testmode should return Simsen.testmode" do
|
51
|
+
Simsen.should_receive(:testmode).and_return("off")
|
52
|
+
gateway.testmode.should eq "off"
|
53
|
+
end
|
54
|
+
it "#testmode_strategy should return Simsen.testmode_strategy" do
|
55
|
+
Simsen.should_receive(:testmode_strategy).and_return("success")
|
56
|
+
gateway.testmode_strategy.should eq "success"
|
57
|
+
end
|
58
|
+
it "#url should return Simsen.url" do
|
59
|
+
Simsen.should_receive(:url).and_return("https://www.example.com")
|
60
|
+
gateway.url.should eq "https://www.example.com"
|
61
|
+
end
|
62
|
+
it "#username should return Simsen.username" do
|
63
|
+
Simsen.should_receive(:username).and_return("admin")
|
64
|
+
gateway.username.should eq "admin"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
|
6
|
+
module Simsen
|
7
|
+
|
8
|
+
describe BulksmsCom do
|
9
|
+
|
10
|
+
# Helper for converting charset
|
11
|
+
def utf_8_to_iso_8859_1(string)
|
12
|
+
@converter ||= Iconv.new('ISO-8859-1//TRANSLIT', 'UTF-8')
|
13
|
+
@converter.iconv(string)
|
14
|
+
end
|
15
|
+
|
16
|
+
# See API documentation for parameter description
|
17
|
+
# http://bulksms.de/docs/eapi/submission/send_sms
|
18
|
+
context "default values regarding the api" do
|
19
|
+
context "API_URL" do
|
20
|
+
it { BulksmsCom::API_URL.should eq "http://bulksms.de:5567/eapi/submission/send_sms/2/2.0" }
|
21
|
+
end
|
22
|
+
its(:dca) { should eq '7bit' }
|
23
|
+
its(:msg_class) { should eq 2 }
|
24
|
+
its(:test_always_fail) { should eq 1 }
|
25
|
+
its(:test_always_succeed) { should eq 1 }
|
26
|
+
its(:want_report) { should eq 1 }
|
27
|
+
end
|
28
|
+
|
29
|
+
context "#deliver" do
|
30
|
+
before do
|
31
|
+
Simsen.setup do |config|
|
32
|
+
config.gateway = :bulksms_com
|
33
|
+
config.password = "secret"
|
34
|
+
config.testmode = :off
|
35
|
+
config.username = "admin"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
let(:message) { "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, öäü éàèë nonumy eirmod tempor invidunt ut l" }
|
39
|
+
let(:phone_number) { "3521234567890" }
|
40
|
+
let(:sms) { Simsen.new_sms(message, phone_number) }
|
41
|
+
context "should deliver if it is valid" do
|
42
|
+
it "talk to the gateway" do
|
43
|
+
Curl.should_receive(:post).with(
|
44
|
+
"http://bulksms.de:5567/eapi/submission/send_sms/2/2.0",
|
45
|
+
{
|
46
|
+
:dca => '7bit',
|
47
|
+
:message => utf_8_to_iso_8859_1("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, öäü éàèë nonumy eirmod tempor invidunt ut l"),
|
48
|
+
:msg_class => 2,
|
49
|
+
:msisdn => "3521234567890",
|
50
|
+
:password => 'secret',
|
51
|
+
:username => 'admin',
|
52
|
+
:want_report => 1
|
53
|
+
}
|
54
|
+
)
|
55
|
+
sms.deliver
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "should not deliver unless it is valid" do
|
60
|
+
let(:message) { "" }
|
61
|
+
let(:phone_number) { "" }
|
62
|
+
it "don't talk to the gateway" do
|
63
|
+
Curl.should_not_receive(:post)
|
64
|
+
sms.deliver
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "testmode" do
|
69
|
+
it "with successful result" do
|
70
|
+
Curl.should_receive(:post).with(
|
71
|
+
"http://bulksms.de:5567/eapi/submission/send_sms/2/2.0",
|
72
|
+
{
|
73
|
+
:dca => '7bit',
|
74
|
+
:message => utf_8_to_iso_8859_1("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, öäü éàèë nonumy eirmod tempor invidunt ut l"),
|
75
|
+
:msg_class => 2,
|
76
|
+
:msisdn => "3521234567890",
|
77
|
+
:password => 'secret',
|
78
|
+
:test_always_succeed => 1,
|
79
|
+
:username => 'admin',
|
80
|
+
:want_report => 1
|
81
|
+
}
|
82
|
+
)
|
83
|
+
Simsen.setup do |config|
|
84
|
+
config.testmode = :on
|
85
|
+
config.testmode_strategy = :succeed
|
86
|
+
end
|
87
|
+
sms.deliver
|
88
|
+
end
|
89
|
+
it "with failing result" do
|
90
|
+
Curl.should_receive(:post).with(
|
91
|
+
"http://bulksms.de:5567/eapi/submission/send_sms/2/2.0",
|
92
|
+
{
|
93
|
+
:dca => '7bit',
|
94
|
+
:message => utf_8_to_iso_8859_1("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, öäü éàèë nonumy eirmod tempor invidunt ut l"),
|
95
|
+
:msg_class => 2,
|
96
|
+
:msisdn => "3521234567890",
|
97
|
+
:password => 'secret',
|
98
|
+
:test_always_fail => 1,
|
99
|
+
:username => 'admin',
|
100
|
+
:want_report => 1
|
101
|
+
}
|
102
|
+
)
|
103
|
+
Simsen.setup do |config|
|
104
|
+
config.testmode = :on
|
105
|
+
config.testmode_strategy = :fail
|
106
|
+
end
|
107
|
+
sms.deliver
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
|
6
|
+
# Example implementation of a SMS gateway to send SMS via a specific provider
|
7
|
+
# It should inherit from Simsen::Base to inherit the base functionallity.
|
8
|
+
# Because the necessary setup and delivery is different for each provider,
|
9
|
+
# it has to implement #self.setup and #deliver by its own.
|
10
|
+
#
|
11
|
+
#
|
12
|
+
module Simsen
|
13
|
+
|
14
|
+
class ExampleGateway < Simsen::Base
|
15
|
+
|
16
|
+
# API_URL:
|
17
|
+
# URL pointing to the sms gateway
|
18
|
+
API_URL = "https://url.to.gateway.example.com"
|
19
|
+
|
20
|
+
# some_api_param:
|
21
|
+
# define provider specific API parameters
|
22
|
+
mattr_reader :some_api_param
|
23
|
+
@@some_api_param = "some_value"
|
24
|
+
|
25
|
+
|
26
|
+
def deliver
|
27
|
+
"#{url}/send_sms?username=#{username}&password=#{password}&message=#{message}&phone_number=#{phone_number}&some_api_param=#{some_api_param}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
# Don't forget to wirte tests for each gateway implementation !
|
36
|
+
#
|
37
|
+
#
|
38
|
+
module Simsen
|
39
|
+
|
40
|
+
describe ExampleGateway do
|
41
|
+
let(:message) { "Hi Mom & Dad" }
|
42
|
+
let(:phone_number) { "+3521234567890" }
|
43
|
+
|
44
|
+
it "should inherit from Simsen::Base" do
|
45
|
+
should be_kind_of(Simsen::Base)
|
46
|
+
end
|
47
|
+
|
48
|
+
context "default values regarding the api" do
|
49
|
+
context "API_URL" do
|
50
|
+
it { ExampleGateway::API_URL.should eq "https://url.to.gateway.example.com" }
|
51
|
+
end
|
52
|
+
its(:some_api_param) { should eq 'some_value' }
|
53
|
+
end
|
54
|
+
|
55
|
+
context "configure gateway and deliver sms" do
|
56
|
+
before do
|
57
|
+
Simsen.setup do |config|
|
58
|
+
config.gateway = :example_gateway
|
59
|
+
config.username = "admin"
|
60
|
+
config.password = "secret"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
let(:sms) { Simsen.new_sms(message, phone_number) }
|
64
|
+
subject { sms.deliver }
|
65
|
+
it "implemented #deliver with a dummy response without using any third-party API" do
|
66
|
+
should eq "https://url.to.gateway.example.com/send_sms?username=admin&password=secret&message=Hi Mom & Dad&phone_number=+3521234567890&some_api_param=some_value"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
data/spec/simsen_spec.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
|
6
|
+
describe Simsen do
|
7
|
+
|
8
|
+
context "#self.setup" do
|
9
|
+
it { expect { Simsen.setup {} }.not_to raise_error }
|
10
|
+
|
11
|
+
context "with all options" do
|
12
|
+
before do
|
13
|
+
Simsen.setup do |config|
|
14
|
+
config.gateway = :bulksms_com
|
15
|
+
config.password = "secret"
|
16
|
+
config.sender = "Sales Lentz"
|
17
|
+
config.testmode = :off
|
18
|
+
config.testmode_strategy = :succeed
|
19
|
+
config.url = "http://www.example.com"
|
20
|
+
config.username = "admin"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
its(:gateway) { should eq Simsen::BulksmsCom }
|
24
|
+
its(:password) { should eq "secret" }
|
25
|
+
its(:sender) { should eq "Sales Lentz" }
|
26
|
+
its(:testmode) { should be_false }
|
27
|
+
its(:testmode_strategy) { should eq :succeed }
|
28
|
+
its(:url) { should eq "http://www.example.com" }
|
29
|
+
its(:username) { should eq "admin" }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "#self.new_sms" do
|
34
|
+
let(:message) { "Hi Mom & Dad" }
|
35
|
+
let(:phone_number) { "+3521234567890" }
|
36
|
+
it "should be delegated to the gateway" do
|
37
|
+
Simsen.gateway.should_receive(:new_sms).with("Hi Mom & Dad", "+3521234567890")
|
38
|
+
Simsen.new_sms(message, phone_number)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'bundler/setup'
|
10
|
+
|
11
|
+
require 'simsen' # and any other gems you need
|
12
|
+
|
13
|
+
PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..')).freeze
|
14
|
+
Dir[File.join(PROJECT_ROOT, 'spec', 'support', '**', '*.rb')].each { |file| require(file) }
|
15
|
+
|
16
|
+
RSpec.configure do |config|
|
17
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
18
|
+
config.run_all_when_everything_filtered = true
|
19
|
+
config.filter_run :focus
|
20
|
+
|
21
|
+
# Run specs in random order to surface order dependencies. If you find an
|
22
|
+
# order dependency and want to debug it, you can fix the order by providing
|
23
|
+
# the seed, which is printed after each run.
|
24
|
+
# --seed 1234
|
25
|
+
config.order = 'random'
|
26
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
RSpec.configure do |config|
|
2
|
+
|
3
|
+
config.before(:each) do
|
4
|
+
Simsen.setup do |config|
|
5
|
+
config.gateway = nil
|
6
|
+
config.password = nil
|
7
|
+
config.sender = nil
|
8
|
+
config.testmode = :off
|
9
|
+
config.testmode_strategy = :succeed
|
10
|
+
config.url = nil
|
11
|
+
config.username = nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'shoulda/matchers'
|
metadata
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simsen
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Christoph König
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-20 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activemodel
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '3.0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: curb
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.8.1
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.8.1
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rspec
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: shoulda-matchers
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
description: Add SMS sending capability to your application. A simple wrapper provides
|
95
|
+
basic functionally needed to create a SMS. Also a DSL to setup the gateway and deliver
|
96
|
+
the SMS is applied. Because every provider has a different API this has to be implemented
|
97
|
+
for each gateway that inherit from this wraper.
|
98
|
+
email:
|
99
|
+
- christoph.koenig@sales-lentz.lu
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- .gitignore
|
105
|
+
- .rspec
|
106
|
+
- Gemfile
|
107
|
+
- LICENSE.txt
|
108
|
+
- README.md
|
109
|
+
- Rakefile
|
110
|
+
- lib/simsen.rb
|
111
|
+
- lib/simsen/base.rb
|
112
|
+
- lib/simsen/bulksms_com.rb
|
113
|
+
- lib/simsen/version.rb
|
114
|
+
- simsen.gemspec
|
115
|
+
- spec/simsen/base_spec.rb
|
116
|
+
- spec/simsen/bulksms_com_spec.rb
|
117
|
+
- spec/simsen/example_gateway_spec.rb
|
118
|
+
- spec/simsen_spec.rb
|
119
|
+
- spec/spec_helper.rb
|
120
|
+
- spec/support/reset_simsen_config.rb
|
121
|
+
- spec/support/shoulda_matchers.rb
|
122
|
+
homepage: https://github.com/SalesLentz/simsen
|
123
|
+
licenses: []
|
124
|
+
post_install_message:
|
125
|
+
rdoc_options: []
|
126
|
+
require_paths:
|
127
|
+
- lib
|
128
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
|
+
none: false
|
136
|
+
requirements:
|
137
|
+
- - ! '>='
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
140
|
+
requirements: []
|
141
|
+
rubyforge_project:
|
142
|
+
rubygems_version: 1.8.24
|
143
|
+
signing_key:
|
144
|
+
specification_version: 3
|
145
|
+
summary: Wrapper dor sending SMS using a third-party gateway API
|
146
|
+
test_files:
|
147
|
+
- spec/simsen/base_spec.rb
|
148
|
+
- spec/simsen/bulksms_com_spec.rb
|
149
|
+
- spec/simsen/example_gateway_spec.rb
|
150
|
+
- spec/simsen_spec.rb
|
151
|
+
- spec/spec_helper.rb
|
152
|
+
- spec/support/reset_simsen_config.rb
|
153
|
+
- spec/support/shoulda_matchers.rb
|
154
|
+
has_rdoc:
|