4info 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/4info.gemspec +2 -2
- data/README.markdown +45 -17
- data/VERSION +1 -1
- data/lib/contactable.rb +43 -24
- data/lib/controller.rb +1 -1
- data/test/four_info_contactable_test.rb +18 -8
- metadata +2 -2
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.
|
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-
|
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
|
-
|
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
|
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.
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
@user.
|
39
|
-
|
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
|
-
|
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
|
-
|
46
|
-
|
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
|
-
|
55
|
-
|
56
|
-
|
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
|
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.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
|
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}
|
34
|
-
|
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
|
-
|
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
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
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
|
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
|
-
|
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
|
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
|
-
|
79
|
-
|
80
|
-
|
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.
|
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.
|
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.
|
98
|
+
assert !@user.sms_confirmed?
|
99
99
|
end
|
100
|
-
context "calling
|
101
|
-
setup { @user.
|
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
|
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.
|
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(:
|
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.
|
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-
|
12
|
+
date: 2010-02-11 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|