textmagic 0.2.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/.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
|