bobes-textmagic 0.2.3 → 0.3.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/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
|