action_sms 0.0.3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -3
- data/Gemfile +4 -0
- data/README.markdown +141 -8
- data/Rakefile +2 -38
- data/action_sms.gemspec +16 -42
- data/lib/action_sms/base.rb +113 -3
- data/lib/action_sms/connection_adapters.rb +4 -1
- data/lib/action_sms/connection_adapters/abstract_adapter.rb +45 -3
- data/lib/action_sms/connection_adapters/sms_global_adapter.rb +76 -0
- data/lib/action_sms/connection_adapters/test_helpers/sms_global.rb +68 -0
- data/lib/action_sms/connection_adapters/test_helpers/tropo.rb +67 -0
- data/lib/action_sms/connection_adapters/tropo_adapter.rb +73 -0
- data/lib/action_sms/version.rb +4 -0
- data/lib/generators/action_sms/initializer/initializer_generator.rb +29 -2
- data/lib/generators/action_sms/initializer/templates/action_sms.rb +28 -8
- data/spec/base_spec.rb +649 -0
- data/spec/connection_adapters/abstract_adapter_spec.rb +58 -0
- data/spec/connection_adapters/sms_global_adapter_spec.rb +259 -0
- data/spec/connection_adapters/test_helpers/sms_global_spec.rb +204 -0
- data/spec/connection_adapters/test_helpers/tropo_spec.rb +135 -0
- data/spec/connection_adapters/tropo_adapter_spec.rb +198 -0
- data/spec/spec_helper.rb +6 -0
- data/todo +0 -2
- metadata +39 -14
- data/VERSION +0 -1
data/.gitignore
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
pkg/*
|
2
|
+
*.gem
|
3
|
+
.bundle
|
data/Gemfile
ADDED
data/README.markdown
CHANGED
@@ -1,26 +1,159 @@
|
|
1
1
|
# action_sms
|
2
2
|
|
3
|
-
action_sms allows you to
|
3
|
+
action_sms allows you to switch between SMS Gateways effortlessly without modifying your application or test code. By keeping SMS Gateway configuration out of your code you can be more adaptable to change.
|
4
|
+
|
5
|
+
## Current SMS Gateway Adapters
|
6
|
+
|
7
|
+
* [SMSGlobal](http://www.smsglobal.com)
|
8
|
+
* [Tropo](http://www.tropo.com)
|
9
|
+
|
10
|
+
## Adapter Specific Configuration
|
11
|
+
|
12
|
+
* [SMSGlobal](http://github.com/dwilkie/action_sms/wiki/SMSGlobal)
|
13
|
+
* [Tropo](http://github.com/dwilkie/action_sms/wiki/Tropo)
|
4
14
|
|
5
15
|
## Usage
|
6
16
|
|
17
|
+
### Configuration
|
18
|
+
|
7
19
|
Establish a connection to your SMS Gateway Adapter:
|
8
20
|
|
9
21
|
ActionSms::Base.establish_connection(
|
10
22
|
:adapter => 'your_adapter',
|
11
23
|
# the remaining options are specific to the SMS Gateway Adapter
|
12
|
-
:username => '
|
13
|
-
:password => '
|
24
|
+
:username => 'username',
|
25
|
+
:password => 'password'
|
14
26
|
)
|
15
27
|
The only required option is `:adapter`. This specifies the SMS Gateway adapter you want to use. The remaining options are specific to the adapter.
|
16
28
|
|
17
|
-
|
29
|
+
### Send an SMS and check if it was successful
|
30
|
+
|
31
|
+
class SMS
|
32
|
+
def recipient
|
33
|
+
"617198378843"
|
34
|
+
end
|
35
|
+
|
36
|
+
def body
|
37
|
+
"Hello world"
|
38
|
+
end
|
39
|
+
|
40
|
+
def from
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
response = ActionSms::Base.deliver(SMS.new)
|
45
|
+
success = ActionSms::Base.delivery_request_successful?(response)
|
46
|
+
|
47
|
+
### Receive an SMS
|
48
|
+
|
49
|
+
# Assume 'params' has the data posted back to your server
|
50
|
+
|
51
|
+
# get sender
|
52
|
+
sender = ActionSms::Base.sender(params)
|
53
|
+
|
54
|
+
# get message text
|
55
|
+
message_text = ActionSms::Base.message_text(params)
|
56
|
+
|
57
|
+
### Delivery receipts
|
58
|
+
|
59
|
+
# Assume 'receipt' has the data posted back to your server as the delivery receipt
|
60
|
+
|
61
|
+
# get status
|
62
|
+
status = ActionSms::Base.status(receipt)
|
63
|
+
|
64
|
+
# get message id
|
65
|
+
message_id = ActionSms::Base.message_id(receipt)
|
66
|
+
|
67
|
+
### Authentication
|
68
|
+
|
69
|
+
ActionSms::Base.establish_connection(
|
70
|
+
:authentication_key => "my secret",
|
71
|
+
:use_ssl => true
|
72
|
+
)
|
73
|
+
|
74
|
+
If you set up an: `authentication_key` in the configuration, your key will be passed back to your listener url. Using an authentication key in conjunction with a secure connection `use_ssl => true` helps protect you against someone faking incoming messages to your server. You can authenticate an incoming message as follows:
|
75
|
+
|
76
|
+
# Assume 'params' has the data posted back to your server
|
77
|
+
|
78
|
+
# Removes the authentication key from 'params' and returns true or false
|
79
|
+
ActionSms::Base.authenticate(params)
|
80
|
+
|
81
|
+
### Service url
|
82
|
+
|
83
|
+
# gets the gateway's api url
|
84
|
+
# ActionSms::Base.service_url
|
85
|
+
|
86
|
+
## Testing
|
87
|
+
|
88
|
+
When you set: `:environment => "test"` in your configuration, you get some additional test helpers.
|
89
|
+
|
90
|
+
ActionSms::Base.establish_connection(
|
91
|
+
:environment => "test"
|
92
|
+
)
|
93
|
+
|
94
|
+
# get sample configuration
|
95
|
+
ActionSms::Base.sample_configuration
|
96
|
+
|
97
|
+
# get sample incoming SMS params
|
98
|
+
ActionSms::Base.sample_incoming_sms
|
99
|
+
|
100
|
+
# get customized sample incoming SMS
|
101
|
+
ActionSms::Base.sample_incoming_sms(
|
102
|
+
:message => "hello",
|
103
|
+
:to => "6128392323",
|
104
|
+
:from => "61289339432",
|
105
|
+
:date => Time.now,
|
106
|
+
:authentic => false # see configuration
|
107
|
+
)
|
108
|
+
|
109
|
+
# get sample delivery response
|
110
|
+
ActionSms::Base.sample_delivery_response
|
111
|
+
|
112
|
+
# get sample delivery response (failed)
|
113
|
+
ActionSms::Base.sample_delivery_response(:failed => true)
|
114
|
+
|
115
|
+
# get a sample delivery response with a message id
|
116
|
+
ActionSms::Base.sample_delivery_response_with_message_id("12345")
|
117
|
+
|
118
|
+
# get sample message id
|
119
|
+
ActionSms::Base.sample_message_id
|
120
|
+
|
121
|
+
# get sample delivery receipt
|
122
|
+
ActionSms::Base.sample_delivery_receipt
|
123
|
+
|
124
|
+
# get customized sample delivery receipt
|
125
|
+
ActionSms::Base.sample_delivery_receipt(
|
126
|
+
:message_id => "12345",
|
127
|
+
:status => "delivered",
|
128
|
+
:error => "some error",
|
129
|
+
:date => Time.now
|
130
|
+
)
|
131
|
+
|
132
|
+
## Creating your own adapter
|
133
|
+
|
134
|
+
To create your own adapter all you need to do is open up the ActionSms::Base class
|
135
|
+
and add a class method named: `my_adapter_connection` which takes a single hash argument of configuration details and returns an instance of your adapter class. For example, let's create an adapter for clickatell:
|
136
|
+
|
137
|
+
# clickatell_adapter.rb
|
138
|
+
require 'action_sms/connection_adapters/abstract_adapter'
|
18
139
|
|
19
|
-
ActionSms
|
140
|
+
module ActionSms
|
141
|
+
class Base
|
142
|
+
def self.clickatell_connection(config)
|
143
|
+
ConnectionAdapters::ClickatellAdapter.new(config)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
20
147
|
|
21
|
-
|
148
|
+
module ConnectionAdapters
|
149
|
+
class ClickatellAdapter < AbstractAdapter
|
150
|
+
# define your adapter here ...
|
151
|
+
def initialize(config)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
22
155
|
|
23
|
-
|
156
|
+
Take a look at the [source](http://github.com/dwilkie/action_sms/tree/master/lib/action_sms/connection_adapters/) for more details
|
24
157
|
|
25
158
|
## Rails
|
26
159
|
|
@@ -28,7 +161,7 @@ For convenience there is a generator that can be used if you are using action_sm
|
|
28
161
|
|
29
162
|
rails g action_sms:initializer
|
30
163
|
|
31
|
-
Generates an initializer
|
164
|
+
Generates an initializer including example configuration for built-in adapters
|
32
165
|
|
33
166
|
## Installation
|
34
167
|
|
data/Rakefile
CHANGED
@@ -1,38 +1,2 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
require 'rake/rdoctask'
|
4
|
-
|
5
|
-
desc 'Default: run unit tests.'
|
6
|
-
task :default => :test
|
7
|
-
|
8
|
-
desc 'Test the ActionSMS plugin.'
|
9
|
-
Rake::TestTask.new(:test) do |t|
|
10
|
-
t.libs << 'lib'
|
11
|
-
t.libs << 'spec'
|
12
|
-
t.libs << 'features'
|
13
|
-
t.pattern = 'spec/**/*_spec.rb'
|
14
|
-
t.verbose = true
|
15
|
-
end
|
16
|
-
|
17
|
-
begin
|
18
|
-
require 'jeweler'
|
19
|
-
Jeweler::Tasks.new do |gemspec|
|
20
|
-
gemspec.name = "action_sms"
|
21
|
-
gemspec.summary = "Lightweight SMS wrapper which can use any gateway"
|
22
|
-
gemspec.email = "dwilkie@gmail.com"
|
23
|
-
gemspec.homepage = "http://github.com/dwilkie/action_sms"
|
24
|
-
gemspec.authors = ["David Wilkie"]
|
25
|
-
end
|
26
|
-
rescue LoadError
|
27
|
-
puts "Jeweler not available. Install it with: gem install jeweler"
|
28
|
-
end
|
29
|
-
|
30
|
-
desc 'Generate documentation for the ActionSMS plugin.'
|
31
|
-
Rake::RDocTask.new(:rdoc) do |rdoc|
|
32
|
-
rdoc.rdoc_dir = 'rdoc'
|
33
|
-
rdoc.title = 'ActionSMS'
|
34
|
-
rdoc.options << '--line-numbers' << '--inline-source'
|
35
|
-
rdoc.rdoc_files.include('README')
|
36
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
37
|
-
end
|
38
|
-
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
data/action_sms.gemspec
CHANGED
@@ -1,50 +1,24 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "action_sms/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |s|
|
7
|
-
s.name
|
8
|
-
s.version
|
6
|
+
s.name = "action_sms"
|
7
|
+
s.version = ActionSms::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["David Wilkie"]
|
10
|
+
s.email = ["dwilkie@gmail.com"]
|
11
|
+
s.homepage = "http://github.com/dwilkie/action_sms"
|
12
|
+
s.summary = %q{Effortlessly switch between SMS Gateways}
|
13
|
+
s.description = %q{Switch between SMS Gateways at a whim without modifying your application code or tests}
|
9
14
|
|
10
|
-
s.
|
11
|
-
s.authors = ["David Wilkie"]
|
12
|
-
s.date = %q{2010-10-14}
|
13
|
-
s.email = %q{dwilkie@gmail.com}
|
14
|
-
s.extra_rdoc_files = [
|
15
|
-
"README.markdown"
|
16
|
-
]
|
17
|
-
s.files = [
|
18
|
-
".gitignore",
|
19
|
-
"MIT-LICENSE",
|
20
|
-
"README.markdown",
|
21
|
-
"Rakefile",
|
22
|
-
"VERSION",
|
23
|
-
"action_sms.gemspec",
|
24
|
-
"lib/action_sms.rb",
|
25
|
-
"lib/action_sms/base.rb",
|
26
|
-
"lib/action_sms/connection_adapters.rb",
|
27
|
-
"lib/action_sms/connection_adapters/abstract_adapter.rb",
|
28
|
-
"lib/action_sms/exceptions.rb",
|
29
|
-
"lib/generators/action_sms/initializer/USAGE",
|
30
|
-
"lib/generators/action_sms/initializer/initializer_generator.rb",
|
31
|
-
"lib/generators/action_sms/initializer/templates/action_sms.rb",
|
32
|
-
"todo"
|
33
|
-
]
|
34
|
-
s.homepage = %q{http://github.com/dwilkie/action_sms}
|
35
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
36
|
-
s.require_paths = ["lib"]
|
37
|
-
s.rubygems_version = %q{1.3.7}
|
38
|
-
s.summary = %q{Lightweight SMS wrapper which can use any gateway}
|
15
|
+
s.rubyforge_project = "action_sms"
|
39
16
|
|
40
|
-
|
41
|
-
|
42
|
-
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
43
21
|
|
44
|
-
|
45
|
-
else
|
46
|
-
end
|
47
|
-
else
|
48
|
-
end
|
22
|
+
s.add_runtime_dependency "tropo_message"
|
49
23
|
end
|
50
24
|
|
data/lib/action_sms/base.rb
CHANGED
@@ -4,6 +4,22 @@ module ActionSms #:nodoc#
|
|
4
4
|
@@connection = nil
|
5
5
|
|
6
6
|
class << self
|
7
|
+
# Returns all adapters that respond to the given method
|
8
|
+
def adapters(adapter_method, config = {})
|
9
|
+
config = connection.configuration if config.empty? && connected?
|
10
|
+
adapters = []
|
11
|
+
methods.each do |method|
|
12
|
+
if method.to_s =~ /\_connection$/
|
13
|
+
begin
|
14
|
+
adapter = send(method, config)
|
15
|
+
rescue
|
16
|
+
end
|
17
|
+
adapters << adapter if adapter && adapter.respond_to?(adapter_method)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
adapters
|
21
|
+
end
|
22
|
+
|
7
23
|
# Returns true if a connection that's accessible to this class has already
|
8
24
|
# been opened.
|
9
25
|
def connected?
|
@@ -24,7 +40,7 @@ module ActionSms #:nodoc#
|
|
24
40
|
@@connection = spec
|
25
41
|
end
|
26
42
|
|
27
|
-
# Establishes the connection to the SMS gateway.
|
43
|
+
# Establishes the connection to the SMS gateway. Accepts a hash as input
|
28
44
|
# where the :adapter key must be specified with the name of a gateway
|
29
45
|
# adapter (in lower-case)
|
30
46
|
#
|
@@ -35,8 +51,6 @@ module ActionSms #:nodoc#
|
|
35
51
|
# :api_id => "myapiid"
|
36
52
|
# )
|
37
53
|
#
|
38
|
-
# Also accepts keys as strings (for parsing from YAML, for example).
|
39
|
-
#
|
40
54
|
# The exceptions AdapterNotSpecified, AdapterNotFound, and ArgumentError
|
41
55
|
# may be returned.
|
42
56
|
def establish_connection(config)
|
@@ -50,6 +64,102 @@ module ActionSms #:nodoc#
|
|
50
64
|
end
|
51
65
|
self.connection = self.send(adapter_method, config)
|
52
66
|
end
|
67
|
+
|
68
|
+
# Adapter Helper Methods
|
69
|
+
|
70
|
+
def authenticate(params)
|
71
|
+
adapter_method_result(:authenticate, params)
|
72
|
+
end
|
73
|
+
|
74
|
+
def authentication_key
|
75
|
+
connection.authentication_key
|
76
|
+
end
|
77
|
+
|
78
|
+
def authentication_key=(value)
|
79
|
+
connection.authentication_key = value
|
80
|
+
end
|
81
|
+
|
82
|
+
def deliver(sms, options = {})
|
83
|
+
connection.deliver(sms, options)
|
84
|
+
end
|
85
|
+
|
86
|
+
def delivery_request_successful?(delivery_request)
|
87
|
+
connection.delivery_request_successful?(delivery_request)
|
88
|
+
end
|
89
|
+
|
90
|
+
def message_id(data)
|
91
|
+
adapter_method_result(:message_id, data)
|
92
|
+
end
|
93
|
+
|
94
|
+
def message_text(params)
|
95
|
+
adapter_method_result(:message_text, params)
|
96
|
+
end
|
97
|
+
|
98
|
+
def sender(params)
|
99
|
+
adapter_method_result(:sender, params)
|
100
|
+
end
|
101
|
+
|
102
|
+
def service_url
|
103
|
+
connection.service_url
|
104
|
+
end
|
105
|
+
|
106
|
+
def status(params)
|
107
|
+
adapter_method_result(:status, params)
|
108
|
+
end
|
109
|
+
|
110
|
+
def use_ssl
|
111
|
+
connection.use_ssl
|
112
|
+
end
|
113
|
+
|
114
|
+
def use_ssl=(value)
|
115
|
+
connection.use_ssl = value
|
116
|
+
end
|
117
|
+
|
118
|
+
# Test Helper Methods
|
119
|
+
|
120
|
+
def sample_configuration(options = {})
|
121
|
+
connection.sample_configuration(options)
|
122
|
+
end
|
123
|
+
|
124
|
+
def sample_delivery_receipt(options = {})
|
125
|
+
adapter_method_result(:sample_delivery_receipt, options)
|
126
|
+
end
|
127
|
+
|
128
|
+
def sample_delivery_response(options = {})
|
129
|
+
connection.sample_delivery_response(options)
|
130
|
+
end
|
131
|
+
|
132
|
+
def sample_delivery_response_with_message_id(message_id, options = {})
|
133
|
+
adapter_method_result(
|
134
|
+
:sample_delivery_response_with_message_id, message_id, options
|
135
|
+
)
|
136
|
+
end
|
137
|
+
|
138
|
+
def sample_incoming_sms(options = {})
|
139
|
+
adapter_method_result(:sample_incoming_sms, options)
|
140
|
+
end
|
141
|
+
|
142
|
+
def sample_message_id(options = {})
|
143
|
+
adapter_method_result(:sample_message_id, options)
|
144
|
+
end
|
145
|
+
|
146
|
+
private
|
147
|
+
def adapter_method_result(adapter_method, *args)
|
148
|
+
result = connection.send(
|
149
|
+
adapter_method, *args
|
150
|
+
) if connection.respond_to?(adapter_method)
|
151
|
+
unless result
|
152
|
+
gateway_adapters = adapters(adapter_method)
|
153
|
+
i = 0
|
154
|
+
adapter = nil
|
155
|
+
begin
|
156
|
+
adapter = gateway_adapters[i]
|
157
|
+
result = adapter.send(adapter_method, *args) if adapter
|
158
|
+
i += 1
|
159
|
+
end until result || adapter.nil?
|
160
|
+
end
|
161
|
+
result
|
162
|
+
end
|
53
163
|
end
|
54
164
|
end
|
55
165
|
end
|