textmagic 0.2.2 → 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/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009 Vladimír Bobeš Tužinský
1
+ Copyright (c) 2009 Vladimir Bobes Tuzinsky
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.rdoc CHANGED
@@ -1,18 +1,21 @@
1
1
  = TextMagic
2
2
 
3
- Code[http://github.com/bobes/textmagic]
4
- |
5
- RDoc[http://textmagic.rubyforge.org]
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
- Forum[http://groups.google.com/group/textmagic-api]
16
+ Doc[http://bobes.github.com/textmagic/rdoc]
8
17
  |
9
- Issues[http://github.com/bobes/textmagic/issues]
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
@@ -26,91 +29,105 @@ Use +sudo+ if required by your system.
26
29
 
27
30
  == Basic usage
28
31
 
29
- To create an API instance, run:
32
+ Start with requiring +textmagic+ library:
33
+
34
+ require 'rubygems'
35
+ require 'textmagic'
36
+
37
+ Then create an API instance with your credentials:
30
38
 
31
39
  api = TextMagic::API.new(username, password)
32
40
 
33
- with your credentials. Created instance will remember the username and password
34
- and will use them in all requests to the SMS gateway.
41
+ These credentials will be used in all requests to the SMS gateway.
35
42
 
36
43
  === Account balance
37
44
 
38
- To retrieve your account's balance, run:
45
+ Check your account's balance:
39
46
 
40
47
  api.account.balance
41
48
  # => 314.15
42
49
 
50
+ See TextMagic::API.account for more information on +account+ method.
51
+
43
52
  === Sending messages
44
53
 
45
54
  To send a message to a single phone number, run:
46
55
 
47
- api.send 'Hi Vilma!', '999314159265'
56
+ api.send 'Hi Wilma!', '999314159265'
48
57
 
49
58
  You can even specify multiple phone numbers:
50
59
 
51
- api.send 'Hi everybody!', '999314159265', '999271828182'
60
+ api.send 'Hello everybody', '999314159265', '999271828182'
52
61
 
53
62
  Unicode messages are supported as well:
54
63
 
55
64
  api.send 'Вильма Привет!', '999314159265'
56
65
 
57
- Long messages will be split to up to 3 parts. If you want to limit maximum number
58
- of parts, you can specify an optional +max_length+ parameter:
66
+ Long messages will be split to up to 3 parts. To limit maximum number
67
+ of parts, specify an optional +max_length+ parameter:
59
68
 
60
- api.send 'Very long message...', '999314159265', :max_length => 2
69
+ api.send 'Very very long message...', '999314159265', :max_length => 2
70
+
71
+ See TextMagic::API.send for more information on +send+ method.
61
72
 
62
73
  === Checking sent message status
63
74
 
64
75
  If you want to check sent message status, you have to use +message_id+
65
- returned in respose to +send+ command.
76
+ returned in response to +send+ command.
66
77
 
67
- api.send('Hi Vilma!', '999314159265').message_id
78
+ api.send('Hi Wilma!', '999314159265')
68
79
  # => '141421'
69
- api.message_status('141421').status
80
+ status = api.message_status('141421')
70
81
  # => 'd'
82
+ status.completed_time
83
+ # => Fri May 22 10:10:18 +0200 2009
71
84
 
72
- You can also supply several message_ids, in which case you'll get a hash with
73
- message_ids as keys:
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:
74
87
 
75
- api.send('Hi Vilma!', '999314159265', '999271828182').message_ids
76
- # => ['141421', '173205']
88
+ api.send('Hi Wilma!', '999314159265', '999271828182').message_id
89
+ # => { '999314159265' => '141421', '999271828182' => '173205' }
77
90
  statuses = api.message_status('141421', '173205')
78
- statuses['141421'].status
79
- # => 'r'
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>
80
99
 
81
100
  === Receiving replies
82
101
 
83
102
  To receive all available replies, run:
84
103
 
85
- replies = api.receive.messages
86
- # => [{ 'timestamp' => Fri May 22 12:12:55 +0200 2009, 'from' => '999314159265', 'text' => 'Hi Fred!', 'message_id' => '1780826' }]
104
+ replies = api.receive
105
+ # => ['999271828182: Hello Fred!', '999314159265: Good day!']
87
106
  replies.first.text
88
- # => 'Hi Fred!'
107
+ # => 'Hello Fred!'
108
+ replies.last.from
109
+ # => '999314159265'
110
+ replies.last.message_id
111
+ # => '223606'
89
112
 
90
113
  To prevent receiving old replies again, supply +last_retrieved_id+ argument:
91
114
 
92
- replies = api.receive('1780826').messages
115
+ api.receive('178082')
93
116
  # => []
94
117
 
95
- === Deleting retrieved replies
96
-
97
- After you retrieve replies, you can delete them from server by running:
118
+ See TextMagic::API.receive for more information on +message_status+ method.
98
119
 
99
- message_ids = api.receive.message_ids
100
- # => ['141421', '1780826']
101
- api.delete_reply '141421', '1780826'
120
+ <b>It is strongly encouraged to setup callbacks to receive replies instead of
121
+ using this method.</b>
102
122
 
123
+ === Deleting retrieved replies
103
124
 
104
- == Links
125
+ After you retrieve replies, you can delete them from server by running:
105
126
 
106
- The code is hosted at GitHub[http://github.com/bobes/textmagic] and released to
107
- RubyForge[http://rubyforge.org/projects/textmagic].
108
- You can find documentation for the gem at project's homepage[http://textmagic.rubyforge.org]
109
- at RubyForge.
127
+ api.delete_reply '141421', '178082'
128
+ # => true
110
129
 
111
- For general information on TextMagic's Bulk SMS Gateway, visit the
112
- official API documentation[http://api.textmagic.com] or
113
- Google group[http://groups.google.com/group/textmagic-api].
130
+ See TextMagic::API.delete_reply for more information on +message_status+ method.
114
131
 
115
132
 
116
133
  == Copyright
data/Rakefile CHANGED
@@ -1,15 +1,20 @@
1
1
  require 'rubygems'
2
2
  require 'rake'
3
+ require 'sdoc'
3
4
 
4
5
  begin
5
6
  require 'jeweler'
6
7
  Jeweler::Tasks.new do |gem|
7
8
  gem.name = "textmagic"
8
- gem.summary = %Q{Ruby interface to the TextMagic's SMS gateway}
9
+ gem.summary = %Q{Ruby interface to the TextMagic's Bulk SMS Gateway}
9
10
  gem.email = "vladimir.tuzinsky@gmail.com"
10
11
  gem.homepage = "http://github.com/bobes/textmagic"
11
- gem.authors = ["Vladimír Bobeš Tužinský"]
12
+ gem.authors = ["Vladimir Bobes Tuzinsky"]
12
13
  gem.rubyforge_project = "textmagic"
14
+ gem.add_runtime_dependency "httparty", ">= 0.4.3"
15
+ gem.add_development_dependency "mocha", ">= 0.9.5"
16
+ gem.add_development_dependency "fakeweb", ">= 1.2.2"
17
+ gem.add_development_dependency "jeremymcanally-matchy", ">= 0.1.0"
13
18
  end
14
19
 
15
20
  Jeweler::RubyforgeTasks.new
@@ -53,4 +58,35 @@ Rake::RDocTask.new do |rdoc|
53
58
  rdoc.title = "textmagic #{version}"
54
59
  rdoc.rdoc_files.include('README*')
55
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
56
92
  end
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 0
3
- :minor: 2
4
- :patch: 2
3
+ :minor: 3
4
+ :patch: 0
data/lib/api.rb CHANGED
@@ -6,72 +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's HTTP gateway done through
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
- # api = TextMagic::API.new('fred', 'secret')
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 and returns a hash with account's balance
22
- # if successful, otherwise it raises an Error.
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
- # Example usage:
27
- #
28
- # api.account
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
- # Using custom reader:
28
+ # Example usage:
32
29
  #
33
30
  # api.account.balance
34
31
  # # => 314.15
35
32
  def account
36
- response = Executor.execute('account', @username, @password)
37
- response.extend(TextMagic::API::Response::Account)
33
+ hash = Executor.execute('account', @username, @password)
34
+ TextMagic::API::Response.account(hash)
38
35
  end
39
36
 
40
- # Executes a send command and returns a hash with message ids, sent text and
41
- # number of parts if successful, otherwise it raises an Error.
42
- # The returned hash will be extended with custom reader method defined
43
- # in Response module.
44
- #
45
- # This method accepts any positive number of phone numbers and an additional
46
- # options hash.
47
- #
48
- # The optional parameters you can specify in the options hash are:
49
- # * +unicode+: accepted values are true, false, 0 and 1
50
- # * +max_length+: accepted values are nil, 1, 2 and 3, defaults to nil
51
- # If not specified, the method will determine the unicode value based on the
52
- # characters in the text.
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 Vilma', '999314159265')
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.message_id_hash
68
- # # => { '999314159265' => '141421', '999271828182' => '173205' }
69
- # response.message_id
57
+ # api.send('Hi Wilma', '999314159265')
70
58
  # # => '141421'
71
- # response.message_id('999271828182')
72
- # # => '173205'
59
+ # response = api.send('Hello everybody', '999314159265', '999271828182', :max_length => 2)
60
+ # # => { '999314159265' => '141421', '999271828182' => '173205' }
73
61
  # response.parts_count
74
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'])
75
73
  def send(text, *args)
76
74
  raise Error.new(1, 'Message text is empty') if text.nil? || text.blank?
77
75
  options = args.last.is_a?(Hash) ? args.pop : {}
@@ -84,99 +82,111 @@ module TextMagic
84
82
  end
85
83
  raise Error.new(6, 'Message contains invalid characters') if unicode && options[:unicode] == 0
86
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)
87
86
  phones = args.flatten
88
87
  raise Error.new(9, 'Invalid phone number format') unless API.validate_phones(phones)
89
- response = Executor.execute('send', @username, @password, options.merge(:text => text, :phone => phones.join(',')))
90
- response.extend(TextMagic::API::Response::Send)
91
- response
88
+ hash = Executor.execute('send', @username, @password, options.merge(:text => text, :phone => phones.join(',')))
89
+ TextMagic::API::Response.send(hash, single)
92
90
  end
93
91
 
94
- # Executes a message_status command and returns a hash with states of
95
- # messages for specified ids if successful, otherwise it raises a
96
- # TextMagic::API::Error.
97
- # The returned hash will be extended with custom reader method defined
98
- # in Response module.
92
+ # Executes a message_status command by sending a request to the TextMagic's
93
+ # SMS gateway.
99
94
  #
100
- # This method accepts any positive number of ids specified as an array
101
- # or as a list of arguments
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.
102
102
  #
103
103
  # Example usage:
104
104
  #
105
- # api.message_status('141421')
106
- # # => { '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 } }
107
- # api.message_status('141421', '173205')
108
- # api.message_status(['141421', '173205'])
109
- #
110
- # Using custom readers:
111
- #
112
- # response = api.message_status('141421', '173205')
113
- # response['141421'].text
114
- # # => 'Hi Vilma'
115
- # response['141421'].status
105
+ # status = api.message_status('141421')
116
106
  # # => 'd'
117
- # response['141421'].created_time
107
+ # status.completed_time
118
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>
119
131
  def message_status(*ids)
120
132
  single = ids.size == 1 && ids.first.is_a?(String)
121
133
  ids.flatten!
122
134
  raise TextMagic::API::Error.new(4, 'Insufficient parameters') if ids.empty?
123
- response = Executor.execute('message_status', @username, @password, :ids => ids.join(','))
124
- response.extend(TextMagic::API::Response::MessageStatus)
125
- single ? response[ids.first] : response
135
+ hash = Executor.execute('message_status', @username, @password, :ids => ids.join(','))
136
+ TextMagic::API::Response.message_status(hash, single)
126
137
  end
127
138
 
128
- # Executes a receive command and returns a hash with unread messages
129
- # if successful, otherwise it raises an Error.
130
- # The returned hash will be extended with custom reader method defined
131
- # in Response module.
132
- #
133
- # This method accepts an optional +last_retrieved_id+ value.
139
+ # Executes a receive command by sending a request to the TextMagic's
140
+ # SMS gateway.
134
141
  #
135
- # Example usage:
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.
136
147
  #
137
- # api.receive
138
- # # => { 'messages' => [{ 'message_id' => '141421', 'from' => '999314159265', 'timestamp' => Fri May 22 12:12:55 +0200 2009, 'text' => 'Hi Fred!' }], 'unread' => 0 }
139
- # 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.
140
151
  #
141
- # Using custom readers:
152
+ # Example usage:
142
153
  #
143
- # response = api.receive
144
- # response.messages
145
- # # => [{ 'timestamp' => Fri May 22 12:12:55 +0200 2009, 'from' => '999314159265', 'text' => 'Hi Fred', 'message_id' => '141421' }]
146
- # response.unread
147
- # # => 0
148
- # response.messages[0].timestamp
149
- # # => Fri May 22 12:12:55 +0200 2009
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>
150
167
  def receive(last_retrieved_id = nil)
151
- response = Executor.execute('receive', @username, @password, :last_retrieved_id => last_retrieved_id)
152
- response.extend(TextMagic::API::Response::Receive)
168
+ hash = Executor.execute('receive', @username, @password, :last_retrieved_id => last_retrieved_id)
169
+ TextMagic::API::Response.receive(hash)
153
170
  end
154
171
 
155
- # Executes a delete_reply command and returns a hash with a list of deleted
156
- # message ids if successful, otherwise it raises an Error.
157
- # The returned hash will be extended with custom reader method defined
158
- # in Response module.
172
+ # Executes a delete_reply command by sending a request to the TextMagic's
173
+ # SMS gateway.
159
174
  #
160
- # This method accepts any positive number of ids specified as an array
161
- # or as a list of arguments.
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.
162
178
  #
163
179
  # Example usage:
164
180
  #
165
181
  # api.delete_reply('141421')
166
- # # => { 'deleted' => ['141421'] }
167
- # api.delete_reply('141421', '173205')
168
- # api.delete_reply(['141421', '173205'])
169
- #
170
- # Using custom readers:
171
- #
172
- # response = api.delete_reply('141421', '173205')
173
- # response.deleted
174
- # # => ['141421', '173205']
182
+ # api.delete_reply('173205', '223606')
183
+ # api.delete_reply(['244948', '264575'])
175
184
  def delete_reply(*ids)
185
+ single = ids.size == 1 && ids.first.is_a?(String)
176
186
  ids.flatten!
177
187
  raise TextMagic::API::Error.new(4, 'Insufficient parameters') if ids.empty?
178
- response = Executor.execute('delete_reply', @username, @password, :ids => ids.join(','))
179
- response.extend(TextMagic::API::Response::DeleteReply)
188
+ Executor.execute('delete_reply', @username, @password, :ids => ids.join(','))
189
+ true
180
190
  end
181
191
  end
182
192
  end
data/lib/error.rb CHANGED
@@ -6,8 +6,8 @@ module TextMagic
6
6
 
7
7
  attr_reader :code, :message
8
8
 
9
- # Creates an instance of TextMagic::API::Error. Error code and message
10
- # can be supplied as arguments or as a response hash.
9
+ # Creates an instance of TextMagic::API::Error. Error code and error message
10
+ # can be supplied as arguments or in a hash.
11
11
  #
12
12
  # TextMagic::API::Error.new(code, message)
13
13
  # TextMagic::API::Error.new('error_code' => code, 'error_message' => message)