bobes-textmagic 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +61 -48
- data/Rakefile +32 -0
- data/VERSION.yml +2 -2
- data/lib/api.rb +114 -100
- data/lib/error.rb +2 -2
- data/lib/response.rb +47 -124
- data/test/test_api.rb +54 -98
- data/test/test_response.rb +141 -93
- data/textmagic.gemspec +4 -5
- metadata +4 -4
data/README.rdoc
CHANGED
@@ -1,18 +1,21 @@
|
|
1
1
|
= TextMagic
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
+textmagic+ gem is a Ruby interface to the TextMagic's Bulk SMS Gateway.
|
4
|
+
It can be used to easily integrate SMS features into your application.
|
5
|
+
It supports sending messages, receiving replies and more. You need to have
|
6
|
+
a valid TextMagic[http://www.textmagic.com] account to use this gem. You can
|
7
|
+
get one at http://www.textmagic.com.
|
8
|
+
|
9
|
+
To learn more about the TextMagic's Bulk
|
10
|
+
SMS Gateway, visit the official {API documentation}[http://api.textmagic.com]
|
11
|
+
or {Google group}[http://groups.google.com/group/textmagic-api].
|
12
|
+
|
13
|
+
Links:
|
14
|
+
Code[http://github.com/bobes/textmagic/tree/master]
|
6
15
|
|
|
7
|
-
|
16
|
+
Doc[http://bobes.github.com/textmagic/rdoc]
|
8
17
|
|
|
9
|
-
|
10
|
-
|
11
|
-
+textmagic+ gem is a Ruby interface to the TextMagic's Bulk SMS Gateway.
|
12
|
-
It can be used to send SMS messages and receive replies, check statuses
|
13
|
-
of sent messages and retrieve account balance.
|
14
|
-
You need to have a valid TextMagic[http://www.textmagic.com] account to use this gem. Sign up at
|
15
|
-
http://www.textmagic.com to get one.
|
18
|
+
Blame[http://bobes.github.com]
|
16
19
|
|
17
20
|
|
18
21
|
== Installation
|
@@ -28,95 +31,105 @@ Use +sudo+ if required by your system.
|
|
28
31
|
|
29
32
|
Start with requiring +textmagic+ library:
|
30
33
|
|
34
|
+
require 'rubygems'
|
31
35
|
require 'textmagic'
|
32
36
|
|
33
|
-
|
37
|
+
Then create an API instance with your credentials:
|
34
38
|
|
35
39
|
api = TextMagic::API.new(username, password)
|
36
40
|
|
37
|
-
|
38
|
-
and will use them in all requests to the SMS gateway.
|
41
|
+
These credentials will be used in all requests to the SMS gateway.
|
39
42
|
|
40
43
|
=== Account balance
|
41
44
|
|
42
|
-
|
45
|
+
Check your account's balance:
|
43
46
|
|
44
47
|
api.account.balance
|
45
48
|
# => 314.15
|
46
49
|
|
50
|
+
See TextMagic::API.account for more information on +account+ method.
|
51
|
+
|
47
52
|
=== Sending messages
|
48
53
|
|
49
54
|
To send a message to a single phone number, run:
|
50
55
|
|
51
|
-
api.send 'Hi
|
56
|
+
api.send 'Hi Wilma!', '999314159265'
|
52
57
|
|
53
58
|
You can even specify multiple phone numbers:
|
54
59
|
|
55
|
-
api.send '
|
60
|
+
api.send 'Hello everybody', '999314159265', '999271828182'
|
56
61
|
|
57
62
|
Unicode messages are supported as well:
|
58
63
|
|
59
64
|
api.send 'Вильма Привет!', '999314159265'
|
60
65
|
|
61
|
-
Long messages will be split to up to 3 parts.
|
62
|
-
of parts,
|
66
|
+
Long messages will be split to up to 3 parts. To limit maximum number
|
67
|
+
of parts, specify an optional +max_length+ parameter:
|
68
|
+
|
69
|
+
api.send 'Very very long message...', '999314159265', :max_length => 2
|
63
70
|
|
64
|
-
|
71
|
+
See TextMagic::API.send for more information on +send+ method.
|
65
72
|
|
66
73
|
=== Checking sent message status
|
67
74
|
|
68
75
|
If you want to check sent message status, you have to use +message_id+
|
69
|
-
returned in
|
76
|
+
returned in response to +send+ command.
|
70
77
|
|
71
|
-
api.send('Hi
|
78
|
+
api.send('Hi Wilma!', '999314159265')
|
72
79
|
# => '141421'
|
73
|
-
api.message_status('141421')
|
80
|
+
status = api.message_status('141421')
|
74
81
|
# => 'd'
|
82
|
+
status.completed_time
|
83
|
+
# => Fri May 22 10:10:18 +0200 2009
|
75
84
|
|
76
|
-
You can also
|
77
|
-
|
85
|
+
You can also check statuses of several messages at once, in which case
|
86
|
+
you'll get a hash with message ids as keys:
|
78
87
|
|
79
|
-
api.send('Hi
|
80
|
-
# =>
|
88
|
+
api.send('Hi Wilma!', '999314159265', '999271828182').message_id
|
89
|
+
# => { '999314159265' => '141421', '999271828182' => '173205' }
|
81
90
|
statuses = api.message_status('141421', '173205')
|
82
|
-
|
83
|
-
|
91
|
+
# => { '141421' => 'r', '173205' => 'd' }
|
92
|
+
statuses['173205'].created_time
|
93
|
+
# => Thu May 28 16:41:45 +0200 2009
|
94
|
+
|
95
|
+
See TextMagic::API.message_status for more information on +message_status+ method.
|
96
|
+
|
97
|
+
<b>It is strongly encouraged to setup callbacks to receive updates on message status
|
98
|
+
instead of using this method.</b>
|
84
99
|
|
85
100
|
=== Receiving replies
|
86
101
|
|
87
102
|
To receive all available replies, run:
|
88
103
|
|
89
|
-
replies = api.receive
|
90
|
-
# => [
|
104
|
+
replies = api.receive
|
105
|
+
# => ['999271828182: Hello Fred!', '999314159265: Good day!']
|
91
106
|
replies.first.text
|
92
|
-
# => '
|
107
|
+
# => 'Hello Fred!'
|
108
|
+
replies.last.from
|
109
|
+
# => '999314159265'
|
110
|
+
replies.last.message_id
|
111
|
+
# => '223606'
|
93
112
|
|
94
113
|
To prevent receiving old replies again, supply +last_retrieved_id+ argument:
|
95
114
|
|
96
|
-
|
115
|
+
api.receive('178082')
|
97
116
|
# => []
|
98
117
|
|
99
|
-
|
118
|
+
See TextMagic::API.receive for more information on +message_status+ method.
|
100
119
|
|
101
|
-
|
102
|
-
|
103
|
-
message_ids = api.receive.message_ids
|
104
|
-
# => ['141421', '1780826']
|
105
|
-
api.delete_reply '141421', '1780826'
|
120
|
+
<b>It is strongly encouraged to setup callbacks to receive replies instead of
|
121
|
+
using this method.</b>
|
106
122
|
|
123
|
+
=== Deleting retrieved replies
|
107
124
|
|
108
|
-
|
125
|
+
After you retrieve replies, you can delete them from server by running:
|
109
126
|
|
110
|
-
|
111
|
-
|
112
|
-
You can find documentation for the gem at project's homepage[http://textmagic.rubyforge.org]
|
113
|
-
at RubyForge.
|
127
|
+
api.delete_reply '141421', '178082'
|
128
|
+
# => true
|
114
129
|
|
115
|
-
|
116
|
-
official API documentation[http://api.textmagic.com] or
|
117
|
-
Google group[http://groups.google.com/group/textmagic-api].
|
130
|
+
See TextMagic::API.delete_reply for more information on +message_status+ method.
|
118
131
|
|
119
132
|
|
120
133
|
== Copyright
|
121
134
|
|
122
|
-
Copyright (c) 2009
|
135
|
+
Copyright (c) 2009 Vladimír Bobeš Tužinský. See LICENSE for details.
|
data/Rakefile
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rake'
|
3
|
+
require 'sdoc'
|
3
4
|
|
4
5
|
begin
|
5
6
|
require 'jeweler'
|
@@ -57,4 +58,35 @@ Rake::RDocTask.new do |rdoc|
|
|
57
58
|
rdoc.title = "textmagic #{version}"
|
58
59
|
rdoc.rdoc_files.include('README*')
|
59
60
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
61
|
+
rdoc.options << '--charset' << 'utf8'
|
62
|
+
rdoc.options << '--fmt' << 'shtml'
|
63
|
+
rdoc.template = 'direct'
|
64
|
+
end
|
65
|
+
|
66
|
+
desc "Build, commit and publish the RDOC files"
|
67
|
+
task :doc => :rerdoc do
|
68
|
+
cmd = <<-EOS
|
69
|
+
echo 'Packing and deleting rdoc directory'
|
70
|
+
tar -cf rdoc.tar rdoc
|
71
|
+
rm -rf rdoc
|
72
|
+
echo 'Checking out gh-pages branch'
|
73
|
+
git checkout -m gh-pages
|
74
|
+
echo 'Replacing rdoc directory'
|
75
|
+
rm -rf rdoc
|
76
|
+
tar -xf rdoc.tar
|
77
|
+
rm rdoc.tar
|
78
|
+
echo 'Commiting'
|
79
|
+
git add rdoc
|
80
|
+
git commit -m 'Updated RDoc'
|
81
|
+
echo 'Pushing to origin'
|
82
|
+
git push origin gh-pages
|
83
|
+
EOS
|
84
|
+
|
85
|
+
system cmd.split(/\n\s*/).join(' && ')
|
86
|
+
|
87
|
+
system <<-EOS
|
88
|
+
echo 'Checking out master'
|
89
|
+
git checkout master
|
90
|
+
echo 'Done'
|
91
|
+
EOS
|
60
92
|
end
|
data/VERSION.yml
CHANGED
data/lib/api.rb
CHANGED
@@ -6,68 +6,70 @@ module TextMagic
|
|
6
6
|
extend Validation
|
7
7
|
|
8
8
|
# Creates new API instance with specified credentials. These will be
|
9
|
-
# used in all requests to the TextMagic
|
9
|
+
# used in all requests to the TextMagic SMS gateway done through
|
10
10
|
# this instance. Multiple instances with different credentials can
|
11
11
|
# be used at the same time.
|
12
12
|
#
|
13
13
|
# Example usage:
|
14
14
|
#
|
15
|
-
#
|
15
|
+
# api = TextMagic::API.new('fred', 'secret')
|
16
16
|
def initialize(username, password)
|
17
17
|
@username = username
|
18
18
|
@password = password
|
19
19
|
end
|
20
20
|
|
21
|
-
# Executes an account command
|
22
|
-
#
|
23
|
-
# The returned hash will be extended with custom reader method defined
|
24
|
-
# in Response module.
|
21
|
+
# Executes an account command by sending a request to the TextMagic's
|
22
|
+
# SMS gateway.
|
25
23
|
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
# # => { 'balance' => 314.15 }
|
24
|
+
# This method returns an object with balance attribute.
|
25
|
+
# In case the request to the SMS gateway is not successful or the server
|
26
|
+
# returns an error response, an Error is raised.
|
30
27
|
#
|
31
|
-
#
|
28
|
+
# Example usage:
|
32
29
|
#
|
33
30
|
# api.account.balance
|
34
31
|
# # => 314.15
|
35
32
|
def account
|
36
|
-
|
37
|
-
|
33
|
+
hash = Executor.execute('account', @username, @password)
|
34
|
+
TextMagic::API::Response.account(hash)
|
38
35
|
end
|
39
36
|
|
40
|
-
# Executes a send command
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
37
|
+
# Executes a send command by sending a request to the TextMagic's
|
38
|
+
# SMS gateway.
|
39
|
+
#
|
40
|
+
# If called with a single phone number, this method returns a string message id.
|
41
|
+
# If called with multiple phone numbers, it will return an hash of message ids
|
42
|
+
# with phone numbers as keys.
|
43
|
+
# In both cases the returned object is extended with +sent_text+ and +parts_count+
|
44
|
+
# attributes.
|
45
|
+
# In case the request to the SMS gateway is not successful or the server returns
|
46
|
+
# an error response, an Error is raised.
|
47
|
+
#
|
48
|
+
# The optional parameters you can specify in the options Hash are:
|
49
|
+
# * +unicode+: accepted values are +true+, +false+, +0+ and +1+. If not specified,
|
50
|
+
# the method will determine the unicode value based on the characters in
|
51
|
+
# the text.
|
52
|
+
# * +max_length+: accepted values are +nil+, +1+, +2+ and +3+, defaults to nil.
|
53
|
+
# If not specified, the SMS gateway will apply its own default value.
|
53
54
|
#
|
54
55
|
# Example usage:
|
55
56
|
#
|
56
|
-
# api.send('Hi
|
57
|
-
# # => { 'message_ids' => [141421], 'message_id_hash' => { '999314159265' => '141421' }, 'sent_text' => 'Hi Vilma', 'parts_count' => 1 }
|
58
|
-
# api.send(text, phone, :unicode => true)
|
59
|
-
# api.send(text, phone1, phone2, :max_length => 2)
|
60
|
-
# api.send(text, [phone1, phone2])
|
61
|
-
#
|
62
|
-
# Using custom readers:
|
63
|
-
#
|
64
|
-
# response = api.send('Hi Vilma', '999314159265', '999271828182')
|
65
|
-
# response.message_ids
|
66
|
-
# # => ['141421', '173205']
|
67
|
-
# response['999314159265']
|
57
|
+
# api.send('Hi Wilma', '999314159265')
|
68
58
|
# # => '141421'
|
59
|
+
# response = api.send('Hello everybody', '999314159265', '999271828182', :max_length => 2)
|
60
|
+
# # => { '999314159265' => '141421', '999271828182' => '173205' }
|
69
61
|
# response.parts_count
|
70
62
|
# # => 1
|
63
|
+
#
|
64
|
+
# Multiple phone numbers can be supplied as an array or as a list of arguments:
|
65
|
+
#
|
66
|
+
# api.send('Hello everybody', ['999314159265', '999271828182'])
|
67
|
+
# api.send('Hello everybody', '999314159265', '999271828182')
|
68
|
+
#
|
69
|
+
# If you want to send a message to a single phone number but still
|
70
|
+
# want to get a hash response, put the phone number in an array:
|
71
|
+
#
|
72
|
+
# api.send('Hi Barney', ['999271828182'])
|
71
73
|
def send(text, *args)
|
72
74
|
raise Error.new(1, 'Message text is empty') if text.nil? || text.blank?
|
73
75
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
@@ -80,99 +82,111 @@ module TextMagic
|
|
80
82
|
end
|
81
83
|
raise Error.new(6, 'Message contains invalid characters') if unicode && options[:unicode] == 0
|
82
84
|
raise Error.new(7, 'Message too long') unless API.validate_text_length(text, unicode)
|
85
|
+
single = args.size == 1 && args.first.is_a?(String)
|
83
86
|
phones = args.flatten
|
84
87
|
raise Error.new(9, 'Invalid phone number format') unless API.validate_phones(phones)
|
85
|
-
|
86
|
-
|
87
|
-
response
|
88
|
+
hash = Executor.execute('send', @username, @password, options.merge(:text => text, :phone => phones.join(',')))
|
89
|
+
TextMagic::API::Response.send(hash, single)
|
88
90
|
end
|
89
91
|
|
90
|
-
# Executes a message_status command
|
91
|
-
#
|
92
|
-
# TextMagic::API::Error.
|
93
|
-
# The returned hash will be extended with custom reader methods defined
|
94
|
-
# in Response module.
|
92
|
+
# Executes a message_status command by sending a request to the TextMagic's
|
93
|
+
# SMS gateway.
|
95
94
|
#
|
96
|
-
#
|
97
|
-
#
|
95
|
+
# If called with a single +id+, this method returns a single string value
|
96
|
+
# denoting the message status. This string is extended with custom attributes
|
97
|
+
# +text+, +status+, +created_time+, +completed_time+, +reply_number+ and
|
98
|
+
# +credits_cost+. If called with multiple ids, it returns a hash of such
|
99
|
+
# strings with message ids as keys.
|
100
|
+
# In case the request to the SMS gateway is not successful or the server returns
|
101
|
+
# an error response, an Error is raised.
|
98
102
|
#
|
99
103
|
# Example usage:
|
100
104
|
#
|
101
|
-
# api.message_status('141421')
|
102
|
-
# # => { '141421' => { 'text' => 'Hi Vilma', 'status' => 'd' , 'created_time' => Mon May 25 16:42:30 +0200 2009, 'reply_number' => '447624800500', 'completed_time' => nil, 'credits_cost' => 0.5 } }
|
103
|
-
# api.message_status('141421', '173205')
|
104
|
-
# api.message_status(['141421', '173205'])
|
105
|
-
#
|
106
|
-
# Using custom readers:
|
107
|
-
#
|
108
|
-
# response = api.message_status('141421', '173205')
|
109
|
-
# response['141421'].text
|
110
|
-
# # => 'Hi Vilma'
|
111
|
-
# response['141421'].status
|
105
|
+
# status = api.message_status('141421')
|
112
106
|
# # => 'd'
|
113
|
-
#
|
107
|
+
# status.completed_time
|
114
108
|
# # => Fri May 22 10:10:18 +0200 2009
|
109
|
+
#
|
110
|
+
# Example with multiple ids:
|
111
|
+
#
|
112
|
+
# statuses = api.message_status('141421', '173205')
|
113
|
+
# # => { '141421' => 'r', '173205' => 'd' }
|
114
|
+
# statuses['141421'].text
|
115
|
+
# # => 'Hi Wilma'
|
116
|
+
# statuses['173205'].created_time
|
117
|
+
# # => Thu May 28 16:41:45 +0200 2009
|
118
|
+
#
|
119
|
+
# Multiple ids can be supplied as an array or as a list of arguments:
|
120
|
+
#
|
121
|
+
# api.send('Hello everybody', ['999314159265', '999271828182'])
|
122
|
+
# api.send('Hello everybody', '999314159265', '999271828182')
|
123
|
+
#
|
124
|
+
# If you want to request status for a single message but still want to get
|
125
|
+
# a hash response, put the id in an array:
|
126
|
+
#
|
127
|
+
# api.message_status(['141421'])
|
128
|
+
#
|
129
|
+
# <b>It is strongly encouraged to setup callbacks to receive updates on message status
|
130
|
+
# instead of using this method.</b>
|
115
131
|
def message_status(*ids)
|
116
132
|
single = ids.size == 1 && ids.first.is_a?(String)
|
117
133
|
ids.flatten!
|
118
134
|
raise TextMagic::API::Error.new(4, 'Insufficient parameters') if ids.empty?
|
119
|
-
|
120
|
-
|
121
|
-
single ? response[ids.first] : response
|
135
|
+
hash = Executor.execute('message_status', @username, @password, :ids => ids.join(','))
|
136
|
+
TextMagic::API::Response.message_status(hash, single)
|
122
137
|
end
|
123
138
|
|
124
|
-
# Executes a receive command
|
125
|
-
#
|
126
|
-
# The returned hash will be extended with custom reader methods defined
|
127
|
-
# in Response module.
|
139
|
+
# Executes a receive command by sending a request to the TextMagic's
|
140
|
+
# SMS gateway.
|
128
141
|
#
|
129
|
-
# This method
|
142
|
+
# This method returnes an array with retrieved messages. Every member of
|
143
|
+
# the array is a string with +from+, +text+, +timestamp+ and +message_id+
|
144
|
+
# attributes. The value of every string contains a phone number and text.
|
145
|
+
# In case the request to the SMS gateway is not successful or the server returns
|
146
|
+
# an error response, an Error is raised.
|
130
147
|
#
|
131
|
-
#
|
132
|
-
#
|
133
|
-
#
|
134
|
-
# # => { 'messages' => [{ 'message_id' => '141421', 'from' => '999314159265', 'timestamp' => Fri May 22 12:12:55 +0200 2009, 'text' => 'Hi Fred!' }], 'unread' => 0 }
|
135
|
-
# api.receive '141421'
|
148
|
+
# This method accepts an optional +last_retrieved_id+ value. If called
|
149
|
+
# with this argument, the gateway will only return replies newer than the
|
150
|
+
# one with specified id.
|
136
151
|
#
|
137
|
-
#
|
152
|
+
# Example usage:
|
138
153
|
#
|
139
|
-
#
|
140
|
-
#
|
141
|
-
#
|
142
|
-
#
|
143
|
-
#
|
144
|
-
#
|
145
|
-
#
|
154
|
+
# replies = api.receive
|
155
|
+
# # => ['999271828182: Hello Fred', '999314159265: Good day']
|
156
|
+
# replies.first.text
|
157
|
+
# # => 'Hello Fred'
|
158
|
+
# replies.first.from
|
159
|
+
# # => '999314159265'
|
160
|
+
# replies.last.message_id
|
161
|
+
# # => '223606'
|
162
|
+
# api.receive '223606'
|
163
|
+
# # => []
|
164
|
+
#
|
165
|
+
# <b>It is strongly encouraged to setup callbacks to receive replies instead of
|
166
|
+
# using this method.</b>
|
146
167
|
def receive(last_retrieved_id = nil)
|
147
|
-
|
148
|
-
|
168
|
+
hash = Executor.execute('receive', @username, @password, :last_retrieved_id => last_retrieved_id)
|
169
|
+
TextMagic::API::Response.receive(hash)
|
149
170
|
end
|
150
171
|
|
151
|
-
# Executes a delete_reply command
|
152
|
-
#
|
153
|
-
# The returned hash will be extended with custom reader methods defined
|
154
|
-
# in Response module.
|
172
|
+
# Executes a delete_reply command by sending a request to the TextMagic's
|
173
|
+
# SMS gateway.
|
155
174
|
#
|
156
|
-
# This method
|
157
|
-
#
|
175
|
+
# This method always returns true.
|
176
|
+
# In case the request to the SMS gateway is not successful or the server returns
|
177
|
+
# an error response, an Error is raised.
|
158
178
|
#
|
159
179
|
# Example usage:
|
160
180
|
#
|
161
181
|
# api.delete_reply('141421')
|
162
|
-
#
|
163
|
-
# api.delete_reply('
|
164
|
-
# api.delete_reply(['141421', '173205'])
|
165
|
-
#
|
166
|
-
# Using custom readers:
|
167
|
-
#
|
168
|
-
# response = api.delete_reply('141421', '173205')
|
169
|
-
# response.deleted
|
170
|
-
# # => ['141421', '173205']
|
182
|
+
# api.delete_reply('173205', '223606')
|
183
|
+
# api.delete_reply(['244948', '264575'])
|
171
184
|
def delete_reply(*ids)
|
185
|
+
single = ids.size == 1 && ids.first.is_a?(String)
|
172
186
|
ids.flatten!
|
173
187
|
raise TextMagic::API::Error.new(4, 'Insufficient parameters') if ids.empty?
|
174
|
-
|
175
|
-
|
188
|
+
Executor.execute('delete_reply', @username, @password, :ids => ids.join(','))
|
189
|
+
true
|
176
190
|
end
|
177
191
|
end
|
178
192
|
end
|