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 CHANGED
@@ -1,3 +1,3 @@
1
- *~
2
- rerun.txt
3
-
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in action_sms.gemspec
4
+ gemspec
data/README.markdown CHANGED
@@ -1,26 +1,159 @@
1
1
  # action_sms
2
2
 
3
- action_sms allows you to use existing or custom SMS Gateway Adapters and switch between them effortlessly without modifying your application or test code. By keeping SMS Gateway configuration out of your code you can be more adaptable to change.
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 => '[username]',
13
- :password => '[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
- Now from your application or test code you can call methods on the adapter by calling:
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::Base.connection
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
- ## Adapters
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
- See [action_sms_gateways](http://github.com/dwilkie/action_sms_gateways) for existing adapters and information on how to create your own.
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 under config/initializers with the `establish_connection` code described above.
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 'rake'
2
- require 'rake/testtask'
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 = %q{action_sms}
8
- s.version = "0.0.3"
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.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
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
- if s.respond_to? :specification_version then
41
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
42
- s.specification_version = 3
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
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
45
- else
46
- end
47
- else
48
- end
22
+ s.add_runtime_dependency "tropo_message"
49
23
  end
50
24
 
@@ -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. Accepts a hash as input
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
@@ -1,2 +1,5 @@
1
- require 'action_sms/connection_adapters/abstract_adapter'
1
+ # Load each available adapter
2
+ Dir["#{File.dirname(__FILE__)}/connection_adapters/*.rb"].sort.each do |path|
3
+ require "action_sms/connection_adapters/#{File.basename(path)}"
4
+ end
2
5