package me.biezhi.weixin;
import java.awt.EventQueue;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import javax.swing.UIManager;
import blade.kit.DateKit;
import blade.kit.StringKit;
import blade.kit.http.HttpRequest;
import blade.kit.json.JSON;
import blade.kit.json.JSONArray;
import blade.kit.json.JSONObject;
import blade.kit.logging.Logger;
import blade.kit.logging.LoggerFactory;
import me.biezhi.weixin.util.CookieUtil;
import me.biezhi.weixin.util.Matchers;
/**
* Hello world!
*
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
private String uuid;
private int tip = 0;
private String base_uri, redirect_uri, webpush_url = "https://webpush2.weixin.qq.com/cgi-bin/mmwebwx-bin";
private String skey, synckey, wxsid, wxuin, pass_ticket, deviceId = "e" + DateKit.getCurrentUnixTime();
private String cookie;
private QRCodeFrame qrCodeFrame;
private JSONObject SyncKey, User, BaseRequest;
// 微信联系人列表,可聊天的联系人列表
private JSONArray MemberList, ContactList;
// 微信特殊账号
private List<String> SpecialUsers = Arrays.asList("newsapp", "fmessage", "filehelper", "weibo", "qqmail", "fmessage", "tmessage", "qmessage", "qqsync", "floatbottle", "lbsapp", "shakeapp", "medianote", "qqfriend", "readerapp", "blogapp", "facebookapp", "masssendapp", "meishiapp", "feedsapp", "voip", "blogappweixin", "weixin", "brandsessionholder", "weixinreminder", "wxid_novlwrv3lqwv11", "gh_22b87fa7cb3c", "officialaccounts", "notification_messages", "wxid_novlwrv3lqwv11", "gh_22b87fa7cb3c", "wxitil", "userexperience_alarm", "notification_messages");
public App() {
System.setProperty("jsse.enableSNIExtension", "false");
}
/**
* 获取UUID
* @return
*/
public String getUUID() {
String url = "https://login.weixin.qq.com/jslogin";
HttpRequest request = HttpRequest.get(url, true,
"appid", "wx782c26e4c19acffb",
"fun", "new",
"lang", "zh_CN",
"_" , DateKit.getCurrentUnixTime());
LOGGER.info("[*] " + request);
String res = request.body();
request.disconnect();
if(StringKit.isNotBlank(res)){
String code = Matchers.match("window.QRLogin.code = (\\d+);", res);
if(null != code){
if(code.equals("200")){
this.uuid = Matchers.match("window.QRLogin.uuid = \"(.*)\";", res);
return this.uuid;
} else {
LOGGER.info("[*] 错误的状态码: %s", code);
}
}
}
return null;
}
/**
* 显示二维码
* @return
*/
public void showQrCode() {
String url = "https://login.weixin.qq.com/qrcode/" + this.uuid;
final File output = new File("temp.jpg");
HttpRequest.post(url, true,
"t", "webwx",
"_" , DateKit.getCurrentUnixTime())
.receive(output);
if(null != output && output.exists() && output.isFile()){
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
qrCodeFrame = new QRCodeFrame(output.getPath());
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
/**
* 等待登录
*/
public String waitForLogin(){
this.tip = 1;
String url = "https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login";
HttpRequest request = HttpRequest.get(url, true,
"tip", this.tip,
"uuid", this.uuid,
"_" , DateKit.getCurrentUnixTime());
LOGGER.info("[*] " + request.toString());
String res = request.body();
request.disconnect();
if(null == res){
LOGGER.info("[*] 扫描二维码验证失败");
return "";
}
String code = Matchers.match("window.code=(\\d+);", res);
if(null == code){
LOGGER.info("[*] 扫描二维码验证失败");
return "";
} else {
if(code.equals("201")){
LOGGER.info("[*] 成功扫描,请在手机上点击确认以登录");
tip = 0;
} else if(code.equals("200")){
LOGGER.info("[*] 正在登录...");
String pm = Matchers.match("window.redirect_uri=\"(\\S+?)\";", res);
this.redirect_uri = pm + "&fun=new";
LOGGER.info("[*] redirect_uri=%s", this.redirect_uri);
this.base_uri = this.redirect_uri.substring(0, this.redirect_uri.lastIndexOf("/"));
LOGGER.info("[*] base_uri=%s", this.base_uri);
} else if(code.equals("408")){
LOGGER.info("[*] 登录超时");
} else {
LOGGER.info("[*] 扫描code=%s", code);
}
}
return code;
}
private void closeQrWindow() {
qrCodeFrame.dispose();
}
/**
* 登录
*/
public boolean login(){
HttpRequest request = HttpRequest.get(this.redirect_uri);
LOGGER.info("[*] " + request);
String res = request.body();
this.cookie = CookieUtil.getCookie(request);
request.disconnect();
if(StringKit.isBlank(res)){
return false;
}
this.skey = Matchers.match("<skey>(\\S+)</skey>", res);
this.wxsid = Matchers.match("<wxsid>(\\S+)</wxsid>", res);
this.wxuin = Matchers.match("<wxuin>(\\S+)</wxuin>", res);
this.pass_ticket = Matchers.match("<pass_ticket>(\\S+)</pass_ticket>", res);
LOGGER.info("[*] skey[%s]", this.skey);
LOGGER.info("[*] wxsid[%s]", this.wxsid);
LOGGER.info("[*] wxuin[%s]", this.wxuin);
LOGGER.info("[*] pass_ticket[%s]", this.pass_ticket);
this.BaseRequest = new JSONObject();
BaseRequest.put("Uin", this.wxuin);
BaseRequest.put("Sid", this.wxsid);
BaseRequest.put("Skey", this.skey);
BaseRequest.put("DeviceID", this.deviceId);
return true;
}
/**
* 微信初始化
*/
public boolean wxInit(){
String url = this.base_uri + "/webwxinit?r=" + DateKit.getCurrentUnixTime() + "&pass_ticket=" + this.pass_ticket +
"&skey=" + this.skey;
JSONObject body = new JSONObject();
body.put("BaseRequest", this.BaseRequest);
HttpRequest request = HttpRequest.post(url)
.header("Content-Type", "application/json;charset=utf-8")
.header("Cookie", this.cookie)
.send(body.toString());
LOGGER.info("[*] " + request);
String res = request.body();
request.disconnect();
if(StringKit.isBlank(res)){
return false;
}
try {
JSONObject jsonObject = JSON.parse(res).asObject();
if(null != jsonObject){
JSONObject BaseResponse = jsonObject.getJSONObject("BaseResponse");
if(null != BaseResponse){
int ret = BaseResponse.getInt("Ret", -1);
if(ret == 0){
this.SyncKey = jsonObject.getJSONObject("SyncKey");
this.User = jsonObject.getJSONObject("User");
StringBuffer synckey = new StringBuffer();
JSONArray list = SyncKey.getJSONArray("List");
for(int i=0, len=list.size(); i<len; i++){
JSONObject item = list.getJSONObject(i);
synckey.append("|" + item.getInt("Key", 0) + "_" + item.getInt("Val", 0));
}
this.synckey = synckey.substring(1);
return true;
}
}
}
} catch (Exception e) {
}
return false;
}
/**
* 微信状态通知
*/
public boolean wxStatusNotify (){
String url = this.base_uri + "/webwxstatusnotify?lang=zh_CN&pass_ticket=" + this.pass_ticket;
JSONObject body = new JSONObject();
body.put("BaseRequest", BaseRequest);
body.put("Code", 3);
body.put("FromUserName", this.User.getString("UserName"));
body.put("ToUserName", this.User.getString("UserName"));
body.put("ClientMsgId", DateKit.getCurrentUnixTime());
HttpRequest request = HttpRequest.post(url)
.header("Content-Type", "application/json;charset=utf-8")
.header("Cookie", this.cookie)
.send(body.toString());
LOGGER.info("[*] " + request);
String res = request.body();
request.disconnect();
if(StringKit.isBlank(res)){
return false;
}
try {
JSONObject jsonObject = J