rumeme 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +12 -0
- data/Rakefile +4 -4
- data/lib/rumeme/configuration.rb +8 -2
- data/lib/rumeme/sms_interface.rb +84 -162
- data/lib/rumeme/version.rb +1 -1
- metadata +2 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
Version 0.1.3 - 2010-03-11
|
2
|
+
===============================================================================
|
3
|
+
|
4
|
+
antlypls (5):
|
5
|
+
fix rake file
|
6
|
+
change long messages settings
|
7
|
+
minor code cleanup
|
8
|
+
refactor internals
|
9
|
+
code cleanup
|
10
|
+
|
11
|
+
|
1
12
|
Version 0.1.2 - 2010-03-11
|
2
13
|
===============================================================================
|
3
14
|
|
@@ -21,3 +32,4 @@ antlypls (5):
|
|
21
32
|
|
22
33
|
|
23
34
|
|
35
|
+
|
data/Rakefile
CHANGED
@@ -132,12 +132,12 @@ task :push_gem do
|
|
132
132
|
system "gem push pkg/#{gemspec.name}-#{gemspec.version}.gem"
|
133
133
|
end
|
134
134
|
|
135
|
-
desc 'release
|
136
|
-
task :
|
135
|
+
desc 'Preparing release'
|
136
|
+
task :prepare_release, :part do |t, args|
|
137
137
|
Rake::Task['bump'].invoke(args[:part])
|
138
138
|
Rake::Task['change'].invoke
|
139
139
|
Rake::Task['push'].invoke
|
140
|
-
Rake::Task['gem'].invoke
|
141
|
-
Rake::Task['push_gem'].invoke
|
142
140
|
end
|
143
141
|
|
142
|
+
desc 'Building and publishing gem'
|
143
|
+
task :publish_release => [:gem, :push_gem]
|
data/lib/rumeme/configuration.rb
CHANGED
@@ -1,11 +1,17 @@
|
|
1
1
|
module Rumeme
|
2
|
+
# Holds configuration attributes for sms interface
|
2
3
|
class Configuration
|
3
4
|
attr_accessor :username
|
4
5
|
attr_accessor :password
|
5
6
|
attr_accessor :use_message_id
|
6
7
|
attr_accessor :secure
|
7
|
-
|
8
|
-
|
8
|
+
|
9
|
+
#
|
10
|
+
# possible values
|
11
|
+
# :send - sends messages as is without any modification
|
12
|
+
# :split - splits messages into small (less than 160 ch) messages
|
13
|
+
# :cut - sends only first 160 symbols
|
14
|
+
attr_accessor :long_messages_strategy
|
9
15
|
end
|
10
16
|
end
|
11
17
|
|
data/lib/rumeme/sms_interface.rb
CHANGED
@@ -7,6 +7,7 @@ module Rumeme
|
|
7
7
|
|
8
8
|
# This is the main class used to interface with the M4U SMS messaging server.
|
9
9
|
class SmsInterface
|
10
|
+
|
10
11
|
# allow_splitting, allow_long_messages, response_code, response_message, username, password, use_message_id, secure, http_connection, server_list, message_list,
|
11
12
|
# http_proxy, http_proxy_port, http_proxy_auth, https_proxy, https_proxy_port, https_proxy_auth, text_buffer,
|
12
13
|
|
@@ -18,24 +19,21 @@ module Rumeme
|
|
18
19
|
# The allowLongMessages parameter enables messages longer than 160
|
19
20
|
# characters to be sent as special concatenated messages. For this
|
20
21
|
# to take effect, the allowSplitting parameter must be set to false.
|
21
|
-
|
22
22
|
def initialize
|
23
23
|
@username = Rumeme.configuration.username
|
24
24
|
@password = Rumeme.configuration.password
|
25
25
|
@use_message_id = Rumeme.configuration.use_message_id
|
26
26
|
@secure = Rumeme.configuration.secure
|
27
|
+
@long_messages_strategy = Rumeme.configuration.long_messages_strategy
|
27
28
|
|
28
|
-
@allow_splitting, @allow_long_messages = Rumeme.configuration.allow_splitting, Rumeme.configuration.allow_long_messages
|
29
|
-
|
30
29
|
@response_code = -1
|
31
30
|
@response_message = nil
|
32
31
|
@message_list = []
|
33
|
-
@http_connection = nil
|
34
32
|
@http_proxy = nil
|
35
33
|
@http_proxy_port = 80
|
36
34
|
@http_proxy_auth = nil
|
37
35
|
@https_proxy = nil
|
38
|
-
@https_proxy_port = 443
|
36
|
+
@https_proxy_port = 443
|
39
37
|
@https_proxy_auth = nil
|
40
38
|
@text_buffer = nil
|
41
39
|
@server_list = ["smsmaster.m4u.com.au", "smsmaster1.m4u.com.au", "smsmaster2.m4u.com.au"]
|
@@ -61,67 +59,16 @@ module Rumeme
|
|
61
59
|
raise 'proxy is not supported'
|
62
60
|
end
|
63
61
|
|
64
|
-
# Return the response code received from calls to
|
65
|
-
# changePassword, getCreditsRemaining, sendMessages, and
|
66
|
-
# checkReplies.
|
67
|
-
attr_reader :response_code
|
68
|
-
|
69
|
-
# Return the message that was returned with the response code.
|
70
|
-
attr_reader :response_message
|
71
|
-
|
72
62
|
# Add a message to be sent.
|
73
|
-
def
|
74
|
-
p 'in
|
63
|
+
def add_message args
|
64
|
+
p 'in add_message '
|
75
65
|
args[:phone_number] = strip_invalid(args[:phone_number]) #not good idea, modifying original args, from outer scope (antlypls)
|
76
66
|
|
77
67
|
raise ArgumentError.new("phone_number is empty") if args[:phone_number].nil? || args[:phone_number].empty?
|
78
68
|
raise ArgumentError.new("message is empty") if args[:message].nil? || args[:message].empty?
|
79
69
|
|
80
|
-
|
81
|
-
|
82
|
-
return
|
83
|
-
end
|
84
|
-
|
85
|
-
if (@allow_long_messages) # Use concatenation.
|
86
|
-
args[:message] = args[:message][0..1071] # 1071??? WTF ??? see php code (antlypls)
|
87
|
-
@message_list << SmsMessage.new(args)
|
88
|
-
return
|
89
|
-
end
|
90
|
-
|
91
|
-
if !@allow_splitting
|
92
|
-
args[:message] = args[:message][0..160] # maybe 159 ? (antlypls)
|
93
|
-
@message_list << SmsMessage.new(args)
|
94
|
-
return
|
95
|
-
end
|
96
|
-
|
97
|
-
ml = []
|
98
|
-
maxlen = 152
|
99
|
-
message_text = args[:message]
|
100
|
-
while message_text.length > maxlen
|
101
|
-
if (pos = message_text[0..maxlen].rindex(" ")) == 0
|
102
|
-
pos = maxlen - 1
|
103
|
-
end
|
104
|
-
|
105
|
-
ml << message_text[0..pos+1]
|
106
|
-
message_text = message_text[pos + 1 .. -1]
|
107
|
-
maxlen = 147;
|
108
|
-
end
|
109
|
-
ml << message_text
|
110
|
-
|
111
|
-
ml.each_index {|i|
|
112
|
-
ni = i + 1
|
113
|
-
if (i == 0)
|
114
|
-
m = ml[i]
|
115
|
-
else
|
116
|
-
m = "(#{ni}/#{ml.size})#{ml[i]}"
|
117
|
-
end
|
118
|
-
|
119
|
-
if (ni != ml.size )
|
120
|
-
m << "...(#{ni}/#{ml.size})"
|
121
|
-
end
|
122
|
-
|
123
|
-
@message_list << SmsMessage.new(args.merge({:message => m, :delay => args[:delay] + 30*i}))
|
124
|
-
}
|
70
|
+
messages = process_long_message(args[:message])
|
71
|
+
@message_list.concat(messages.map{|m| SmsMessage.new(args.merge({:message => m}))})
|
125
72
|
end
|
126
73
|
|
127
74
|
# Clear all the messages from the list.
|
@@ -129,26 +76,13 @@ module Rumeme
|
|
129
76
|
@message_list.clear
|
130
77
|
end
|
131
78
|
|
132
|
-
# Open a connection to the specified server.
|
133
|
-
# proxy is not supported
|
134
79
|
def open_server_connection server, secure
|
135
|
-
|
136
|
-
if secure
|
137
|
-
@http_connection = Net::HTTP.new(server, 443)
|
138
|
-
@http_connection.use_ssl = true
|
139
|
-
|
140
|
-
else
|
141
|
-
@http_connection = Net::HTTP.new(server, 80)
|
142
|
-
end
|
80
|
+
port, use_ssl = secure ? [443, true] : [80, false]
|
143
81
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
# 4 php api compatibility, returns response code from latest http flush
|
150
|
-
def read_response_code
|
151
|
-
@latest_response_code
|
82
|
+
http_connection = Net::HTTP.new(server, port)
|
83
|
+
http_connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
84
|
+
http_connection.use_ssl = use_ssl
|
85
|
+
http_connection
|
152
86
|
end
|
153
87
|
|
154
88
|
# Change the password on the local machine and server.
|
@@ -159,60 +93,31 @@ module Rumeme
|
|
159
93
|
|
160
94
|
# Return the list of replies we have received.
|
161
95
|
def check_replies auto_confirm = true
|
162
|
-
connect
|
163
96
|
p 'in check_replies'
|
164
|
-
return nil if @http_connection.nil?
|
165
|
-
@text_buffer << "CHECKREPLY2.0\r\n.\r\n"
|
166
|
-
|
167
|
-
if (!flush_buffer || read_response_code != 150)
|
168
|
-
close
|
169
|
-
return nil
|
170
|
-
end
|
171
97
|
|
172
|
-
|
98
|
+
response_message, response_code = post_data_to_server("CHECKREPLY2.0\r\n.\r\n")
|
99
|
+
return if response_code != 150
|
173
100
|
|
174
|
-
messages =
|
175
|
-
|
176
|
-
close
|
177
|
-
|
178
|
-
if auto_confirm && messages.size > 0
|
179
|
-
confirm_replies_received
|
180
|
-
end
|
101
|
+
messages = response_message.split("\r\n")[1..-2].map{|message_line| SmsReply.parse(message_line, @use_message_id)}
|
102
|
+
confirm_replies_received if auto_confirm && messages.size > 0
|
181
103
|
|
182
104
|
return messages
|
183
105
|
end
|
184
106
|
|
185
107
|
# sends confirmation to server
|
186
108
|
def confirm_replies_received
|
187
|
-
connect
|
188
109
|
p 'in confirm_replies_received'
|
189
|
-
|
190
|
-
ok = true
|
191
|
-
|
192
|
-
@text_buffer << "CONFIRM_RECEIVED\r\n.\r\n";
|
193
|
-
if !flush_buffer
|
194
|
-
ok = false
|
195
|
-
end
|
196
|
-
|
197
|
-
close
|
198
|
-
p "result: #{ok}"
|
199
|
-
|
200
|
-
return ok;
|
110
|
+
post_data_to_server "CONFIRM_RECEIVED\r\n.\r\n"
|
201
111
|
end
|
202
112
|
|
203
113
|
# Returns the credits remaining (for prepaid users only).
|
204
114
|
def get_credits_remaining
|
205
|
-
|
206
|
-
return -2 if @http_connection.nil?
|
207
|
-
@text_buffer << "MESSAGES\r\n.\r\n"
|
115
|
+
p 'in get_credits_remaining'
|
208
116
|
|
209
|
-
|
210
|
-
close
|
211
|
-
return -2
|
212
|
-
end
|
117
|
+
response_message, response_code = post_data_to_server("MESSAGES\r\n.\r\n")
|
213
118
|
|
214
119
|
if response_message =~ /^(\d+)\s+OK\s+(\d+).+/
|
215
|
-
if
|
120
|
+
if response_code != 100
|
216
121
|
p 'M4U code is not 100'
|
217
122
|
return -1
|
218
123
|
end
|
@@ -226,70 +131,90 @@ module Rumeme
|
|
226
131
|
# Sends all the messages that have been added with the
|
227
132
|
# add_message command.
|
228
133
|
def send_messages
|
229
|
-
|
230
|
-
return false if @http_connection.nil?
|
231
|
-
@text_buffer << "MESSAGES2.0\r\n"
|
134
|
+
text_buffer = "MESSAGES2.0\r\n"
|
232
135
|
|
233
136
|
@message_list.each {|sm|
|
234
137
|
s = "#{sm.message_id} #{sm.phone_number} #{sm.delay} #{sm.validity_period} "
|
235
138
|
s << (sm.delivery_report ? "1 " : "0 ")
|
236
|
-
s << "#{sm.message}\r\n"
|
237
|
-
|
139
|
+
s << "#{sm.message}\r\n"
|
140
|
+
text_buffer << s
|
238
141
|
}
|
142
|
+
text_buffer << ".\r\n"
|
239
143
|
|
240
|
-
|
241
|
-
@text_buffer << ".\r\n";
|
242
|
-
if (!flush_buffer || (read_response_code / 100) != 1)
|
243
|
-
ok = false;
|
244
|
-
end
|
144
|
+
response_message, response_code = post_data_to_server(text_buffer)
|
245
145
|
|
246
|
-
|
247
|
-
return ok
|
146
|
+
return response_code == 100 ? true : false
|
248
147
|
end
|
249
148
|
|
250
149
|
private
|
251
150
|
|
151
|
+
def process_long_message message
|
152
|
+
return [message] if message.length <= 160
|
153
|
+
case @long_messages_strategy
|
154
|
+
when :send
|
155
|
+
[message]
|
156
|
+
when :cut
|
157
|
+
[message[0..160]]
|
158
|
+
when :split
|
159
|
+
SmsInterface.split_message message
|
160
|
+
else
|
161
|
+
raise 'unknown long_messages_strategy'
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def self.split_message message
|
166
|
+
messages = split_message_internal message
|
167
|
+
i = 1
|
168
|
+
["#{messages[0]}...(1/#{messages.size})"].concat(messages[1..-1].map {|m| "(#{i+=1}/#{messages.size})#{m}"})
|
169
|
+
end
|
170
|
+
|
171
|
+
def self.split_message_internal message
|
172
|
+
list =[]
|
173
|
+
|
174
|
+
head, message = head_tail_split(message, 152)
|
175
|
+
list << head
|
176
|
+
|
177
|
+
while !message.nil? do
|
178
|
+
head, message = head_tail_split(message, 155)
|
179
|
+
list << head
|
180
|
+
end
|
181
|
+
|
182
|
+
list
|
183
|
+
end
|
184
|
+
|
185
|
+
def self.head_tail_split message, max_len
|
186
|
+
return [message, nil] if message.length < max_len
|
187
|
+
pattern = /\s\.,!;:-\)/
|
188
|
+
index = message[0..max_len].rindex(pattern) || max_len
|
189
|
+
[message[0..index], message[index+1 .. -1]]
|
190
|
+
end
|
191
|
+
|
252
192
|
# Strip invalid characters from the phone number.
|
253
193
|
def strip_invalid phone
|
254
194
|
return if phone.nil?
|
255
195
|
"+#{phone.gsub(/[^0-9]/, '')}"
|
256
196
|
end
|
257
197
|
|
258
|
-
|
259
|
-
|
260
|
-
p 'in connect'
|
261
|
-
return unless @http_connection.nil?
|
262
|
-
|
263
|
-
@server_list.all? {|server| !open_server_connection(server, @secure)} # unusefull code open_server_connection,
|
264
|
-
# does not connect to server, just creates http object,
|
265
|
-
# so we can't check availability of the server at this moment (antlypls)
|
198
|
+
def post_data_to_server data
|
199
|
+
p 'post_data_to_server'
|
266
200
|
|
267
|
-
|
201
|
+
http_connection = open_server_connection(@server_list[0], @secure)
|
268
202
|
|
269
|
-
|
203
|
+
text_buffer = "m4u\r\nUSER=#{@username}"
|
270
204
|
if @use_message_id
|
271
|
-
|
205
|
+
text_buffer << "#"
|
272
206
|
end
|
273
|
-
|
274
|
-
end
|
207
|
+
text_buffer << "\r\nPASSWORD=#{@password}\r\nVER=PHP1.0\r\n"
|
275
208
|
|
276
|
-
|
277
|
-
def close
|
278
|
-
@http_connection = nil unless @http_connection.nil?
|
279
|
-
end
|
209
|
+
text_buffer << data
|
280
210
|
|
281
|
-
|
282
|
-
|
283
|
-
p 'in flush_buffer'
|
284
|
-
p "buffer: #{@text_buffer}"
|
285
|
-
headers = {
|
286
|
-
'Content-Length' => @text_buffer.length.to_s
|
287
|
-
}
|
211
|
+
p "buffer: #{text_buffer}"
|
212
|
+
headers = {'Content-Length' => text_buffer.length.to_s}
|
288
213
|
|
289
214
|
path = '/'
|
290
215
|
|
291
216
|
begin
|
292
|
-
resp, data =
|
217
|
+
resp, data = http_connection.post(path, text_buffer, headers)
|
293
218
|
p resp.inspect
|
294
219
|
p data.inspect
|
295
220
|
rescue
|
@@ -297,28 +222,25 @@ module Rumeme
|
|
297
222
|
return false
|
298
223
|
end
|
299
224
|
|
300
|
-
|
301
225
|
if resp.code.to_i != 200
|
302
226
|
p 'http response code != 200'
|
303
227
|
return false
|
304
228
|
end
|
305
229
|
|
306
|
-
@latest_response_code = @response_code = resp.code.to_i
|
307
|
-
|
308
230
|
doc = Nokogiri::HTML(data)
|
309
231
|
|
310
232
|
return false if doc.xpath('//title').text != "M4U SMSMASTER"
|
311
233
|
|
312
|
-
|
313
|
-
|
314
|
-
|
234
|
+
response_message = doc.xpath('//body').text.strip
|
235
|
+
response_code = nil
|
236
|
+
if response_message =~ /^(\d+)\s+/
|
237
|
+
response_code = $1.to_i
|
315
238
|
end
|
316
239
|
|
317
|
-
p "latest response code: #{
|
318
|
-
p "response #{
|
240
|
+
p "latest response code: #{response_code}"
|
241
|
+
p "response #{response_message }"
|
319
242
|
|
320
|
-
|
321
|
-
return true
|
243
|
+
[response_message, response_code]
|
322
244
|
end
|
323
245
|
end
|
324
246
|
end
|
data/lib/rumeme/version.rb
CHANGED