action_sms_gateways 0.0.6 → 0.0.7

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.
@@ -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