textmagic 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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)