4info 1.2.5 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{4info}
8
- s.version = "1.2.5"
8
+ s.version = "1.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jack Danger Canty"]
12
- s.date = %q{2010-02-11}
12
+ s.date = %q{2010-02-20}
13
13
  s.description = %q{A complete Ruby API for handling SMS messages via 4info.com}
14
14
  s.email = %q{gitcommit@6brand.com}
15
15
  s.extra_rdoc_files = [
@@ -23,6 +23,7 @@ Gem::Specification.new do |s|
23
23
  "VERSION",
24
24
  "init.rb",
25
25
  "lib/4info.rb",
26
+ "lib/configuration.rb",
26
27
  "lib/contactable.rb",
27
28
  "lib/controller.rb",
28
29
  "lib/four_info.rb",
@@ -36,7 +37,6 @@ Gem::Specification.new do |s|
36
37
  "test/four_info_contactable_test.rb",
37
38
  "test/four_info_controller_test.rb",
38
39
  "test/four_info_module_test.rb",
39
- "test/sms.yml",
40
40
  "test/test_helper.rb"
41
41
  ]
42
42
  s.homepage = %q{http://github.com/JackDanger/4info}
@@ -37,6 +37,22 @@ Because it can be expensive to send TXTs accidentally, it's required that you ma
37
37
 
38
38
  Skipping this step (or adding any other value) will prevent TXTs from actually being sent.
39
39
 
40
+ You'll also want to configure your setup with your client_id and client_key. Put this in the same file as above or in a separate initializer if you wish:
41
+
42
+ FourInfo.configure do |config|
43
+ # these two are required:
44
+ # (replace them with your actual account info)
45
+ config.client_id = 12345
46
+ config.client_key = 'ABC123'
47
+
48
+ # the rest are optional:
49
+ config.short_code = 00001 # if you have a custom short code
50
+ config.proxy_address = 'my.proxy.com'
51
+ config.proxy_port = '80'
52
+ config.proxy_username = 'user'
53
+ config.proxy_password = 'password'
54
+ end
55
+
40
56
  Phone number formatting
41
57
  ---
42
58
 
@@ -46,7 +62,7 @@ Whatever is stored in the sms_phone_number_column will be subject to normalized
46
62
  user.sms_phone_number # => 2065551234
47
63
 
48
64
  If you want to preserve the format of the number exactly as the user entered it you'll want
49
- to save it in a different attribute.
65
+ to save that in a different attribute.
50
66
 
51
67
 
52
68
  Confirming Phone Number And Sending Messages
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.2.5
1
+ 1.3.0
@@ -0,0 +1,39 @@
1
+ module FourInfo
2
+ class << self
3
+ def mode
4
+ @@mode ||= :test
5
+ end
6
+
7
+ def mode=(new_mode)
8
+ @@mode = new_mode
9
+ end
10
+
11
+ def configured?
12
+ return false unless configuration
13
+ configuration.client_id && configuration.client_key
14
+ end
15
+
16
+ def configuration
17
+ @@configuration
18
+ end
19
+
20
+ def configure(&block)
21
+ @@configuration = Configuration.new(&block)
22
+ end
23
+ end
24
+
25
+ class Configuration
26
+
27
+ attr_accessor :client_id
28
+ attr_accessor :client_key
29
+ attr_accessor :short_code
30
+ attr_accessor :proxy_address
31
+ attr_accessor :proxy_port
32
+ attr_accessor :proxy_username
33
+ attr_accessor :proxy_password
34
+
35
+ def initialize
36
+ yield self
37
+ end
38
+ end
39
+ end
@@ -79,18 +79,14 @@ module FourInfo
79
79
  return true if sms_confirmed?
80
80
  return false if four_info_sms_phone_number.blank?
81
81
 
82
- response = FourInfo::Request.new.confirm(four_info_sms_phone_number)
83
- if response.success?
84
- self.four_info_sms_confirmation_code = response.confirmation_code
85
- self.four_info_sms_confirmation_attempted = Time.now.utc
86
- self.four_info_sms_confirmed_phone_number = nil
87
- save
88
- else
89
- # "Confirmation Failed: #{response['message'].inspect}"
90
- false
91
- end
82
+ # If we're using a custom short code we'll
83
+ # need to create a custom configuration message
84
+ FourInfo.configuration.short_code ?
85
+ confirm_four_info_sms_with_custom_message :
86
+ confirm_four_info_sms_with_default_message
92
87
  end
93
88
 
89
+
94
90
  # Sends an unblock request via xml to the 4info gateway.
95
91
  # If request succeeds, changes the contactable record's
96
92
  # sms_blocked_column to false.
@@ -125,5 +121,41 @@ module FourInfo
125
121
  return false if four_info_sms_confirmed_phone_number.blank?
126
122
  four_info_sms_confirmed_phone_number == four_info_sms_phone_number
127
123
  end
124
+
125
+ protected
126
+ def confirm_four_info_sms_with_custom_message
127
+ confirmation_code = FourInfo.generate_confirmation_code
128
+
129
+ # Use this class' confirmation_message method if it
130
+ # exists, otherwise use the generic message
131
+ message = (self.class.respond_to?(:confirmation_message) ?
132
+ self.class :
133
+ FourInfo).confirmation_message(confirmation_code)
134
+
135
+ response = FourInfo::Request.new.deliver_message(message, four_info_sms_phone_number)
136
+
137
+ if response.success?
138
+ update_four_info_sms_confirmation confirmation_code
139
+ else
140
+ false
141
+ end
142
+ end
143
+
144
+ def confirm_four_info_sms_with_default_message
145
+ response = FourInfo::Request.new.confirm(four_info_sms_phone_number)
146
+
147
+ if response.success?
148
+ update_four_info_sms_confirmation response.confirmation_code
149
+ else
150
+ false
151
+ end
152
+ end
153
+
154
+ def update_four_info_sms_confirmation(new_code)
155
+ self.four_info_sms_confirmation_code = new_code
156
+ self.four_info_sms_confirmation_attempted = Time.now.utc
157
+ self.four_info_sms_confirmed_phone_number = nil
158
+ save
159
+ end
128
160
  end
129
161
  end
@@ -5,13 +5,6 @@ module FourInfo
5
5
  URI.parse 'http://gateway.4info.net/msg'
6
6
  end
7
7
 
8
- def mode
9
- @@mode ||= :test
10
- end
11
- def mode=(new_mode)
12
- @@mode = new_mode
13
- end
14
-
15
8
  def log(msg)
16
9
  if defined?(Rails)
17
10
  Rails.logger.info msg
@@ -37,9 +30,19 @@ module FourInfo
37
30
  nil
38
31
  end
39
32
  end
33
+
34
+ def confirmation_message(confirmation_code)
35
+ "4INFO alert confirm. code: #{confirmation_code} Enter code on web to verify phone. Msg&amp;data rates may apply. Freq set by u. T&amp;C &amp; support at www.4info.com. Txt HELP for help"
36
+ end
37
+
38
+ def generate_confirmation_code
39
+ chars = (0..9).to_a + ('A'..'Z').to_a
40
+ (0...6).collect { chars[Kernel.rand(chars.length)] }.join
41
+ end
40
42
  end
41
43
  end
42
44
 
45
+ require File.join(File.dirname(__FILE__), 'configuration')
43
46
  require File.join(File.dirname(__FILE__), 'contactable')
44
47
  require File.join(File.dirname(__FILE__), 'controller')
45
48
  require File.join(File.dirname(__FILE__), 'request')
@@ -1,34 +1,19 @@
1
1
  module FourInfo
2
2
  class Request
3
3
 
4
- # Haml templates for XML
5
- @@templates = Dir.glob(File.expand_path(File.join(File.dirname(__FILE__), 'templates', '*.haml')))
6
-
7
- # YML config files
8
- @@test_mode_config_file = File.join(File.dirname(__FILE__), '..', 'test', 'sms.yml')
9
- @@likely_config_files = [
10
- File.join(File.dirname(__FILE__), '..', 'sms.yml'),
11
- defined?(Rails) ? File.join(Rails.root, 'config', 'sms.yml') : '',
12
- File.join('config', 'sms.yml'),
13
- 'sms.yml'
14
- ]
15
-
16
4
  attr_accessor :config
17
5
  attr_accessor :number
18
6
  attr_accessor :message
19
7
 
20
8
  def initialize
21
- config_file = :live == FourInfo.mode.to_sym ?
22
- @@likely_config_files.detect {|f| File.exist?(f) } :
23
- @@test_mode_config_file
24
-
25
- raise "Missing config File! Please add sms.yml to ./config or the 4info directory" unless config_file
26
-
27
- @config = YAML.load(File.read(config_file))['4info'].with_indifferent_access
9
+ unless FourInfo.configured?
10
+ raise "You need to configure FourInfo before using it!"
11
+ end
12
+ self.config = FourInfo.configuration
28
13
  end
29
14
 
30
15
  def deliver_message(message, number)
31
- self.number = FourInfo.internationalize(number)
16
+ self.number = FourInfo.internationalize(number)
32
17
  self.message = message
33
18
 
34
19
  xml = template(:deliver).render(self)
@@ -36,7 +21,7 @@ module FourInfo
36
21
  end
37
22
 
38
23
  def confirm(number)
39
- self.number = FourInfo.internationalize(number)
24
+ self.number = FourInfo.internationalize(number)
40
25
 
41
26
  xml = template(:confirm).render(self)
42
27
  Response.new(perform(xml))
@@ -52,7 +37,9 @@ module FourInfo
52
37
  protected
53
38
 
54
39
  def template(name)
55
- file = @@templates.detect {|t| File.basename(t).chomp('.haml').to_sym == name.to_sym }
40
+ # Haml templates for XML
41
+ templates = Dir.glob(File.expand_path(File.join(File.dirname(__FILE__), 'templates', '*.haml')))
42
+ file = templates.detect {|t| File.basename(t).chomp('.haml').to_sym == name.to_sym }
56
43
  raise ArgumentError, "Missing 4Info template: #{name}" unless file
57
44
  Haml::Engine.new(File.read(file))
58
45
  end
@@ -72,9 +59,13 @@ module FourInfo
72
59
  end
73
60
 
74
61
  def start
75
- net = config[:proxy].blank? ?
76
- Net::HTTP :
77
- Net::HTTP::Proxy(*config[:proxy].split(":"))
62
+ net = config.proxy_address ?
63
+ Net::HTTP::Proxy(
64
+ config.proxy_address,
65
+ config.proxy_port,
66
+ config.proxy_username,
67
+ config.proxy_password) :
68
+ Net::HTTP
78
69
  net.start(FourInfo.gateway.host, FourInfo.gateway.port) do |http|
79
70
  yield http
80
71
  end
@@ -3,9 +3,14 @@ module FourInfo
3
3
  def initialize(xml)
4
4
  gem 'hpricot'
5
5
  require 'hpricot'
6
+ @xml = xml
6
7
  @body = Hpricot.parse(xml)
7
8
  end
8
9
 
10
+ def inspect
11
+ @xml.to_s
12
+ end
13
+
9
14
  def [](name)
10
15
  nodes = (@body/name)
11
16
  1 == nodes.size ? nodes.first : nodes
@@ -1,5 +1,5 @@
1
1
  !!! XML
2
- %request{ :clientId => config[:client_id], :clientKey => config[:client_key], :type => "VALIDATION" }
2
+ %request{ :clientId => config.client_id, :clientKey => config.client_key, :type => "VALIDATION" }
3
3
  %validation
4
4
  %recipient
5
5
  %type= 5
@@ -1,6 +1,10 @@
1
1
  !!! XML
2
- %request{ :clientId => config[:client_id], :clientKey => config[:client_key], :type => "MESSAGE" }
2
+ %request{ :clientId => config.client_id, :clientKey => config.client_key, :type => "MESSAGE" }
3
3
  %message
4
+ - if config.short_code
5
+ %sender
6
+ %type= 6
7
+ %id= config.short_code
4
8
  %recipient
5
9
  %type= 5
6
10
  %id= number
@@ -1,5 +1,5 @@
1
1
  !!! XML
2
- %request{ :clientId => config[:client_id], :clientKey => config[:client_key], :type => "UNBLOCK" }
2
+ %request{ :clientId => config.client_id, :clientKey => config.client_key, :type => "UNBLOCK" }
3
3
  %unblock
4
4
  %recipient
5
5
  %type= 5
@@ -140,6 +140,36 @@ class FourInfoContactableTest < ActiveSupport::TestCase
140
140
  end
141
141
  end
142
142
  end
143
+ context "confirming phone number with a custom short code" do
144
+ context "with expectations" do
145
+ setup {
146
+ FourInfo.configure do |config|
147
+ config.short_code = '0005'
148
+ config.client_id = 1
149
+ config.client_key = 'ABC123'
150
+ end
151
+ message = "long message blah blah MYCODE blah"
152
+ FourInfo.expects(:generate_confirmation_code).returns('MYCODE').once
153
+ FourInfo.expects(:confirmation_message).returns(message).once
154
+ FourInfo::Request.any_instance.expects(:deliver_message).with(message, @user.four_info_sms_phone_number).once
155
+ @user.send_sms_confirmation!
156
+ }
157
+ end
158
+ context "(normal)" do
159
+ setup {
160
+ FourInfo.configure do |config|
161
+ config.short_code = '0005'
162
+ config.client_id = 1
163
+ config.client_key = 'ABC123'
164
+ end
165
+ FourInfo::Request.any_instance.stubs(:perform).returns(SendMsgSuccess)
166
+ @worked = @user.send_sms_confirmation!
167
+ }
168
+ should "work" do
169
+ assert @worked
170
+ end
171
+ end
172
+ end
143
173
  context "confirming phone number when the confirmation fails for some reason" do
144
174
  setup {
145
175
  FourInfo::Request.any_instance.stubs(:perform).returns(ValidationError)
@@ -36,4 +36,21 @@ class FourInfoModuleTest < ActiveSupport::TestCase
36
36
  end
37
37
  end
38
38
  end
39
+
40
+ context "generating codes" do
41
+ setup { @code = FourInfo.generate_confirmation_code }
42
+ should "be 6 digits" do
43
+ assert_equal 6, @code.length
44
+ end
45
+ end
46
+
47
+ context "confirmation message" do
48
+ setup {
49
+ @code = 'ABC123'
50
+ @message = FourInfo.confirmation_message(@code)
51
+ }
52
+ should "include code" do
53
+ assert @message.include?(@code)
54
+ end
55
+ end
39
56
  end
@@ -8,6 +8,12 @@ require 'active_support/test_case'
8
8
  require 'shoulda'
9
9
  require File.join(File.dirname(__FILE__), "..", 'lib', 'four_info')
10
10
 
11
+ # default test configuration
12
+ FourInfo.configure do |config|
13
+ config.client_id = '1'
14
+ config.client_key = 'ABCDEF'
15
+ end
16
+
11
17
  FourInfo.mode = :test
12
18
  config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
13
19
  ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: 4info
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.5
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jack Danger Canty
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-11 00:00:00 -08:00
12
+ date: 2010-02-20 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -68,6 +68,7 @@ files:
68
68
  - VERSION
69
69
  - init.rb
70
70
  - lib/4info.rb
71
+ - lib/configuration.rb
71
72
  - lib/contactable.rb
72
73
  - lib/controller.rb
73
74
  - lib/four_info.rb
@@ -81,7 +82,6 @@ files:
81
82
  - test/four_info_contactable_test.rb
82
83
  - test/four_info_controller_test.rb
83
84
  - test/four_info_module_test.rb
84
- - test/sms.yml
85
85
  - test/test_helper.rb
86
86
  has_rdoc: true
87
87
  homepage: http://github.com/JackDanger/4info
@@ -1,6 +0,0 @@
1
- 4info:
2
- client_id: 1
3
- client_key: ABCDEFG
4
- proxy: myhost.com:8080
5
- # or:
6
- # proxy: myhost.com:8080:username:password