4info 1.1.1 → 1.2.0

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.
data/4info.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{4info}
8
- s.version = "1.1.1"
8
+ s.version = "1.2.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-10}
12
+ s.date = %q{2010-02-11}
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 = [
data/README.markdown CHANGED
@@ -3,12 +3,12 @@
3
3
 
4
4
  Connect to the 4info SMS gateway
5
5
 
6
- If you're using 4info.com as your SMS gateway this gem will give you a painless API.
6
+ If you're using 4info.com as your SMS gateway this gem will give you a painless API for both sending and receiving messages.
7
7
 
8
- USAGE
8
+ Setting Up Your Model
9
9
  =====
10
10
 
11
- Include FourInfo::Contactable into your User class or whatever you're using to represent an entity with a phone number.
11
+ Include FourInfo::Contactable into your User class or whatever you're using to represent an entity with a phone number.
12
12
 
13
13
  class User < ActiveRecord::Base
14
14
  include FourInfo::Contactable
@@ -25,25 +25,39 @@ You can also specify which attributes you'd like to use instead of the defaults
25
25
  sms_confirmation_attempted_column :when_was_the_sms_confirmation_attempted
26
26
  sms_confirmed_phone_number_column :the_mobile_number_thats_been_confirmed
27
27
 
28
- # Defaults to the name on the left (minus the word '_column')
28
+ # Defaults to the name on the left (minus the '_column' at the end)
29
29
  end
30
30
 
31
+
32
+ Confirming Phone Number And Sending Messages
33
+ ====
34
+
31
35
  You can manage the user's SMS state like so:
32
36
 
33
37
  @user = User.create(:sms_phone_number => '5552223333')
34
- @user.confirm_sms!
35
- # then ask the user for the confirmation code and
36
- # compare it to @user.sms_confirmation_code
37
- # if they're the same, call
38
- @user.sms_confirmed!
39
- @user.update_attributes(:sms_confirmed_phone_number => @user.sms_phone_number)
38
+ @user.send_sms_confirmation!
39
+
40
+ then ask the user for the confirmation code off their phone and pass it in to sms_confirm_with:
41
+
42
+ @user.sms_confirm_with(user_provided_code)
43
+
44
+ If the code is right then the user's current phone number will be automatically marked as confirmed. You can check this at any time with:
45
+
46
+ @user.sms_confirmed? # => true
40
47
  @user.send_sms!("Hi! This is a text message.")
41
- # Then maybe the user will reply with 'BLOCK' by accident
48
+
49
+ Then maybe the user will reply with 'BLOCK' by accident and @user.sms_blocked? will be true.
50
+ You can fix this by calling:
51
+
42
52
  @user.unblock_sms!
43
53
 
44
54
 
45
- There's also a controller module that allows you to super-easily create a controller
46
- that receives data from 4info.com
55
+ Receiving Messages From 4info.com
56
+ ====
57
+
58
+ You can also receive data posted to you from 4info.com. This is how you'll receive messages and notices that users have been blocked.
59
+ All you need is to create a bare controller and include FourInfo::Controller into it. Then specify which Ruby class you're using as a contactable user model (likely User)
60
+
47
61
 
48
62
  class SMSController < ApplicationController
49
63
  include FourInfo::Controller
@@ -51,10 +65,24 @@ that receives data from 4info.com
51
65
  sms_contactable User # or whichever class you included FourInfo::Contactable into
52
66
  end
53
67
 
54
- Now anything posted to the index (or create, if you've hooked this up RESTfully) action
55
- will automatically work. If a user sends 4info.com a message their user record on your site
56
- will (if User has a 'receive_sms' method defined) receive the message directly.
68
+ And hook this up in your routes.rb file like so:
69
+
70
+ ActionController::Routing::Routes.draw do |map|
71
+ map.route '4info', :controller => 'four_info', :action => :index
72
+ end
73
+
74
+ Now just tell 4info.com to POST messages and block notices to you at:
75
+
76
+ http://myrubyapp.com/4info
77
+
78
+ Now if your users reply to an SMS with 'STOP' your database will be updated to reflect this.
79
+
80
+ Incoming messages from a user will automatically be sent to that user's record:
81
+
82
+ # If "I love you!" is sent to you from a user with the phone
83
+ # number "555-111-9999" then the following will be executed:
84
+ User.find_by_sms_phone_number('5551119999').receive_sms("I love you!")
57
85
 
58
86
  That's it. Patches welcome, forks celebrated.
59
87
 
60
- Copyright (c) 2010 Jack Danger Canty (http://jåck.com/), released under the MIT license
88
+ Copyright (c) 2010 [Jack Danger Canty](http://jåck.com/), released under the MIT license
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.1
1
+ 1.2.0
data/lib/contactable.rb CHANGED
@@ -13,7 +13,7 @@ module FourInfo
13
13
  require 'net/http'
14
14
 
15
15
  Attributes.each do |attribute|
16
- # add a method for setting or retrieving
16
+ # add a method in the class for setting or retrieving
17
17
  # which column should be used for which attribute
18
18
  #
19
19
  # :sms_phone_number_column defaults to :sms_phone_number, etc.
@@ -24,34 +24,34 @@ module FourInfo
24
24
  @#{attribute}_column
25
25
  end
26
26
  "
27
- # provide a helper method to access the right value
28
- # no matter which column it's stored in
27
+ # provide helper methods to access the right value
28
+ # no matter which column it's stored in.
29
29
  #
30
30
  # e.g.: @user.four_info_sms_confirmation_code
31
31
  # == @user.send(User.sms_confirmation_code_column)
32
32
  model.class_eval "
33
- def four_info_#{attribute}(value = nil)
34
- value ?
35
- send(self.class.#{attribute}_column.to_s+'=', value) :
36
- send(self.class.#{attribute}_column)
33
+ def four_info_#{attribute}
34
+ send self.class.#{attribute}_column
37
35
  end
38
36
  alias_method :four_info_#{attribute}?, :four_info_#{attribute}
39
- alias_method :four_info_#{attribute}=, :four_info_#{attribute}
37
+ def four_info_#{attribute}=(value)
38
+ send self.class.#{attribute}_column.to_s+'=', value
39
+ end
40
40
  "
41
41
  end
42
42
  end
43
43
 
44
- def current_phone_number_confirmed_for_sms?
45
- return false if four_info_sms_confirmed_phone_number.blank?
46
- four_info_sms_confirmed_phone_number == four_info_sms_phone_number
47
- end
48
-
44
+ # Sends one or more TXT messages to the contactable record's
45
+ # mobile number (if the number has been confirmed).
46
+ # Any messages longer than 160 characters will need to be accompanied
47
+ # by a second argument <tt>true</tt> to clarify that sending
48
+ # multiple messages is intentional.
49
49
  def send_sms!(msg, allow_multiple = false)
50
50
  if msg.to_s.size > 160 && !allow_multiple
51
51
  raise ArgumentError, "SMS Message is too long. Either specify that you want multiple messages or shorten the string."
52
52
  end
53
53
  return false if msg.to_s.strip.blank? || four_info_sms_blocked?
54
- return false unless current_phone_number_confirmed_for_sms?
54
+ return false unless sms_confirmed?
55
55
 
56
56
  # split into pieces that fit as individual messages.
57
57
  msg.to_s.scan(/.{1,160}/m).map do |text|
@@ -59,15 +59,18 @@ module FourInfo
59
59
  end
60
60
  end
61
61
 
62
- def confirm_sms!
62
+ # Sends an SMS validation request via xml to the 4info gateway.
63
+ # If request succeeds the 4info-generated confirmation code is saved
64
+ # in the contactable record.
65
+ def send_sms_confirmation!
63
66
  return false if four_info_sms_blocked?
64
- return true if current_phone_number_confirmed_for_sms?
67
+ return true if sms_confirmed?
65
68
  return false if four_info_sms_phone_number.blank?
66
69
 
67
70
  response = FourInfo::Request.new.confirm(four_info_sms_phone_number)
68
71
  if response.success?
69
- self.four_info_sms_confirmation_code response.confirmation_code
70
- self.four_info_sms_confirmation_attempted Time.now
72
+ self.four_info_sms_confirmation_code = response.confirmation_code
73
+ self.four_info_sms_confirmation_attempted = Time.now
71
74
  save
72
75
  else
73
76
  # "Confirmation Failed: #{response['message'].inspect}"
@@ -75,21 +78,37 @@ module FourInfo
75
78
  end
76
79
  end
77
80
 
78
- def sms_confirmed!
79
- # save the phone number into the 'confirmed phone number' attribute
80
- four_info_sms_confirmed_phone_number four_info_sms_phone_number
81
- end
82
-
81
+ # Sends an unblock request via xml to the 4info gateway.
82
+ # If request succeeds, changes the contactable record's
83
+ # sms_blocked_column to false.
83
84
  def unblock_sms!
84
85
  return false unless four_info_sms_blocked?
85
86
 
86
87
  response = FourInfo::Request.new.unblock(four_info_sms_phone_number)
87
88
  if response.success?
88
- four_info_sms_blocked 'false'
89
+ self.four_info_sms_blocked = 'false'
89
90
  save!
90
91
  else
91
92
  false
92
93
  end
93
94
  end
95
+
96
+ # Compares user-provided code with the stored confirmation
97
+ # code. If they match then the current phone number is set
98
+ # as confirmed by the user.
99
+ def sms_confirm_with(code)
100
+ if four_info_sms_confirmation_code == code
101
+ # save the phone number into the 'confirmed phone number' attribute
102
+ self.four_info_sms_confirmed_phone_number = four_info_sms_phone_number
103
+ save
104
+ end
105
+ end
106
+
107
+ # Returns true if the current phone number has been confirmed by
108
+ # the user for recieving TXT messages.
109
+ def sms_confirmed?
110
+ return false if four_info_sms_confirmed_phone_number.blank?
111
+ four_info_sms_confirmed_phone_number == four_info_sms_phone_number
112
+ end
94
113
  end
95
114
  end
data/lib/controller.rb CHANGED
@@ -47,7 +47,7 @@ module FourInfo
47
47
  end
48
48
 
49
49
  def find_contactable(id)
50
- [id, id.sub(/^\+/,''), id.sub(/^\+1/,'')].each do |possible_phone_number|
50
+ [id, id.sub(/^\+/,''), id.sub(/^\+1/,'')].uniq.compact.each do |possible_phone_number|
51
51
  found = @@contactable_class.find(
52
52
  :first,
53
53
  :conditions =>
@@ -60,7 +60,7 @@ class FourInfoContactableTest < ActiveSupport::TestCase
60
60
  context "when phone number is blank" do
61
61
  setup { @user.sms_phone_number = nil}
62
62
  context "confirming phone number" do
63
- setup { @user.confirm_sms! }
63
+ setup { @user.send_sms_confirmation! }
64
64
  should_not_change "any attributes" do
65
65
  @user.attributes.inspect
66
66
  end
@@ -82,7 +82,7 @@ class FourInfoContactableTest < ActiveSupport::TestCase
82
82
  context "confirming phone number" do
83
83
  setup {
84
84
  FourInfo::Request.any_instance.stubs(:perform).returns(ValidationSuccess)
85
- @worked = @user.confirm_sms!
85
+ @worked = @user.send_sms_confirmation!
86
86
  }
87
87
  should "work" do assert @worked end
88
88
  should "save confirmation number in proper attribute" do
@@ -95,15 +95,25 @@ class FourInfoContactableTest < ActiveSupport::TestCase
95
95
  @user.four_info_sms_confirmation_code
96
96
  end
97
97
  should "not have number confirmed yet" do
98
- assert !@user.current_phone_number_confirmed_for_sms?
98
+ assert !@user.sms_confirmed?
99
99
  end
100
- context "calling sms_confirmed!" do
101
- setup { @user.sms_confirmed! }
100
+ context "calling sms_confirm_with(right_code)" do
101
+ setup { @user.sms_confirm_with(@user.four_info_sms_confirmation_code) }
102
102
  should "save the phone number into the confirmed attribute" do
103
103
  assert_equal @user.four_info_sms_confirmed_phone_number,
104
104
  @user.four_info_sms_phone_number
105
105
  end
106
- should_change "confirmed phone number attribuet" do
106
+ should_change "confirmed phone number attribute" do
107
+ @user.four_info_sms_confirmed_phone_number
108
+ end
109
+ end
110
+ context "calling sms_confirm_with(wrong_code)" do
111
+ setup { @user.sms_confirm_with('wrong_code') }
112
+ should "not save the phone number into the confirmed attribute" do
113
+ assert_not_equal @user.four_info_sms_confirmed_phone_number,
114
+ @user.four_info_sms_phone_number
115
+ end
116
+ should_not_change "confirmed phone number attribute" do
107
117
  @user.four_info_sms_confirmed_phone_number
108
118
  end
109
119
  end
@@ -111,7 +121,7 @@ class FourInfoContactableTest < ActiveSupport::TestCase
111
121
  context "confirming phone number when the confirmation fails for some reason" do
112
122
  setup {
113
123
  FourInfo::Request.any_instance.stubs(:perform).returns(ValidationError)
114
- @worked = @user.confirm_sms!
124
+ @worked = @user.send_sms_confirmation!
115
125
  }
116
126
  should "not work" do assert !@worked end
117
127
  should "not save confirmation number" do
@@ -149,7 +159,7 @@ class FourInfoContactableTest < ActiveSupport::TestCase
149
159
  context "when the number is confirmed" do
150
160
  setup {
151
161
  FourInfo::Request.any_instance.stubs(:perform).returns(SendMsgSuccess)
152
- @user.stubs(:current_phone_number_confirmed_for_sms?).returns(true)
162
+ @user.stubs(:sms_confirmed?).returns(true)
153
163
  }
154
164
  context "sending a message" do
155
165
  setup { @result = @user.send_sms!('message') }
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.1.1
4
+ version: 1.2.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-10 00:00:00 -08:00
12
+ date: 2010-02-11 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency