flyerhzm-rfetion 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.textile ADDED
@@ -0,0 +1,26 @@
1
+ h1. rfetion
2
+
3
+ rfetion is a ruby gem for China Mobile fetion service that you can send SMS free.
4
+
5
+ **************************************************************************
6
+
7
+ h2. Install
8
+
9
+ <pre><code>
10
+ gem sources -a http://gems.github.com
11
+ gem install flyerhzm-rfetion
12
+ </code></pre>
13
+
14
+ **************************************************************************
15
+
16
+ h2. Usage
17
+
18
+ send sms to yourself
19
+ <pre><code>
20
+ Fetion.send_sms_to_self(mobile_no, password, content)
21
+ </code></pre>
22
+
23
+ send sms to friends
24
+ <pre><code>
25
+ Fetion.send_sms_to_friends(mobile_no, password, friend_mobile_no or array of friends_mobile_no, content)
26
+ </code></pre>
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'jeweler'
2
+
3
+ Jeweler::Tasks.new do |gemspec|
4
+ gemspec.name = 'rfetion'
5
+ gemspec.summary = 'rfetion is a ruby gem for China Mobile fetion service that you can send SMS free.'
6
+ gemspec.description = 'rfetion is a ruby gem for China Mobile fetion service that you can send SMS free.'
7
+ gemspec.email = 'flyerhzm@gmail.com'
8
+ gemspec.homepage = ''
9
+ gemspec.authors = ['Richard Huang']
10
+ gemspec.files.exclude '.gitignore'
11
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,216 @@
1
+ class FetionException < Exception
2
+ end
3
+
4
+ class Fetion
5
+ attr_accessor :mobile_no, :password
6
+ attr_reader :uri, :contacts
7
+
8
+ FETION_URL = 'http://221.130.44.194/ht/sd.aspx'
9
+ FETION_LOGIN_URL = 'https://nav.fetion.com.cn/ssiportal/SSIAppSignIn.aspx'
10
+ FETION_CONFIG_URL = 'http://nav.fetion.com.cn/nav/getsystemconfig.aspx'
11
+ FETION_SIPP = 'SIPP'
12
+ GUID = UUID.new.generate
13
+
14
+ def initialize
15
+ @next_call = 0
16
+ @seq = 0
17
+ @buddies = []
18
+ @contacts = []
19
+ @logger = Logger.new(STDOUT)
20
+ @logger.level = Logger::INFO
21
+ end
22
+
23
+ def logger_level=(level)
24
+ @logger.level = level
25
+ end
26
+
27
+ def Fetion.send_sms_to_self(mobile_no, password, content)
28
+ fetion = Fetion.new
29
+ fetion.mobile_no = mobile_no
30
+ fetion.password = password
31
+ fetion.login
32
+ fetion.register
33
+ fetion.send_sms(fetion.uri, content)
34
+ end
35
+
36
+ def Fetion.send_sms_to_friends(mobile_no, password, friend_mobiles, content)
37
+ friend_mobiles = Array(friend_mobiles)
38
+ fetion = Fetion.new
39
+ fetion.mobile_no = mobile_no
40
+ fetion.password = password
41
+ fetion.login
42
+ fetion.register
43
+ fetion.get_buddy_list
44
+ fetion.get_contacts_info
45
+ fetion.contacts.each do |contact|
46
+ if friend_mobiles.include? contact[:mobile_no].to_i
47
+ fetion.send_sms(contact[:sip], content)
48
+ end
49
+ end
50
+ end
51
+
52
+ def login
53
+ @logger.info "fetion login"
54
+ uri = URI.parse(FETION_LOGIN_URL + "?mobileno=#{@mobile_no}&pwd=#{@password}")
55
+ http = Net::HTTP.new(uri.host, uri.port)
56
+ http.use_ssl = true
57
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
58
+ headers = {'Content-Type' => 'application/oct-stream', 'Pragma' => "xz4BBcV#{GUID}", 'User-Agent' => 'IIC2.0/PC 3.2.0540'}
59
+ response = http.request_get(uri.request_uri, headers)
60
+
61
+ raise FetionException.new('Fetion Error: Login failed.') unless response.is_a? Net::HTTPSuccess
62
+ raise FetionException.new('Fetion Error: No ssic found in cookie.') unless response['set-cookie'] =~ /ssic=(.*);/
63
+
64
+ @ssic = $1
65
+ doc = REXML::Document.new(response.body)
66
+ results = doc.root
67
+ @status_code = results.attributes["status-code"]
68
+ user = results.children.first
69
+ @user_status = user.attributes['user-status']
70
+ @uri = user.attributes['uri']
71
+ @mobile_no = user.attributes['mobile-no']
72
+ @user_id = user.attributes['user-id']
73
+ if @uri =~ /sip:(\d+)@(.+);/
74
+ @sid = $1
75
+ @domain = $2
76
+ end
77
+ @logger.debug "ssic: " + @ssic
78
+ @logger.debug "status_code: " + @status_code
79
+ @logger.debug "user_status: " + @user_status
80
+ @logger.debug "uri: " + @uri
81
+ @logger.debug "mobile_no: " + @mobile_no
82
+ @logger.debug "user_id: " + @user_id
83
+ @logger.debug "sid: " + @sid
84
+ @logger.debug "domain: " + @domain
85
+ @logger.info "fetion login success"
86
+ end
87
+
88
+ def register
89
+ @logger.info "fetion http register"
90
+ arg = '<args><device type="PC" version="44" client-version="3.2.0540" /><caps value="simple-im;im-session;temp-group;personal-group" /><events value="contact;permission;system-message;personal-group" /><user-info attributes="all" /><presence><basic value="400" desc="" /></presence></args>'
91
+
92
+ call = next_call
93
+ curl_exec(next_url, @ssic, FETION_SIPP)
94
+
95
+ msg = sip_create("R fetion.com.cn SIP-C/2.0", {'F' => @sid, 'I' => call, 'Q' => '1 R'}, arg) + FETION_SIPP
96
+ curl_exec(next_url('i'), @ssic, msg)
97
+
98
+ response = curl_exec(next_url, @ssic, FETION_SIPP)
99
+ raise FetionException.new("Fetion Error: no nonce found") unless response.body =~ /nonce="(\w+)"/
100
+
101
+ @nonce = $1
102
+ @salt = "777A6D03"
103
+ @cnonce = calc_cnonce
104
+ @response = calc_response
105
+
106
+ @logger.debug "nonce: #{@nonce}"
107
+ @logger.debug "salt: #{@salt}"
108
+ @logger.debug "cnonce: #{@cnonce}"
109
+ @logger.debug "response: #{@response}"
110
+
111
+ msg = sip_create('R fetion.com.cn SIP-C/2.0', {'F' => @sid, 'I' => call, 'Q' => '2 R', 'A' => "Digest algorithm=\"SHA1-sess\",response=\"#{@response}\",cnonce=\"#{@cnonce}\",salt=\"#{@salt}\""}, arg) + FETION_SIPP
112
+ curl_exec(next_url, @ssic, msg)
113
+ response = curl_exec(next_url, @ssic, FETION_SIPP)
114
+
115
+ @logger.info "fetion http register success"
116
+ response.is_a? Net::HTTPSuccess
117
+ end
118
+
119
+ def get_buddy_list
120
+ @logger.info "fetion get buddy list"
121
+ arg = '<args><contacts><buddy-lists /><buddies attributes="all" /><mobile-buddies attributes="all" /><chat-friends /><blacklist /></contacts></args>'
122
+ msg = sip_create('S fetion.com.cn SIP-C/2.0', {'F' => @sid, 'I' => next_call, 'Q' => '1 S', 'N' => 'GetContactList'}, arg) + FETION_SIPP
123
+ curl_exec(next_url, @ssic, msg)
124
+ response = curl_exec(next_url, @ssic, FETION_SIPP)
125
+ raise FetionException.new("Fetion Error: No buddy list found") unless response.body =~ /.*?\r\n\r\n(.*)#{FETION_SIPP}\s*$/i
126
+
127
+ response.body.scan(/uri="([^"]+)"/).each do |buddy|
128
+ @buddies << {:uri => buddy[0]}
129
+ end
130
+ @logger.debug @buddies.inspect
131
+ @logger.info "fetion get buddy list success"
132
+ end
133
+
134
+ def get_contacts_info
135
+ @logger.info "fetion get contacts info"
136
+ arg = '<args><contacts attributes="all">'
137
+ @buddies.each do |buddy|
138
+ arg += "<contact uri=\"#{buddy[:uri]}\" />"
139
+ end
140
+ arg += '</contacts></args>'
141
+
142
+ msg = sip_create('S fetion.com.cn SIP-C/2.0', {'F' => @sid, 'I' => next_call, 'Q' => '1 S', 'N' => 'GetContactsInfo'}, arg) + FETION_SIPP
143
+ curl_exec(next_url, @ssic, msg)
144
+ response = curl_exec(next_url, @ssic, FETION_SIPP)
145
+ response.body.scan(/uri="([^"]+)".*?mobile-no="([^"]+)"/).each do |contact|
146
+ @contacts << {:sip => contact[0], :mobile_no => contact[1]}
147
+ end
148
+ @logger.debug @contacts.inspect
149
+ @logger.info "fetion get contacts info success"
150
+ end
151
+
152
+ def send_sms(to, content)
153
+ @logger.info "fetion send sms to #{to}"
154
+ msg = sip_create('M fetion.com.cn SIP-C/2.0', {'F' => @sid, 'I' => next_call, 'Q' => '1 M', 'T' => to, 'N' => 'SendSMS'}, content) + FETION_SIPP
155
+ curl_exec(next_url, @ssic, msg)
156
+
157
+ response = curl_exec(next_url, @ssic, FETION_SIPP)
158
+ @logger.info "fetion send sms to #{to} success"
159
+ response.is_a? Net::HTTPSuccess
160
+ end
161
+
162
+ def curl_exec(url, ssic, body)
163
+ @logger.debug "fetion curl exec"
164
+ @logger.debug "url: #{url}"
165
+ @logger.debug "ssic: #{ssic}"
166
+ @logger.debug "body: #{body}"
167
+ uri = URI.parse(url)
168
+ http = Net::HTTP.new(uri.host, uri.port)
169
+ headers = {'Content-Type' => 'application/oct-stream', 'Pragma' => "xz4BBcV#{GUID}", 'User-Agent' => 'IIC2.0/PC 3.2.0540', 'Cookie' => "ssic=#{@ssic}"}
170
+ response = http.request_post(uri.request_uri, body, headers)
171
+
172
+ @logger.debug "response: #{response.inspect}"
173
+ @logger.debug "response body: #{response.body}"
174
+ @logger.debug "fetion curl exec complete"
175
+ response
176
+ end
177
+
178
+ def sip_create(invite, fields, arg)
179
+ sip = invite + "\r\n"
180
+ fields.each {|k, v| sip += "#{k}: #{v}\r\n"}
181
+ sip += "L: #{arg.size}\r\n\r\n#{arg}"
182
+ @logger.debug "sip message: #{sip}"
183
+ sip
184
+ end
185
+
186
+ def calc_response
187
+ str = [hash_password[8..-1]].pack("H*")
188
+ key = Digest::SHA1.digest("#{@sid}:#{@domain}:#{str}")
189
+
190
+ h1 = Digest::MD5.hexdigest("#{key}:#{@nonce}:#{@cnonce}").upcase
191
+ h2 = Digest::MD5.hexdigest("REGISTER:#{@sid}").upcase
192
+
193
+ Digest::MD5.hexdigest("#{h1}:#{@nonce}:#{h2}").upcase
194
+ end
195
+
196
+ def calc_cnonce
197
+ Digest::MD5.hexdigest(UUID.new.generate).upcase
198
+ end
199
+
200
+ def hash_password
201
+ salt = "#{0x77.chr}#{0x7A.chr}#{0x6D.chr}#{0x03.chr}"
202
+ src = salt + Digest::SHA1.digest(@password)
203
+ '777A6D03' + Digest::SHA1.hexdigest(src).upcase
204
+ end
205
+
206
+ def next_url(t = 's')
207
+ @seq += 1
208
+ FETION_URL + "?t=#{t}&i=#{@seq}"
209
+ end
210
+
211
+ def next_call
212
+ @next_call += 1
213
+ @next_call
214
+ end
215
+ end
216
+
data/lib/rfetion.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'uuid'
3
+ require 'net/http'
4
+ require 'net/https'
5
+ require 'rexml/document'
6
+ require 'digest/sha1'
7
+ require 'logger'
8
+ require 'rfetion/fetion'
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flyerhzm-rfetion
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Richard Huang
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-09-17 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: rfetion is a ruby gem for China Mobile fetion service that you can send SMS free.
17
+ email: flyerhzm@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.textile
24
+ files:
25
+ - README.textile
26
+ - Rakefile
27
+ - VERSION
28
+ - lib/rfetion.rb
29
+ - lib/rfetion/fetion.rb
30
+ has_rdoc: false
31
+ homepage: ""
32
+ licenses:
33
+ post_install_message:
34
+ rdoc_options:
35
+ - --charset=UTF-8
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: "0"
43
+ version:
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ version:
50
+ requirements: []
51
+
52
+ rubyforge_project:
53
+ rubygems_version: 1.3.5
54
+ signing_key:
55
+ specification_version: 3
56
+ summary: rfetion is a ruby gem for China Mobile fetion service that you can send SMS free.
57
+ test_files: []
58
+