mirror of
https://gitee.com/hotlcc/wechat4j.git
synced 2025-06-08 03:24:09 +08:00
提交代码
This commit is contained in:
parent
cf4d8a7973
commit
266fda8433
@ -3,7 +3,9 @@ package com.hotlcc.wechat4j;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.hotlcc.wechat4j.api.WebWeixinApi;
|
||||
import com.hotlcc.wechat4j.enums.LoginTipEnum;
|
||||
import com.hotlcc.wechat4j.util.PropertiesUtil;
|
||||
import com.hotlcc.wechat4j.util.QRCodeUtil;
|
||||
import com.hotlcc.wechat4j.util.StringUtil;
|
||||
import org.apache.http.client.CookieStore;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.impl.client.BasicCookieStore;
|
||||
@ -11,6 +13,9 @@ import org.apache.http.impl.client.HttpClients;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
/**
|
||||
* 微信客户端
|
||||
*
|
||||
@ -19,14 +24,18 @@ import org.slf4j.LoggerFactory;
|
||||
public class Wechat {
|
||||
private static Logger logger = LoggerFactory.getLogger(Wechat.class);
|
||||
|
||||
private WebWeixinApi webWeixinApi;
|
||||
|
||||
private CookieStore cookieStore;
|
||||
private HttpClient httpClient;
|
||||
|
||||
private WebWeixinApi webWeixinApi;
|
||||
//在线状态
|
||||
private volatile boolean isOnline = false;
|
||||
|
||||
public void setWebWeixinApi(WebWeixinApi webWeixinApi) {
|
||||
this.webWeixinApi = webWeixinApi;
|
||||
}
|
||||
private volatile String wxsid;
|
||||
private volatile String passTicket;
|
||||
private volatile String skey;
|
||||
private volatile String wxuin;
|
||||
|
||||
public Wechat(CookieStore cookieStore) {
|
||||
this.cookieStore = cookieStore;
|
||||
@ -38,11 +47,290 @@ public class Wechat {
|
||||
this.httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();
|
||||
}
|
||||
|
||||
public void setWebWeixinApi(WebWeixinApi webWeixinApi) {
|
||||
this.webWeixinApi = webWeixinApi;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取uuid
|
||||
*
|
||||
* @param ps
|
||||
* @param time
|
||||
* @return
|
||||
*/
|
||||
private String getWxUuid(PrintStream ps, int time) {
|
||||
ps.print("尝试正常方式获取uuid...");
|
||||
ps.flush();
|
||||
|
||||
for (int i = 0; i <= time; i++) {
|
||||
if (i > 0) {
|
||||
ps.print("\t第" + i + "次尝试...");
|
||||
ps.flush();
|
||||
}
|
||||
JSONObject result = webWeixinApi.getWxUuid(httpClient);
|
||||
|
||||
if (result == null) {
|
||||
ps.println("\t失败:出现异常");
|
||||
ps.flush();
|
||||
return null;
|
||||
}
|
||||
|
||||
String code = result.getString("code");
|
||||
String uuid = result.getString("uuid");
|
||||
if (!"200".equals(code)) {
|
||||
String msg = result.getString("msg");
|
||||
ps.println("\t失败:" + msg);
|
||||
ps.flush();
|
||||
return null;
|
||||
}
|
||||
|
||||
if (StringUtil.isEmpty(uuid)) {
|
||||
ps.print("\t失败");
|
||||
if (i == 0 && time > 0) {
|
||||
ps.print(",将重复尝试" + time + "次");
|
||||
}
|
||||
ps.println();
|
||||
ps.flush();
|
||||
continue;
|
||||
}
|
||||
|
||||
ps.println("\t成功,值为:" + uuid);
|
||||
ps.flush();
|
||||
return uuid;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取并显示qrcode
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private boolean getAndShowQRCode(PrintStream ps, String uuid, int time) {
|
||||
ps.print("获取二维码...");
|
||||
ps.flush();
|
||||
|
||||
for (int i = 0; i <= time; i++) {
|
||||
if (i > 0) {
|
||||
ps.print("\t第" + i + "次尝试...");
|
||||
ps.flush();
|
||||
}
|
||||
|
||||
byte[] data = webWeixinApi.getQR(httpClient, uuid);
|
||||
|
||||
if (data == null || data.length <= 0) {
|
||||
ps.print("\t失败");
|
||||
if (i == 0 && time > 0) {
|
||||
ps.print(",将重新获取uuid并重复尝试" + time + "次");
|
||||
}
|
||||
ps.println();
|
||||
ps.flush();
|
||||
getWxUuid(ps, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
ps.println("\t成功,请扫描二维码:");
|
||||
ps.flush();
|
||||
ps.println(QRCodeUtil.toCharMatrix(data));
|
||||
ps.flush();
|
||||
QRCodeUtil.openQRCodeImage(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 等待手机端确认登录
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String waitForConfirm(PrintStream ps, String uuid) {
|
||||
ps.print("等待手机端扫码...");
|
||||
ps.flush();
|
||||
|
||||
String code = null;
|
||||
boolean flag = false;
|
||||
while (!"200".equals(code)) {
|
||||
JSONObject result = webWeixinApi.getRedirectUri(httpClient, LoginTipEnum.TIP_0, uuid);
|
||||
if (result == null) {
|
||||
ps.println("\t失败:出现异常");
|
||||
ps.flush();
|
||||
return null;
|
||||
}
|
||||
|
||||
code = result.getString("code");
|
||||
if ("408".equals(code)) {
|
||||
ps.print(".");
|
||||
ps.flush();
|
||||
continue;
|
||||
} else if ("400".equals(code)) {
|
||||
ps.println("\t失败,二维码失效");
|
||||
ps.flush();
|
||||
return null;
|
||||
} else if ("201".equals(code)) {
|
||||
if (!flag) {
|
||||
ps.println();
|
||||
ps.print("请确认登录...");
|
||||
ps.flush();
|
||||
flag = true;
|
||||
}
|
||||
continue;
|
||||
} else if ("200".equals(code)) {
|
||||
String redirectUri = result.getString("redirectUri");
|
||||
ps.println("\t成功,认证完成");
|
||||
ps.flush();
|
||||
return redirectUri;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录认证码
|
||||
*/
|
||||
private boolean getLoginCode(PrintStream ps, String redirectUri) {
|
||||
ps.print("获取登录认证码...");
|
||||
ps.flush();
|
||||
|
||||
JSONObject result = webWeixinApi.getLoginCode(httpClient, redirectUri);
|
||||
if (result == null) {
|
||||
ps.println("\t失败:出现异常");
|
||||
ps.flush();
|
||||
return false;
|
||||
}
|
||||
|
||||
String ret = result.getString("ret");
|
||||
if (!"0".equals(ret)) {
|
||||
ps.println("\t失败:错误的返回码(" + ret + ")");
|
||||
ps.flush();
|
||||
return false;
|
||||
}
|
||||
|
||||
wxsid = result.getString("wxsid");
|
||||
passTicket = result.getString("pass_ticket");
|
||||
skey = result.getString("skey");
|
||||
wxuin = result.getString("wxuin");
|
||||
isOnline = true;
|
||||
|
||||
ps.println("\t成功");
|
||||
ps.flush();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* push方式获取uuid
|
||||
*
|
||||
* @param ps
|
||||
* @param wxuin
|
||||
* @return
|
||||
*/
|
||||
private String getWxUuid(PrintStream ps, String wxuin) {
|
||||
ps.print("尝试push方式获取uuid...");
|
||||
ps.flush();
|
||||
|
||||
JSONObject result = webWeixinApi.pushLogin(httpClient, wxuin);
|
||||
if (result == null) {
|
||||
ps.println("\t失败:出现异常");
|
||||
ps.flush();
|
||||
return null;
|
||||
}
|
||||
|
||||
String ret = result.getString("ret");
|
||||
if (!"0".equals(ret)) {
|
||||
ps.println("\t失败:错误的返回码(" + ret + ")");
|
||||
ps.flush();
|
||||
return null;
|
||||
}
|
||||
|
||||
String uuid = result.getString("uuid");
|
||||
if (StringUtil.isEmpty(uuid)) {
|
||||
ps.println("\t失败:空值");
|
||||
ps.flush();
|
||||
return null;
|
||||
}
|
||||
|
||||
ps.println("\t成功,值为:" + uuid);
|
||||
ps.flush();
|
||||
|
||||
return uuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动登录
|
||||
*/
|
||||
public void autoLogin() {
|
||||
public boolean autoLogin(OutputStream os) {
|
||||
// 0、获取消息打印流
|
||||
PrintStream ps = null;
|
||||
if (os != null) {
|
||||
ps = new PrintStream(os);
|
||||
} else {
|
||||
ps = System.out;
|
||||
}
|
||||
|
||||
// 1、判断是否已经登录
|
||||
if (isOnline) {
|
||||
ps.println("当前已是登录状态,无需登录");
|
||||
return true;
|
||||
}
|
||||
|
||||
JSONObject result = null;
|
||||
int time = PropertiesUtil.getIntValue("wechat4j.retry.time", 3);
|
||||
|
||||
// 2、登录
|
||||
// 2.1、获取uuid
|
||||
String uuid = null;
|
||||
if (StringUtil.isNotEmpty(wxuin)) {
|
||||
uuid = getWxUuid(ps, wxuin);
|
||||
}
|
||||
if (StringUtil.isEmpty(uuid)) {
|
||||
uuid = getWxUuid(ps, time);
|
||||
}
|
||||
if (StringUtil.isEmpty(uuid)) {
|
||||
ps.println("无法获取uuid,登录不成功");
|
||||
ps.flush();
|
||||
return false;
|
||||
}
|
||||
// 2.2、获取并显示二维码
|
||||
if (!getAndShowQRCode(ps, uuid, time)) {
|
||||
ps.println("无法获取二维码,登录不成功");
|
||||
ps.flush();
|
||||
return false;
|
||||
}
|
||||
// 2.3、等待确认
|
||||
String redirectUri = waitForConfirm(ps, uuid);
|
||||
if (StringUtil.isEmpty(redirectUri)) {
|
||||
ps.println("手机端认证失败,登录不成功");
|
||||
ps.flush();
|
||||
return false;
|
||||
}
|
||||
// 2.4、获取登录认证码
|
||||
if (!getLoginCode(ps, redirectUri)) {
|
||||
ps.println("无法获取登录认证码,登录不成功");
|
||||
ps.flush();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动登录
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean autoLogin() {
|
||||
return autoLogin(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
*/
|
||||
public void logout() {
|
||||
webWeixinApi.logout(httpClient, wxsid, skey, wxuin);
|
||||
}
|
||||
|
||||
public void test() {
|
||||
@ -116,9 +404,9 @@ public class Wechat {
|
||||
JSONObject SyncKey = result.getJSONObject("SyncKey");
|
||||
logger.info("初始化数据完成");
|
||||
//6、开启消息状态通知
|
||||
logger.info("开始开启消息状态通知");
|
||||
result = webWeixinApi.statusNotify(httpClient, passTicket, wxsid, skey, wxuin, loginUser.getString("UserName"));
|
||||
logger.info("开启消息状态通知完成");
|
||||
// logger.info("开始开启消息状态通知");
|
||||
// result = webWeixinApi.statusNotify(httpClient, passTicket, wxsid, skey, wxuin, loginUser.getString("UserName"));
|
||||
// logger.info("开启消息状态通知完成");
|
||||
//7、获取联系人信息
|
||||
// logger.info("开始获取全部联系人");
|
||||
// result = webWeixinApi.getContact(httpClient, passTicket, wxsid);
|
||||
@ -127,7 +415,17 @@ public class Wechat {
|
||||
// System.out.println("昵称\t备注名\tUserName");
|
||||
// for (int i = 0, len = MemberList.size(); i < len; i++) {
|
||||
// JSONObject Member = MemberList.getJSONObject(i);
|
||||
// System.out.println(Member.getString("NickName") + "\t" + Member.getString("RemarkName") + "\t" + Member.getString("UserName"));
|
||||
// if ("BYCX-IT".equals(Member.getString("NickName"))) {
|
||||
// System.out.println(Member);
|
||||
// JSONArray params = new JSONArray();
|
||||
// JSONObject param = new JSONObject();
|
||||
// param.put("EncryChatRoomId", "");
|
||||
// param.put("UserName", Member.getString("UserName"));
|
||||
// params.add(param);
|
||||
// result = webWeixinApi.batchGetContact(httpClient, passTicket, wxsid, skey, wxuin, params);
|
||||
// System.out.println(result);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// logger.info("获取全部联系人完成,共{}条", MemberList.size());
|
||||
//7、服务端状态同步
|
||||
@ -163,11 +461,11 @@ public class Wechat {
|
||||
// }
|
||||
// }
|
||||
//测试给特定联系人发送文本信息
|
||||
result = webWeixinApi.sendMsg(httpClient, passTicket, wxsid, skey, wxuin,
|
||||
"测试消息",
|
||||
1,
|
||||
loginUser.getString("UserName"),
|
||||
"@493f6dbadb4ed2f471b8098fd7f6db1bbcc7294e829e8ecbdc6d2b32647bc2d2");
|
||||
System.out.println(result);
|
||||
// result = webWeixinApi.sendMsg(httpClient, passTicket, wxsid, skey, wxuin,
|
||||
// "测试消息",
|
||||
// 1,
|
||||
// loginUser.getString("UserName"),
|
||||
// "@493f6dbadb4ed2f471b8098fd7f6db1bbcc7294e829e8ecbdc6d2b32647bc2d2");
|
||||
// System.out.println(result);
|
||||
}
|
||||
}
|
||||
|
@ -258,6 +258,37 @@ public class WebWeixinApi {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* push登录
|
||||
*/
|
||||
public JSONObject pushLogin(HttpClient httpClient,
|
||||
String wxuin) {
|
||||
try {
|
||||
long millis = System.currentTimeMillis();
|
||||
String url = new ST(PropertiesUtil.getProperty("webwx-url.pushlogin_url"))
|
||||
.add("uin", wxuin)
|
||||
.render();
|
||||
|
||||
HttpGet httpGet = new HttpGet(url);
|
||||
httpGet.setHeader("User-Agent", PropertiesUtil.getProperty("wechat4j.userAgent"));
|
||||
httpGet.setConfig(RequestConfig.custom().setRedirectsEnabled(false).build());
|
||||
|
||||
HttpResponse response = httpClient.execute(httpGet);
|
||||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
if (HttpStatus.SC_OK != statusCode) {
|
||||
throw new RuntimeException("响应失败(" + statusCode + ")");
|
||||
}
|
||||
|
||||
HttpEntity entity = response.getEntity();
|
||||
String res = EntityUtils.toString(entity, Consts.UTF_8);
|
||||
|
||||
return JSONObject.parseObject(res);
|
||||
} catch (Exception e) {
|
||||
logger.error("push登录异常", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取初始化数据
|
||||
*/
|
||||
|
@ -53,4 +53,28 @@ public final class PropertiesUtil {
|
||||
public static String getProperty(String key, String defaultValue) {
|
||||
return prop.getProperty(key, defaultValue);
|
||||
}
|
||||
|
||||
public static Integer getInteger(String key, Integer defaultValue) {
|
||||
String p = getProperty(key);
|
||||
if (p == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
p.trim();
|
||||
if ("".equals(p)) {
|
||||
return defaultValue;
|
||||
}
|
||||
return Integer.valueOf(p);
|
||||
}
|
||||
|
||||
public static Integer getInteger(String key) {
|
||||
return getInteger(key, null);
|
||||
}
|
||||
|
||||
public static int getIntValue(String key, int defaultValue) {
|
||||
return getInteger(key, defaultValue);
|
||||
}
|
||||
|
||||
public static int getIntValue(String key) {
|
||||
return getInteger(key);
|
||||
}
|
||||
}
|
||||
|
@ -3,4 +3,6 @@ webwx.appid=wx782c26e4c19acffb
|
||||
# httpclient的UserAgent
|
||||
wechat4j.userAgent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
|
||||
# QRCode图片临时文件前缀
|
||||
wechat4j.qrcode.tmpfile.prefix=wechat4j_tmp_
|
||||
wechat4j.qrcode.tmpfile.prefix=wechat4j_tmp_
|
||||
# 全局重试次数
|
||||
wechat4j.retry.time=3
|
@ -9,6 +9,8 @@ webwx-url.redirect_uri=https://login.wx2.qq.com/cgi-bin/mmwebwx-bin/login?logini
|
||||
webwx-url.newlogin_url=<redirectUri>&fun=new&version=v2
|
||||
## 1.5、退出登录
|
||||
webwx-url.logout_url=https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=<type>&skey=<skey>
|
||||
## 1.6、push登录
|
||||
webwx-url.pushlogin_url=https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxpushloginurl?uin=<uin>
|
||||
# 2、数据同步
|
||||
## 2.1、页面初始化
|
||||
webwx-url.webwxinit_url=https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=<r>&lang=zh_CN&pass_ticket=<pass_ticket>
|
||||
|
@ -18,11 +18,18 @@ public class TestClass {
|
||||
System.out.println(QRCodeUtil.toCharMatrix(image));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test04() {
|
||||
WebWeixinApi api = new WebWeixinApi();
|
||||
Wechat wechat = new Wechat();
|
||||
wechat.setWebWeixinApi(api);
|
||||
wechat.test();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test05() {
|
||||
WebWeixinApi api = new WebWeixinApi();
|
||||
Wechat wechat = new Wechat();
|
||||
wechat.setWebWeixinApi(api);
|
||||
System.out.println(wechat.autoLogin());
|
||||
}
|
||||
}
|
||||
|
12
src/test/java/TestClass2.java
Normal file
12
src/test/java/TestClass2.java
Normal file
@ -0,0 +1,12 @@
|
||||
import com.hotlcc.wechat4j.Wechat;
|
||||
import com.hotlcc.wechat4j.api.WebWeixinApi;
|
||||
|
||||
public class TestClass2 {
|
||||
public static void main(String[] args) {
|
||||
WebWeixinApi api = new WebWeixinApi();
|
||||
Wechat wechat = new Wechat();
|
||||
wechat.setWebWeixinApi(api);
|
||||
System.out.println(wechat.autoLogin());
|
||||
wechat.logout();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user