Created
September 30, 2014 04:13
-
-
Save ftiasch/7d2ef15a648b2f0c245c to your computer and use it in GitHub Desktop.
WebQQ robot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
crypto = require 'crypto' | |
request = require 'request' | |
cookieJar = request.jar() | |
request = request.defaults {jar: cookieJar} | |
#require('request').debug = true | |
class Client | |
constructor: (@id, @password) -> | |
check: (callback) -> | |
client = @ | |
request.get {url: 'https://ssl.ptlogin2.qq.com/check', qs: {uin: @id}}, (error, response, body) -> | |
if !error and response.statusCode == 200 | |
console.log body | |
[flag, captcha, bits, _] = body.match(/\'.*?\'/g).map((string) -> string[1..-2]) | |
if flag == '0' | |
client.tryLogin captcha, bits, callback | |
else | |
client.getCaptcha bits, callback | |
else | |
throw [error, response] | |
getCaptcha: (bits, callback) -> | |
client = @ | |
# encoding - Encoding to be used on `setEncoding` of response data. If null, the `body` is returned as a `Buffer`. | |
request.get {url: 'http://captcha.qq.com/getimage', qs: {uin: @id}, encoding: null}, (error, response, body) -> | |
if !error and response.statusCode == 200 | |
(require 'fs').writeFileSync 'captcha.jpg', body, 'binary' | |
myInterface = (require 'readline').createInterface | |
input: process.stdin | |
output: process.stdout | |
myInterface.question 'Enter captcha in `captcha.jpg`: ', (input) -> | |
myInterface.close() | |
client.tryLogin input, bits, callback | |
else | |
throw [error, response] | |
tryLogin: (captcha, bits, callback) -> | |
client = @ | |
encrypt = (password, captcha, bits) -> | |
hex = (string) -> string.match(/\w{2}/g).map((s) -> String.fromCharCode parseInt(s, 16)).join('') | |
md5 = (string) -> crypto.createHash('md5').update(string.toString()).digest('hex') | |
encoding = md5(hex(md5(password)) + hex(bits.replace /\\x/g, '')).toUpperCase() + captcha.toUpperCase() | |
return md5(encoding).toUpperCase() | |
q = | |
u: @id | |
p: encrypt(@password, captcha, bits) | |
u1: 'http://web2.qq.com/loginproxy.html?login2qq=1&webqq_type=10' | |
verifycode: captcha, login2qq: 1, webqq_type: 10, aid: 1003903, h: 1, daid: 164, from_ui: 1, pttype: 1, g: 1 | |
request.get {url: 'https://ssl.ptlogin2.qq.com/login', qs: q}, (error, response, body) -> | |
if !error and response.statusCode == 200 | |
console.log body | |
[_, _, url, _, _, _] = body.match(/\'.*?\'/g).map((string) -> string[1..-2]) | |
client.getCookies url, callback | |
else | |
throw [error, response] | |
getCookies: (url, callback) -> | |
client = @ | |
request.get url, (error, response, body) -> | |
if !error and response.statusCode == 200 | |
client.login callback | |
else | |
throw [error, response] | |
login: (callback) -> | |
client = @ | |
@clientid = 1000000 + parseInt(89999999 * Math.random()) | |
@ptwebqq = cookieJar._jar.store.idx['qq.com']['/'].ptwebqq.value | |
options = | |
url: 'http://d.web2.qq.com/channel/login2' | |
headers: | |
Referer: 'http://d.web2.qq.com/proxy.html?v=20110331002&callback=1&id=3' | |
form: | |
clientid: @clientid | |
r: JSON.stringify | |
status: 'online' | |
ptwebqq: @ptwebqq | |
clientid: @clientid.toString() | |
request.post options, (error, response, body) -> | |
if !error and response.statusCode == 200 | |
r = JSON.parse(body) | |
if r.retcode == 0 | |
r = r.result | |
[client.psessionid, client.uin, client.vfwebqq] = [r.psessionid, r.uin, r.vfwebqq] | |
client.poll callback | |
else | |
throw r | |
else | |
throw [error, response] | |
poll: (callback) -> | |
client = @ | |
options = | |
url: 'http://d.web2.qq.com/channel/poll2' | |
headers: | |
Referer: 'http://d.web2.qq.com/proxy.html?v=20110331002&callback=1&id=3' | |
form: | |
clientid: @clientid | |
psessionid: @psessionid | |
r: JSON.stringify | |
clientid: @clientid.toString() | |
psessionid: @psessionid | |
key: 0, ids: [] | |
request.post options, (error, response, body) -> | |
if !error and response.statusCode == 200 | |
r = JSON.parse(body) | |
if r.retcode == 0 | |
for event in r.result | |
client.handle(event) | |
client.poll callback | |
else | |
throw r | |
else | |
throw [error, response] | |
handle: (event, callback) -> | |
switch event.poll_type | |
when 'buddies_status_change' | |
# ignore | |
else | |
console.error event | |
run = -> | |
client = new Client '', '' | |
client.check() | |
run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment