textmagic 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +40 -0
- data/Rakefile +57 -0
- data/VERSION.yml +4 -0
- data/lib/api.rb +179 -0
- data/lib/charset.rb +23 -0
- data/lib/error.rb +27 -0
- data/lib/executor.rb +34 -0
- data/lib/response.rb +141 -0
- data/lib/textmagic.rb +12 -0
- data/lib/validation.rb +34 -0
- data/test/test_api.rb +246 -0
- data/test/test_charset.rb +28 -0
- data/test/test_error.rb +24 -0
- data/test/test_executor.rb +70 -0
- data/test/test_helper.rb +38 -0
- data/test/test_response.rb +176 -0
- data/test/test_validation.rb +99 -0
- data/textmagic.gemspec +64 -0
- metadata +80 -0
data/.document
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Vladimir Bobes Tuzinsky
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
= TextMagic
|
2
|
+
|
3
|
+
TextMagic is a Ruby interface to the TextMagic's HTTP API. You need to have
|
4
|
+
a valid TextMagic account to use this gem. Sign up at http://www.textmagic.com
|
5
|
+
to get one.
|
6
|
+
|
7
|
+
== Installation
|
8
|
+
|
9
|
+
Run
|
10
|
+
|
11
|
+
gem install textmagic
|
12
|
+
|
13
|
+
Use +sudo+ if required by your system.
|
14
|
+
|
15
|
+
|
16
|
+
== Basic usage
|
17
|
+
|
18
|
+
To create an API instance, run:
|
19
|
+
|
20
|
+
api = TextMagic::API.new(username, password)
|
21
|
+
|
22
|
+
with your credentials. Created instance will remember the username and password
|
23
|
+
and will use it for all commands.
|
24
|
+
|
25
|
+
To retrieve your account's balance, run:
|
26
|
+
|
27
|
+
api.account.balance
|
28
|
+
|
29
|
+
To send a text message, run:
|
30
|
+
|
31
|
+
api.send 'Hi Vilma!', '441234567890'
|
32
|
+
|
33
|
+
You can even specify multiple phone numbers:
|
34
|
+
|
35
|
+
api.send 'Hi Vilma!', '314159265358', '271828182845'
|
36
|
+
|
37
|
+
|
38
|
+
== Copyright
|
39
|
+
|
40
|
+
Copyright (c) 2009 Vladimir Bobes Tuzinsky. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "textmagic"
|
8
|
+
gem.summary = %Q{Ruby interface to the TextMagic's SMS gateway}
|
9
|
+
gem.email = "vladimir.tuzinsky@gmail.com"
|
10
|
+
gem.homepage = "http://github.com/bobes/textmagic"
|
11
|
+
gem.authors = ["Vladimir Bobes Tuzinsky"]
|
12
|
+
gem.rubyforge_project = "textmagic"
|
13
|
+
end
|
14
|
+
|
15
|
+
Jeweler::RubyforgeTasks.new
|
16
|
+
rescue LoadError
|
17
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'rake/testtask'
|
21
|
+
Rake::TestTask.new(:test) do |test|
|
22
|
+
test.libs << 'lib' << 'test'
|
23
|
+
test.pattern = 'test/**/*_test.rb'
|
24
|
+
test.verbose = true
|
25
|
+
end
|
26
|
+
|
27
|
+
begin
|
28
|
+
require 'rcov/rcovtask'
|
29
|
+
Rcov::RcovTask.new do |test|
|
30
|
+
test.libs << 'test'
|
31
|
+
test.pattern = 'test/**/*_test.rb'
|
32
|
+
test.verbose = true
|
33
|
+
end
|
34
|
+
rescue LoadError
|
35
|
+
task :rcov do
|
36
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
task :default => :test
|
42
|
+
|
43
|
+
require 'rake/rdoctask'
|
44
|
+
Rake::RDocTask.new do |rdoc|
|
45
|
+
if File.exist?('VERSION.yml')
|
46
|
+
config = YAML.load(File.read('VERSION.yml'))
|
47
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
48
|
+
else
|
49
|
+
version = ""
|
50
|
+
end
|
51
|
+
|
52
|
+
rdoc.rdoc_dir = 'rdoc'
|
53
|
+
rdoc.title = "textmagic #{version}"
|
54
|
+
rdoc.rdoc_files.include('README*')
|
55
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
56
|
+
end
|
57
|
+
|
data/VERSION.yml
ADDED
data/lib/api.rb
ADDED
@@ -0,0 +1,179 @@
|
|
1
|
+
module TextMagic
|
2
|
+
|
3
|
+
class API
|
4
|
+
|
5
|
+
extend Charset
|
6
|
+
extend Validation
|
7
|
+
|
8
|
+
# Creates new API instance with specified credentials. These will be
|
9
|
+
# used in all requests to the TextMagic's HTTP gateway done through
|
10
|
+
# this instance. Multiple instances with different credentials can
|
11
|
+
# be used at the same time.
|
12
|
+
#
|
13
|
+
# Example usage:
|
14
|
+
#
|
15
|
+
# api = TextMagic::API.new('fred', 'secret')
|
16
|
+
def initialize(username, password)
|
17
|
+
@username = username
|
18
|
+
@password = password
|
19
|
+
end
|
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.
|
25
|
+
#
|
26
|
+
# Example usage:
|
27
|
+
#
|
28
|
+
# api.account
|
29
|
+
# # => { 'balance' => 314.15 }
|
30
|
+
#
|
31
|
+
# Using custom reader:
|
32
|
+
#
|
33
|
+
# api.account.balance
|
34
|
+
# # => 314.15
|
35
|
+
def account
|
36
|
+
response = Executor.execute('account', @username, @password)
|
37
|
+
response.extend(TextMagic::API::Response::Account)
|
38
|
+
end
|
39
|
+
|
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.
|
53
|
+
#
|
54
|
+
# Example usage:
|
55
|
+
#
|
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
|
70
|
+
# # => '141421'
|
71
|
+
# response.message_id('999271828182')
|
72
|
+
# # => '173205'
|
73
|
+
# response.parts_count
|
74
|
+
# # => 1
|
75
|
+
def send(text, *args)
|
76
|
+
raise Error.new(1, 'Message text is empty') if text.nil? || text.blank?
|
77
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
78
|
+
unicode = API.is_unicode(text)
|
79
|
+
options[:unicode] = case options[:unicode]
|
80
|
+
when 1, true: 1
|
81
|
+
when 0, false: 0
|
82
|
+
when nil: unicode ? 1 : 0
|
83
|
+
else raise Error.new(10, "Wrong parameter value #{options[:unicode]} for parameter unicode")
|
84
|
+
end
|
85
|
+
raise Error.new(6, 'Message contains invalid characters') if unicode && options[:unicode] == 0
|
86
|
+
raise Error.new(7, 'Message too long') unless API.validate_text_length(text, unicode)
|
87
|
+
phones = args.flatten
|
88
|
+
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
|
+
end
|
92
|
+
|
93
|
+
# Executes a message_status command and returns a hash with states of
|
94
|
+
# messages for specified ids if successful, otherwise it raises a
|
95
|
+
# TextMagic::API::Error.
|
96
|
+
# The returned hash will be extended with custom reader method defined
|
97
|
+
# in Response module.
|
98
|
+
#
|
99
|
+
# This method accepts any positive number of ids specified as an array
|
100
|
+
# or as a list of arguments
|
101
|
+
#
|
102
|
+
# Example usage:
|
103
|
+
#
|
104
|
+
# api.message_status('141421')
|
105
|
+
# # => { '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 } }
|
106
|
+
# api.message_status('141421', '173205')
|
107
|
+
# api.message_status(['141421', '173205'])
|
108
|
+
#
|
109
|
+
# Using custom readers:
|
110
|
+
#
|
111
|
+
# response = api.message_status('141421', '173205')
|
112
|
+
# response['141421'].text
|
113
|
+
# # => 'Hi Vilma'
|
114
|
+
# response['141421'].status
|
115
|
+
# # => 'd'
|
116
|
+
# response['141421'].created_time
|
117
|
+
# # => Fri May 22 10:10:18 +0200 2009
|
118
|
+
def message_status(*ids)
|
119
|
+
ids.flatten!
|
120
|
+
raise TextMagic::API::Error.new(4, 'Insufficient parameters') if ids.empty?
|
121
|
+
response = Executor.execute('message_status', @username, @password, :ids => ids.join(','))
|
122
|
+
response.extend(TextMagic::API::Response::MessageStatus)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Executes a receive command and returns a hash with unread messages
|
126
|
+
# if successful, otherwise it raises an Error.
|
127
|
+
# The returned hash will be extended with custom reader method defined
|
128
|
+
# in Response module.
|
129
|
+
#
|
130
|
+
# This method accepts an optional +last_retrieved_id+ value.
|
131
|
+
#
|
132
|
+
# Example usage:
|
133
|
+
#
|
134
|
+
# api.receive
|
135
|
+
# # => { 'messages' => [{ 'message_id' => '141421', 'from' => '999314159265', 'timestamp' => Fri May 22 12:12:55 +0200 2009, 'text' => 'Hi Fred!' }], 'unread' => 0 }
|
136
|
+
# api.receive '141421'
|
137
|
+
#
|
138
|
+
# Using custom readers:
|
139
|
+
#
|
140
|
+
# response = api.receive
|
141
|
+
# response.messages
|
142
|
+
# # => [{ 'timestamp' => Fri May 22 12:12:55 +0200 2009, 'from' => '999314159265', 'text' => 'Hi Fred', 'message_id' => '141421' }]
|
143
|
+
# response.unread
|
144
|
+
# # => 0
|
145
|
+
# response.messages[0].timestamp
|
146
|
+
# # => Fri May 22 12:12:55 +0200 2009
|
147
|
+
def receive(last_retrieved_id = nil)
|
148
|
+
response = Executor.execute('receive', @username, @password, :last_retrieved_id => last_retrieved_id)
|
149
|
+
response.extend(TextMagic::API::Response::Receive)
|
150
|
+
end
|
151
|
+
|
152
|
+
# Executes a delete_reply command and returns a hash with a list of deleted
|
153
|
+
# message ids if successful, otherwise it raises an Error.
|
154
|
+
# The returned hash will be extended with custom reader method defined
|
155
|
+
# in Response module.
|
156
|
+
#
|
157
|
+
# This method accepts any positive number of ids specified as an array
|
158
|
+
# or as a list of arguments.
|
159
|
+
#
|
160
|
+
# Example usage:
|
161
|
+
#
|
162
|
+
# api.delete_reply('141421')
|
163
|
+
# # => { 'deleted' => ['141421'] }
|
164
|
+
# api.delete_reply('141421', '173205')
|
165
|
+
# api.delete_reply(['141421', '173205'])
|
166
|
+
#
|
167
|
+
# Using custom readers:
|
168
|
+
#
|
169
|
+
# response = api.delete_reply('141421', '173205')
|
170
|
+
# response.deleted
|
171
|
+
# # => ['141421', '173205']
|
172
|
+
def delete_reply(*ids)
|
173
|
+
ids.flatten!
|
174
|
+
raise TextMagic::API::Error.new(4, 'Insufficient parameters') if ids.empty?
|
175
|
+
response = Executor.execute('delete_reply', @username, @password, :ids => ids.join(','))
|
176
|
+
response.extend(TextMagic::API::Response::DeleteReply)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
data/lib/charset.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module TextMagic
|
2
|
+
|
3
|
+
class API
|
4
|
+
|
5
|
+
module Charset
|
6
|
+
|
7
|
+
GSM_CHARSET = "@£$¥èéùìòÇ\nØø\rÅåΔ_ΦΓΛΩΠΨΣΘΞ\e\f^{}\\[~]|€ÆæßÉ !\"#¤%&'()*+,-./0123456789:;<=>?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà".scan(/./u)
|
8
|
+
|
9
|
+
# Returns +true+ if the supplied text contains only characters from
|
10
|
+
# GSM 03.38 charset, otherwise it returns +false+.
|
11
|
+
def is_gsm(text)
|
12
|
+
text.scan(/./u).each { |c| return false unless GSM_CHARSET.include?(c) }
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns +true+ if the supplied text contains characters outside of
|
17
|
+
# GSM 03.38 charset, otherwise it returns +false+.
|
18
|
+
def is_unicode(text)
|
19
|
+
!is_gsm(text)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/error.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
module TextMagic
|
2
|
+
|
3
|
+
class API
|
4
|
+
|
5
|
+
class Error < StandardError
|
6
|
+
|
7
|
+
attr_reader :code, :message
|
8
|
+
|
9
|
+
# Creates an instance of TextMagic::API::Error. Error code and message
|
10
|
+
# can be supplied as arguments or as a response hash.
|
11
|
+
#
|
12
|
+
# TextMagic::API::Error.new(code, message)
|
13
|
+
# TextMagic::API::Error.new('error_code' => code, 'error_message' => message)
|
14
|
+
def initialize(*args)
|
15
|
+
if args.first.is_a?(Hash)
|
16
|
+
@code, @message = args.first['error_code'], args.first['error_message']
|
17
|
+
else
|
18
|
+
@code, @message = args
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
"#{@message} (#{@code})"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/executor.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module TextMagic
|
2
|
+
|
3
|
+
class API
|
4
|
+
|
5
|
+
class Executor
|
6
|
+
|
7
|
+
include HTTParty
|
8
|
+
base_uri "http://www.textmagic.com/app"
|
9
|
+
|
10
|
+
# Executes a command by sending a request to the TextMagic's HTTP
|
11
|
+
# gateway. This is a low-level generic method used by methods in
|
12
|
+
# TextMagic::API class. You should never need to use this method
|
13
|
+
# directly.
|
14
|
+
#
|
15
|
+
# Parameters specified in the +options+ hash will be added to the
|
16
|
+
# HTTP request's URI.
|
17
|
+
#
|
18
|
+
# Returns a hash with values parsed from the server's response if
|
19
|
+
# the command was successfully executed. In case the server replies
|
20
|
+
# with error, this method raises a TextMagic::API::Error.
|
21
|
+
def self.execute(command, username, password, options = {})
|
22
|
+
raise TextMagic::API::Error.new(3, 'Command is undefined') if command.nil? || command.blank?
|
23
|
+
if username.nil? || username.blank? || password.nil? || password.blank?
|
24
|
+
raise TextMagic::API::Error.new(5, 'Invalid username & password combination')
|
25
|
+
end
|
26
|
+
options.merge!(:username => username, :password => password, :cmd => command)
|
27
|
+
options.delete_if { |key, value| key.nil? || key.to_s.blank? || value.nil? || value.to_s.blank? }
|
28
|
+
response = self.get('/api', :query => options, :format => :json)
|
29
|
+
raise Error.new(response) if response && response['error_code']
|
30
|
+
response
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/response.rb
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
module TextMagic
|
2
|
+
|
3
|
+
class API
|
4
|
+
|
5
|
+
# Used to cleanup response hash and extend it with custom reader methods.
|
6
|
+
#
|
7
|
+
# === Account response hash
|
8
|
+
#
|
9
|
+
# When extended, it
|
10
|
+
# * converts the +balance+ value to +float+ and
|
11
|
+
# * adds a reader method +balance+.
|
12
|
+
#
|
13
|
+
# === Send response hash
|
14
|
+
#
|
15
|
+
# When extended, it
|
16
|
+
# * inverts the +message_id+ hash and puts it in +message_id_hash+,
|
17
|
+
# * adds an array of ids to +message_ids+,
|
18
|
+
# * adds reader methods +message_id_hash+, +message_ids+, +sent_text+ and
|
19
|
+
# +parts_count+ to the hash.
|
20
|
+
# * adds a reader method +message_id+, which returns a +message_id+ for
|
21
|
+
# a given phone number, or the first message_id if no phone number
|
22
|
+
# is specified.
|
23
|
+
#
|
24
|
+
# === Message status response hash
|
25
|
+
#
|
26
|
+
# When extended, it
|
27
|
+
# * converts the +credits_cost+ value to +float+,
|
28
|
+
# * converts the +created_time+ and +completed_time+ values to +Time+,
|
29
|
+
# * adds reader methods +text+, +status+, +reply_number+, +credits_cost+,
|
30
|
+
# +created_time+ and +completed_time+ to all values of the hash.
|
31
|
+
#
|
32
|
+
# === Receive status response hash
|
33
|
+
#
|
34
|
+
# When extended, it
|
35
|
+
# * converts the +timestamp+ value to +Time+,
|
36
|
+
# * adds reader methods +messages+ and +unread+ to the hash
|
37
|
+
# * adds reader methods +message_id+, +timestamp+, +text+ and +from+
|
38
|
+
# to all members of the +messages+ array.
|
39
|
+
#
|
40
|
+
# === Delete reply response hash
|
41
|
+
#
|
42
|
+
# When extended, it
|
43
|
+
# * adds a reader method +deleted+.
|
44
|
+
module Response
|
45
|
+
|
46
|
+
module Account #:nodoc: all
|
47
|
+
|
48
|
+
def self.extended(base)
|
49
|
+
return unless base.is_a?(Hash)
|
50
|
+
base['balance'] = base['balance'].to_f if base['balance']
|
51
|
+
end
|
52
|
+
|
53
|
+
def balance
|
54
|
+
self['balance']
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
module Send #:nodoc: all
|
59
|
+
|
60
|
+
def self.extended(base)
|
61
|
+
return unless base.is_a?(Hash)
|
62
|
+
base['message_id_hash'] = base.delete('message_id').invert if base['message_id']
|
63
|
+
base['message_ids'] = base['message_id_hash'].values.sort if base['message_id_hash']
|
64
|
+
end
|
65
|
+
|
66
|
+
%w(message_id_hash message_ids sent_text parts_count).each do |method|
|
67
|
+
module_eval <<-EOS
|
68
|
+
def #{method}
|
69
|
+
self['#{method}']
|
70
|
+
end
|
71
|
+
EOS
|
72
|
+
end
|
73
|
+
|
74
|
+
def message_id(phone = nil)
|
75
|
+
phone ? message_id_hash[phone] : message_ids.first
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
module MessageStatus #:nodoc: all
|
80
|
+
|
81
|
+
def self.extended(base)
|
82
|
+
return unless base.is_a?(Hash)
|
83
|
+
base.values.each do |status|
|
84
|
+
status['credits_cost'] = status['credits_cost'].to_f if status['credits_cost']
|
85
|
+
status['created_time'] = Time.at(status['created_time'].to_i) if status['created_time']
|
86
|
+
status['completed_time'] = Time.at(status['completed_time'].to_i) if status['completed_time']
|
87
|
+
status.extend Status
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
module Status
|
92
|
+
|
93
|
+
%w(text status reply_number credits_cost created_time completed_time).each do |method|
|
94
|
+
module_eval <<-EOS
|
95
|
+
def #{method}
|
96
|
+
self['#{method}']
|
97
|
+
end
|
98
|
+
EOS
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
module Receive #:nodoc: all
|
104
|
+
|
105
|
+
def self.extended(base)
|
106
|
+
return unless base.is_a?(Hash) && base['messages']
|
107
|
+
base['messages'].each do |message|
|
108
|
+
message['timestamp'] = Time.at(message['timestamp'].to_i) if message['timestamp']
|
109
|
+
message.extend Message
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
%w(messages unread).each do |method|
|
114
|
+
module_eval <<-EOS, __FILE__, __LINE__ + 1
|
115
|
+
def #{method}
|
116
|
+
self['#{method}']
|
117
|
+
end
|
118
|
+
EOS
|
119
|
+
end
|
120
|
+
|
121
|
+
module Message
|
122
|
+
|
123
|
+
%w(message_id timestamp text from).each do |method|
|
124
|
+
module_eval <<-EOS
|
125
|
+
def #{method}
|
126
|
+
self['#{method}']
|
127
|
+
end
|
128
|
+
EOS
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
module DeleteReply #:nodoc: all
|
134
|
+
|
135
|
+
def deleted
|
136
|
+
self['deleted']
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|