action_sms_gateways 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,22 +1,157 @@
1
1
  # action_sms_gateways
2
+
2
3
  A collection of SMS Gateway Adapters for [action_sms](http://github.com/dwilkie/action_sms)
3
4
 
4
5
  ## Current SMS Adapters
6
+
5
7
  * [SMSGlobal](http://www.smsglobal.com)
8
+ * [Tropo](http://www.tropo.com)
9
+
10
+ ## Configuration
11
+
12
+ * [SMSGlobal](http://github.com/dwilkie/action_sms_gateways/wiki/SMSGlobal)
13
+ * [Tropo](http://github.com/dwilkie/action_sms_gateways/wiki/Tropo)
14
+
15
+ ## Usage
16
+
17
+ ### Send an SMS and check if it was successful
18
+
19
+ class SMS
20
+ def recipient
21
+ "617198378843"
22
+ end
23
+
24
+ def body
25
+ "Hello world"
26
+ end
27
+
28
+ def from
29
+ end
30
+ end
31
+
32
+ sms_gateway = ActionSms::Base.connection
33
+ response = sms_gateway.deliver(SMS.new)
34
+ success = sms_gateway.delivery_request_successful?(response)
35
+
36
+ ### Receive an SMS
37
+
38
+ # Assume 'params' has the data posted back to your server
39
+
40
+ sms_gateway = ActionSms::Base.connection
41
+
42
+ # get sender
43
+ sender = sms_gateway.sender(params)
44
+
45
+ # get message text
46
+ message_text = sms_gateway.message_text(params)
47
+
48
+ ### Delivery receipts
49
+
50
+ # Assume 'receipt' has the data posted back to your server as the delivery receipt
51
+
52
+ sms_gateway = ActionSms::Base.connection
53
+
54
+ # get status
55
+ status = sms_gateway.status(receipt)
56
+
57
+ # get message id
58
+ message_id = sms_gateway.message_id(receipt)
59
+
60
+ ### Authentication
61
+
62
+ ActionSms::Base.establish_connection(
63
+ :authentication_key => "my secret",
64
+ :use_ssl => true
65
+ )
66
+
67
+ 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:
6
68
 
7
- ## Creating your own SMS Gateway Adapter
8
- Take a look at the source under `lib/action_sms_gateways/connection_adapters/sms_global.rb` and use it as a template for your own adapter. Then why not share it for all to use...
69
+ # Assume 'params' has the data posted back to your server
9
70
 
10
- ## Contributing
11
- * Fork the project.
12
- * Make your SMS Gateway Adapter.
13
- * Add tests for it. This is important so I don’t break it in a future version unintentionally.
14
- * Commit, do not mess with rakefile, version, or history.
15
- * Send me a pull request.
71
+ sms_gateway = ActionSms::Base.connection
72
+
73
+ # Removes the authentication key from 'params' and returns true or false
74
+ sms_gateway.authenticate(params)
75
+
76
+ ### Service url
77
+
78
+ # gets the gateway's api url
79
+ # ActionSms::Base.connection.service_url
80
+
81
+ ## Testing
82
+
83
+ When you set: `:environment => "test"` in your configuration, you get some additional test helpers.
84
+
85
+ ActionSms::Base.establish_connection(
86
+ :environment => "test"
87
+ )
88
+
89
+ sms_gateway = ActionSms::Base.connection
90
+
91
+ # get sample incoming SMS params
92
+ sms_gateway.sample_incoming_sms
93
+
94
+ # get customized sample incoming SMS
95
+ sms_gateway.sample_incoming_sms(
96
+ :message => "hello",
97
+ :to => "6128392323",
98
+ :from => "61289339432",
99
+ :date => Time.now,
100
+ :authentic => false # see configuration
101
+ )
102
+
103
+ # get sample delivery response
104
+ sms_gateway.sample_delivery_response
105
+
106
+ # get sample delivery response (failed)
107
+ sms_gateway.sample_delivery_response(:failed => true)
108
+
109
+ # get sample message id
110
+ sms_gateway.sample_message_id
111
+
112
+ # get sample delivery receipt
113
+ sms_gateway.sample_delivery_receipt
114
+
115
+ # get customized sample delivery receipt
116
+ sms_gateway.sample_delivery_receipt(
117
+ :message_id => "12345",
118
+ :status => "delivered",
119
+ :error => "some error",
120
+ :date => Time.now
121
+ )
122
+
123
+ ## Creating your own adapter
124
+
125
+ To create your own adapter all you need to do is open up the ActionSms::Base class
126
+ 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:
127
+
128
+ # clickatell.rb
129
+ require 'action_sms/connection_adapters/abstract_adapter'
130
+
131
+ module ActionSms
132
+ class Base
133
+ def self.clickatell_connection(config)
134
+ ConnectionAdapters::ClickatellAdapter.new(config)
135
+ end
136
+ end
137
+ end
138
+
139
+ module ConnectionAdapters
140
+ class ClickatellAdapter < AbstractAdapter
141
+ # define your adapter here ...
142
+ def initialize(config)
143
+ end
144
+ end
145
+ end
146
+
147
+ Take a look at the [source](http://github.com/dwilkie/action_sms_gateways/tree/master/lib/action_sms_gateways/connection_adapters/) for more details
16
148
 
17
149
  ## Installation
150
+
18
151
  gem install action_sms_gateways
152
+
19
153
  ### Rails
154
+
20
155
  Place the following in your Gemfile:
21
156
 
22
157
  gem action_sms_gateways
data/Rakefile CHANGED
@@ -22,6 +22,7 @@ begin
22
22
  gemspec.email = "dwilkie@gmail.com"
23
23
  gemspec.homepage = "http://github.com/dwilkie/action_sms_gateways"
24
24
  gemspec.authors = ["David Wilkie"]
25
+ gemspec.add_runtime_dependency "tropo_message", ">=0.0.4"
25
26
  end
26
27
  rescue LoadError
27
28
  puts "Jeweler not available. Install it with: gem install jeweler"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.6
1
+ 0.0.7
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{action_sms_gateways}
8
- s.version = "0.0.6"
8
+ s.version = "0.0.7"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["David Wilkie"]
12
- s.date = %q{2010-10-03}
12
+ s.date = %q{2010-10-14}
13
13
  s.email = %q{dwilkie@gmail.com}
14
14
  s.extra_rdoc_files = [
15
15
  "README.markdown"
@@ -24,6 +24,9 @@ Gem::Specification.new do |s|
24
24
  "lib/action_sms_gateways.rb",
25
25
  "lib/action_sms_gateways/connection_adapters.rb",
26
26
  "lib/action_sms_gateways/connection_adapters/sms_global.rb",
27
+ "lib/action_sms_gateways/connection_adapters/test_helpers/sms_global.rb",
28
+ "lib/action_sms_gateways/connection_adapters/test_helpers/tropo.rb",
29
+ "lib/action_sms_gateways/connection_adapters/tropo.rb",
27
30
  "todo"
28
31
  ]
29
32
  s.homepage = %q{http://github.com/dwilkie/action_sms_gateways}
@@ -37,9 +40,12 @@ Gem::Specification.new do |s|
37
40
  s.specification_version = 3
38
41
 
39
42
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
43
+ s.add_runtime_dependency(%q<tropo_message>, [">= 0.0.4"])
40
44
  else
45
+ s.add_dependency(%q<tropo_message>, [">= 0.0.4"])
41
46
  end
42
47
  else
48
+ s.add_dependency(%q<tropo_message>, [">= 0.0.4"])
43
49
  end
44
50
  end
45
51
 
@@ -1,10 +1,18 @@
1
1
  require 'action_sms/connection_adapters/abstract_adapter'
2
- require 'uri'
3
2
 
4
3
  module ActionSms
5
4
  class Base
6
5
  def self.sms_global_connection(config) #:nodoc:
7
- return ConnectionAdapters::SMSGlobalAdapter.new(logger, config)
6
+ if config[:environment].to_s == "test"
7
+ test_helper = File.expand_path(File.dirname(__FILE__) + '/test_helpers/sms_global')
8
+ if File.exists?("#{test_helper}.rb")
9
+ require test_helper
10
+ ConnectionAdapters::SMSGlobalAdapter.class_eval do
11
+ include TestHelpers::SMSGlobal
12
+ end
13
+ end
14
+ end
15
+ ConnectionAdapters::SMSGlobalAdapter.new(config)
8
16
  end
9
17
  end
10
18
 
@@ -13,14 +21,18 @@ module ActionSms
13
21
  # class. You can use this interface directly by borrowing the gateway
14
22
  # connection from the Base with Base.connection.
15
23
  class SMSGlobalAdapter < AbstractAdapter
24
+ require 'uri'
25
+
16
26
  SERVICE_HOST = "http://smsglobal.com.au"
17
27
  SERVICE_PATH = "http-api.php"
18
28
 
19
- def initialize(logger = nil, config = {}) #:nodoc:
20
- super(logger)
29
+ attr_reader :service_url
30
+
31
+ def initialize(config = {}) #:nodoc:
21
32
  @config = config.dup
22
- @service_url = URI.join(SERVICE_HOST, SERVICE_PATH)
23
- @service_url.scheme = config[:use_ssl] ? "https" : "http"
33
+ service_uri = URI.join(SERVICE_HOST, SERVICE_PATH)
34
+ service_uri.scheme = config[:use_ssl] ? "https" : "http"
35
+ @service_url = service_uri.to_s
24
36
  end
25
37
 
26
38
  def message_id(data)
@@ -72,7 +84,7 @@ module ActionSms
72
84
  params.merge!(
73
85
  :userfield => userfield
74
86
  ) if userfield
75
- send_http_request(@service_url.to_s, params)
87
+ send_http_request(@service_url, params)
76
88
  end
77
89
  end
78
90
  end
@@ -0,0 +1,40 @@
1
+ module TestHelpers
2
+ module SMSGlobal
3
+ def sample_incoming_sms(options = {})
4
+ options[:message] ||= "Endia kasdf ofeao"
5
+ options[:to] ||= "61447100308"
6
+ options[:from] ||= "61447100399"
7
+ options[:date] ||= "2010-05-13 23:59:11"
8
+ params = {
9
+ "to" => options[:to],
10
+ "from" => options[:from],
11
+ "msg"=> options[:message],
12
+ "date" => options[:date]
13
+ }
14
+ params.merge!("userfield" => @config[:authentication_key]) unless options[:authentic] == false
15
+ params
16
+ end
17
+
18
+ def sample_delivery_response(options = {})
19
+ options[:failed] ? "ERROR: No action requested" : "OK: 0; Sent queued message ID: 86b1a945370734f4 SMSGlobalMsgID:6942744494999745"
20
+ end
21
+
22
+ def sample_message_id
23
+ "SMSGlobalMsgID:6942744494999745"
24
+ end
25
+
26
+ def sample_delivery_receipt(options = {})
27
+ options[:message_id] ||= "6942744494999745"
28
+ options[:status] ||= "DELIVRD"
29
+ options[:error] ||= "000"
30
+ options[:date] ||= "1005132312"
31
+ {
32
+ "msgid"=> options[:message_id],
33
+ "dlrstatus"=> options[:status],
34
+ "dlr_err"=> options[:error],
35
+ "donedate"=> options[:date]
36
+ }
37
+ end
38
+ end
39
+ end
40
+
@@ -0,0 +1,68 @@
1
+ module TestHelpers
2
+ module Tropo
3
+ def sample_incoming_sms(options = {})
4
+ options[:message] ||= "Endia kasdf ofeao"
5
+ options[:to] ||= "61447100308"
6
+ options[:from] ||= "61447100399"
7
+ options[:date] ||= "Mon Oct 11 09:21:38 UTC 2010"
8
+ params = {
9
+ "session" => {
10
+ "id"=>"12349516546e59746d6a89a990466789",
11
+ "account_id"=>"12345",
12
+ "timestamp"=> options[:date],
13
+ "user_type"=>"HUMAN",
14
+ "initial_text"=> options[:message],
15
+ "call_id"=>"123e71195545ad204bdd99f2070a7d86",
16
+ "to"=>{
17
+ "id"=> options[:to],
18
+ "name"=>"unknown",
19
+ "channel"=>"TEXT",
20
+ "network"=>"SMS"
21
+ },
22
+ "from" => {
23
+ "id"=> options[:from],
24
+ "name"=>"unknown",
25
+ "channel"=>"TEXT",
26
+ "network"=>"SMS"
27
+ },
28
+ "headers" => {
29
+ "_max-_forwards"=>"70",
30
+ "_content-_length"=>"124",
31
+ "_contact"=>"<sip:11.8.93.101:5066;transport=udp>",
32
+ "_to"=>"<sip:1231454582@10.6.69.203:5061;to=#{options[:to]}>",
33
+ "_c_seq"=>"1 INVITE",
34
+ "_via"=>"SIP/2.0/UDP 11.8.93.101:5066;branch=h0hG4bKk5sy1e",
35
+ "_call-_i_d"=>"ieeg18",
36
+ "_content-_type"=>"application/sdp",
37
+
38
+ "_from"=>"<sip:15EB6BAB-99DF-44C2-871DFBA75C319776@11.8.93.201;channel=private;user=#{options[:to]};msg=#{options[:message]};network=SMS;step=1>;tag=zm13kt"
39
+ }
40
+ }
41
+ }
42
+ params.merge!("authentication_key" => @config[:authentication_key]) unless options[:authentic] == false
43
+ params
44
+ end
45
+
46
+ def sample_delivery_response(options = {})
47
+ options[:failure] ? "<session><success>false</success><token></token><reason>FAILED TO ROUTE TOKEN</reason></session>" : "<session><success>true</success></session>"
48
+ end
49
+
50
+ def sample_message_id
51
+ "123e71195545ad204bdd99f2070a7d86"
52
+ end
53
+
54
+ # This is here simply so the current tests pass
55
+ # Tropo does not *yet* send delivery receipts
56
+ def sample_delivery_receipt(options = {})
57
+ options[:message_id] ||= "123e71195545ad204bdd99f2070a7d86"
58
+ options[:status] ||= "delivered"
59
+ options[:date] ||= "Mon Oct 11 09:21:38 UTC 2010"
60
+ {
61
+ "message_id"=> options[:message_id],
62
+ "status"=> options[:status],
63
+ "delivered_at"=> options[:date]
64
+ }
65
+ end
66
+ end
67
+ end
68
+
@@ -0,0 +1,82 @@
1
+ require 'action_sms/connection_adapters/abstract_adapter'
2
+
3
+ module ActionSms
4
+ class Base
5
+ def self.tropo_connection(config) #:nodoc:
6
+ if config[:environment].to_s == "test"
7
+ test_helper = File.expand_path(File.dirname(__FILE__) + '/test_helpers/tropo')
8
+ if File.exists?("#{test_helper}.rb")
9
+ require test_helper
10
+ ConnectionAdapters::TropoAdapter.class_eval do
11
+ include TestHelpers::Tropo
12
+ end
13
+ end
14
+ end
15
+ ConnectionAdapters::TropoAdapter.new(config)
16
+ end
17
+ end
18
+
19
+ module ConnectionAdapters
20
+ # All the concrete gateway adapters follow the interface laid down in this
21
+ # class. You can use this interface directly by borrowing the gateway
22
+ # connection from the Base with Base.connection.
23
+ class TropoAdapter < AbstractAdapter
24
+ require 'uri'
25
+ require 'tropo_message'
26
+
27
+ attr_reader :service_url
28
+
29
+ SERVICE_HOST = "http://api.tropo.com/1.0"
30
+ SERVICE_PATH = "sessions"
31
+
32
+ def initialize(config = {}) #:nodoc:
33
+ @config = config.dup
34
+ service_uri = URI.join(SERVICE_HOST, SERVICE_PATH)
35
+ service_uri.scheme = config[:use_ssl] ? "https" : "http"
36
+ @service_url = service_uri.to_s
37
+ end
38
+
39
+ # message_id and status are for text message delivery receipts only
40
+ # Tropo does not *yet* send text message delivery receipts, so these
41
+ # two methods are here for testing purposes
42
+ def message_id(data)
43
+ data.is_a?(Hash) ? data["message_id"] : data
44
+ end
45
+
46
+ def status(delivery_receipt)
47
+ delivery_receipt["status"]
48
+ end
49
+
50
+ def delivery_request_successful?(gateway_response)
51
+ gateway_response =~ /\<success\>true\<\/success\>/
52
+ end
53
+
54
+ def message_text(params)
55
+ session(params)["initial_text"]
56
+ end
57
+
58
+ def sender(params)
59
+ session(params)["from"]["id"]
60
+ end
61
+
62
+ def authenticate(params)
63
+ params.delete("authentication_key") == @config[:authentication_key]
64
+ end
65
+
66
+ def deliver(sms)
67
+ tropo_message = Tropo::Message.new
68
+ tropo_message.to = sms.recipient
69
+ tropo_message.text = sms.body || ""
70
+ tropo_message.from = sms.from if sms.respond_to?(:from)
71
+ tropo_message.token = @config[:outgoing_token]
72
+ send_http_request(@service_url, tropo_message.request_xml)
73
+ end
74
+
75
+ private
76
+ def session(params)
77
+ params["session"]
78
+ end
79
+ end
80
+ end
81
+ end
82
+
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 6
9
- version: 0.0.6
8
+ - 7
9
+ version: 0.0.7
10
10
  platform: ruby
11
11
  authors:
12
12
  - David Wilkie
@@ -14,10 +14,24 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-10-03 00:00:00 +07:00
17
+ date: 2010-10-14 00:00:00 +07:00
18
18
  default_executable:
19
- dependencies: []
20
-
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: tropo_message
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ - 0
31
+ - 4
32
+ version: 0.0.4
33
+ type: :runtime
34
+ version_requirements: *id001
21
35
  description:
22
36
  email: dwilkie@gmail.com
23
37
  executables: []
@@ -36,6 +50,9 @@ files:
36
50
  - lib/action_sms_gateways.rb
37
51
  - lib/action_sms_gateways/connection_adapters.rb
38
52
  - lib/action_sms_gateways/connection_adapters/sms_global.rb
53
+ - lib/action_sms_gateways/connection_adapters/test_helpers/sms_global.rb
54
+ - lib/action_sms_gateways/connection_adapters/test_helpers/tropo.rb
55
+ - lib/action_sms_gateways/connection_adapters/tropo.rb
39
56
  - todo
40
57
  has_rdoc: true
41
58
  homepage: http://github.com/dwilkie/action_sms_gateways