//使用NodeJs实现微信协议登录
var http = require('http');
var https = require("https");
var crypto = require('crypto');
var fs = require('fs');
var express = require('express');
var iconv = require("iconv-lite");
var bodyParser = require("body-parser");
var app = express();
var request = require('request');
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
function getSubstr(ret,start,end)
{
var deps = ret.indexOf(start)+start.length;
//如果结束字符为空,则取从开始字符到结束字符的所有字符串
if (end == "")
var depe = ret.length;
else
var depe = ret.indexOf(end);
var dep = ret.substr(deps,depe-deps);
return dep;
}
function rand(Min,Max){
var Range = Max - Min;
var Rand = Math.random();
var num = Min + Math.round(Rand * Range); //四舍五入
return num;
}
function getTimeStamps(){
return Date.parse(new Date())/1000;
}
function debug(msg) {
console.log("Console\t" + getTime() + "\t" + msg);
}
function sha1(str) {
var sha1 = crypto.createHash("sha1"); //定义加密方式:md5不可逆,此处的md5可以换成任意hash加密的方法名称;
sha1.update(str);
var res = sha1.digest("hex"); //加密后的值d
return res;
}
function getTime() {
var now = new Date();
var hours = now.getHours();
var minutes = now.getMinutes();
var seconds = now.getSeconds();
if (hours < 10) {
hours = "0" + hours;
}
if (minutes < 10) {
minutes = "0" + minutes;
}
if (seconds < 10) {
seconds = "0" + seconds;
}
return hours + ":" + minutes + ":" + seconds;
}
function randInt(length){
var str = "";
var arr = ['1', '2', '3', '4', '5', '6', '7', '8', '9'];
for(var i=0; i<length; i++){
str += arr[rand(0,arr.length-1)];
}
return str;
}
function randStr(length){
var str = "";
var arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
for(var i=0; i<length; i++){
str += arr[rand(0,arr.length-1)];
}
return str;
}
var BaseRequest={};
var progressWaiting=false,progressListen=false;
var nowUuid;
var Config={};
app.get('/welcome/', function(req, res) {
var param = req.query.id;
BaseRequest.DeviceID="e"+randInt(15);
if(!progressWaiting){
//等待处理结果
var url = "https://login.wx.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_="+getTimeStamps()+rand(100,999);
request(url, function (error, response, body) {
if (!error && response.statusCode == 200) {
var code = getSubstr(body,'window.QRLogin.code = ','; window.QRLogin.uuid');
nowUuid = getSubstr(body,'window.QRLogin.uuid = "','";');
debug("Waiting for scan result");
res.setHeader("Refresh",10);
res.send('<center><img width="200px" src="https://login.weixin.qq.com/qrcode/'+nowUuid+'"/><br>请在10s内扫描</center>');
res.end();
progressWaiting=true;
}else{
res.end("Error");
}
});
}else{
var isResponsed=false;
var time=getTimeStamps();
var checkTime=~time;
url="https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid="+nowUuid+"&tip=1&r="+checkTime+"&_="+time;
request(url, function (error, response, body) {
if (!error && response.statusCode == 200) {
isResponsed=true;
var code = getSubstr(body,'window.code=',';');
switch (code){
case "200":
url=getSubstr(body,'window.redirect_uri="','";');
url+="&fun=new&version=v2";
request(url, function (error, response, body) {
if (!error && response.statusCode == 200) {
BaseRequest.skey=getSubstr(body,'<skey>','</skey>');
BaseRequest.Sid=getSubstr(body,'<wxsid>','</wxsid>');
BaseRequest.Uin=getSubstr(body,'<wxuin>','</wxuin>');
BaseRequest.pass_ticket=getSubstr(body,'<pass_ticket>','</pass_ticket>');
var cookieArr=response.headers['set-cookie'];
Config.cookie="";
cookieArr.forEach(function (cookie){
var c=getSubstr(cookie,"",'; Domain');
Config.cookie+=c+"; ";
});
debug("Wechat login success!");
res.end();
url = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r="+(~getTimeStamps())+"&pass_ticket="+BaseRequest.pass_ticket;
request({
url: url,
method: "POST",
json: false,
headers: {
"content-type": "application/json",
},
body: JSON.stringify({"BaseRequest":BaseRequest})
},
function(error, response, body) {
if (!error && response.statusCode == 200) {
body=JSON.parse(body);
Config.myinfo=body.User;
Config.last=body.SyncKey;
debug("Listen wechat message...");
//Now start listen wechat message
if(!progressListen){
//if not listenning...
msgloop();
progressListen=true;
}
}else{
debug("Listen wechat message error");
}
});
}else{
debug("Wechat login error!");
}
});
break;
case "201":
res.setHeader("Refresh",1);
res.end("Please confirm the login request!");
debug("Please confirm the request of login");
break;
case "408":
progressWaiting=false;
debug("Login timeout and refresh please");
break;
default:
res.setHeader("Refresh",1);
res.end();
progressWaiting=false;
console.log(body);
}
}else{
progressWaiting=false;
debug("Error with "+response.statusCode);
}
});
setTimeout(function() {
if(!isResponsed){
progressWaiting=false;
res.setHeader("Refresh",1);
res.end();
}
}, 3000);
}
});
function msgloop(){
debug("Getting Message...");
url = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid="+BaseRequest.Sid+"&skey="+BaseRequest.skey+"&lang=zh_CN&pass_ticket="+BaseRequest.pass_ticket;
request({
url: url,
method: "POST",
json: false,
headers: {
"content-type": "application/json",
},
body: JSON.stringify({"BaseRequest":BaseRequest,"SyncKey":Config.last,"rr":(~getTimeStamps())})
},
function(error, response, body) {
if (!error && response.statusCode == 200) {
body=JSON.parse(body);
//console.log(body);
Config.last=body.SyncKey;
body.AddMsgList.forEach(function (msg){
console.log("MSG from "+msg.FromUserName+" : "+msg.Content);
var fromType=msg.FromUserName.substring(0,2);
if(fromType=="@@"){
//群消息
debug("Msg From Group : "+msg.Content);
responseMsg(msg.FromUserName,"[自动回复]:"+msg.Content);
}else{
fromType=msg.FromUserName.substring(0,1);
if(fromType=="@"){
//个人消息
debug("Msg From Person : "+msg.Content);
responseMsg(msg.FromUserName,"[自动回复]:"+msg.Content);
}else{
//公众号消息
debug("Msg From MpAccount : "+msg.Content);
}
}
});
}
setTimeout(function(){
msgloop();
},rand(1000,5000));
});
}
function responseMsg(FromUserName,Content){
var url="https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?lang=zh_CN&pass_ticket="+BaseRequest.pass_ticket;
var localId=(getTimeStamps()+rand(100,999));
request({
url: url,
method: "POST",
json: false,
headers: {
"content-type": "application/json",
},
body: JSON.stringify({"BaseRequest":BaseRequest,"Msg":{
"ClientMsgId":localId,
"Content":Content,
"FromUserName":Config.myinfo.UserName,
"LocalID":localId,
"ToUserName":FromUserName,
"Type":1
},"Scene":0})
},
function(error, response, body) {
debug("Message response success!");
});
}
app.get('/*', function(req, res) {
var params = req.originalUrl;
res.send("<center><h1>808 Not Found</h1><hr>Nginx&Node</center>");
});
var server = app.listen(10002, function() {
//var host = server.address().address
//var port = server.address().port
debug("Server running...");
});