2
0
mirror of https://gitee.com/hotlcc/wechat4j.git synced 2025-06-08 11:34:07 +08:00

!12 升级版本号[0.2.3->0.2.4]

Merge pull request !12 from Allen/feature/20180914
This commit is contained in:
Allen 2019-04-17 10:21:19 +08:00
commit 4facae51c9
19 changed files with 507 additions and 277 deletions

View File

@ -17,10 +17,8 @@
## 简单使用 ## 简单使用
```java ```java
WebWeixinApi api = new WebWeixinApi();
// 实例化微信客户端 // 实例化微信客户端
Wechat wechat = new Wechat(); Wechat wechat = new Wechat();
wechat.setWebWeixinApi(api);
// 自动登录 // 自动登录
wechat.autoLogin(); wechat.autoLogin();
``` ```
@ -57,6 +55,23 @@ JSONObject sendImage(String userName, String nickName, String remarkName, byte[]
JSONObject sendImage(String userName, String nickName, String remarkName, File image); JSONObject sendImage(String userName, String nickName, String remarkName, File image);
``` ```
### 视频消息
```java
// 通过userName发送视频消息
JSONObject sendVideo(String userName, byte[] mediaData, String mediaName, ContentType contentType);
JSONObject sendVideo(String userName, File image);
// 通过昵称发送视频消息
JSONObject sendVideoToNickName(String nickName, byte[] mediaData, String mediaName, ContentType contentType);
JSONObject sendVideoToNickName(String nickName, File image);
// 通过备注名发送视频消息
JSONObject sendVideoToRemarkName(String remarkName, byte[] mediaData, String mediaName, ContentType contentType);
JSONObject sendVideoToRemarkName(String remarkName, File image);
// 发送视频消息(根据多种名称)
JSONObject sendVideo(String userName, String nickName, String remarkName, byte[] mediaData, String mediaName, ContentType contentType);
JSONObject sendVideo(String userName, String nickName, String remarkName, File image);
```
> 更多消息类型支持尽请期待。 > 更多消息类型支持尽请期待。
## 消息处理器 ## 消息处理器

View File

@ -6,7 +6,7 @@
<groupId>com.hotlcc</groupId> <groupId>com.hotlcc</groupId>
<artifactId>wechat4j</artifactId> <artifactId>wechat4j</artifactId>
<version>0.2.3</version> <version>0.2.4</version>
<name>wechat4j</name> <name>wechat4j</name>
<description>Wechat client for Java.</description> <description>Wechat client for Java.</description>

View File

@ -2,13 +2,12 @@ package com.hotlcc.wechat4j;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.hotlcc.wechat4j.api.WebWeixinApi;
import com.hotlcc.wechat4j.enums.*; import com.hotlcc.wechat4j.enums.*;
import com.hotlcc.wechat4j.handler.ExitEventHandler; import com.hotlcc.wechat4j.handler.ExitEventHandler;
import com.hotlcc.wechat4j.handler.ReceivedMsgHandler; import com.hotlcc.wechat4j.handler.ReceivedMsgHandler;
import com.hotlcc.wechat4j.model.*; import com.hotlcc.wechat4j.model.*;
import com.hotlcc.wechat4j.util.*; import com.hotlcc.wechat4j.util.*;
import org.apache.http.HttpException; import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpRequest; import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor; import org.apache.http.HttpRequestInterceptor;
import org.apache.http.client.CookieStore; import org.apache.http.client.CookieStore;
@ -18,11 +17,8 @@ import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -36,11 +32,8 @@ import java.util.concurrent.locks.ReentrantLock;
* @author Allen * @author Allen
*/ */
@SuppressWarnings({"Duplicates", "unused"}) @SuppressWarnings({"Duplicates", "unused"})
@Slf4j
public class Wechat { public class Wechat {
private static Logger logger = LoggerFactory.getLogger(Wechat.class);
private WebWeixinApi webWeixinApi;
private CookieStore cookieStore; private CookieStore cookieStore;
private HttpClient httpClient; private HttpClient httpClient;
@ -78,10 +71,6 @@ public class Wechat {
this(new BasicCookieStore()); this(new BasicCookieStore());
} }
public void setWebWeixinApi(WebWeixinApi webWeixinApi) {
this.webWeixinApi = webWeixinApi;
}
/** /**
* 获取Cookie * 获取Cookie
* *
@ -189,7 +178,7 @@ public class Wechat {
private HttpClient buildHttpClient(CookieStore cookieStore) { private HttpClient buildHttpClient(CookieStore cookieStore) {
HttpRequestInterceptor interceptor = new HttpRequestInterceptor() { HttpRequestInterceptor interceptor = new HttpRequestInterceptor() {
@Override @Override
public void process(HttpRequest httpRequest, HttpContext httpContext) throws HttpException, IOException { public void process(HttpRequest httpRequest, HttpContext httpContext) {
httpRequest.addHeader("User-Agent", PropertiesUtil.getProperty("wechat4j.userAgent")); httpRequest.addHeader("User-Agent", PropertiesUtil.getProperty("wechat4j.userAgent"));
} }
}; };
@ -203,8 +192,8 @@ public class Wechat {
/** /**
* 获取uuid登录时 * 获取uuid登录时
* *
* @param pw * @param pw 打印器
* @param time * @param time 时间
* @return * @return
*/ */
private String getWxUuid(PrintWriter pw, int time) { private String getWxUuid(PrintWriter pw, int time) {
@ -216,7 +205,7 @@ public class Wechat {
pw.print("\t第" + i + "次尝试..."); pw.print("\t第" + i + "次尝试...");
pw.flush(); pw.flush();
} }
JSONObject result = webWeixinApi.getWxUuid(httpClient); JSONObject result = WebWeixinApiUtil.getWxUuid(httpClient);
if (result == null) { if (result == null) {
pw.println("\t失败出现异常"); pw.println("\t失败出现异常");
@ -253,7 +242,7 @@ public class Wechat {
/** /**
* 获取并显示qrcode登录时 * 获取并显示qrcode登录时
* *
* @return * @return 是否成功
*/ */
private boolean getAndShowQRCode(PrintWriter pw, String uuid, int time) { private boolean getAndShowQRCode(PrintWriter pw, String uuid, int time) {
pw.print("获取二维码..."); pw.print("获取二维码...");
@ -265,7 +254,7 @@ public class Wechat {
pw.flush(); pw.flush();
} }
byte[] data = webWeixinApi.getQR(httpClient, uuid); byte[] data = WebWeixinApiUtil.getQR(httpClient, uuid);
if (data == null || data.length <= 0) { if (data == null || data.length <= 0) {
pw.print("\t失败"); pw.print("\t失败");
@ -302,7 +291,7 @@ public class Wechat {
boolean flag = false; boolean flag = false;
while (true) { while (true) {
JSONObject result = webWeixinApi.getRedirectUri(httpClient, LoginTipEnum.TIP_0, uuid); JSONObject result = WebWeixinApiUtil.getRedirectUri(httpClient, LoginTip.TIP_0, uuid);
if (result == null) { if (result == null) {
pw.println("\t失败出现异常"); pw.println("\t失败出现异常");
pw.flush(); pw.flush();
@ -343,7 +332,7 @@ public class Wechat {
pw.print("获取登录认证码..."); pw.print("获取登录认证码...");
pw.flush(); pw.flush();
JSONObject result = webWeixinApi.getLoginCode(httpClient, redirectUri); JSONObject result = WebWeixinApiUtil.getLoginCode(httpClient, redirectUri);
if (result == null) { if (result == null) {
pw.println("\t失败出现异常"); pw.println("\t失败出现异常");
pw.flush(); pw.flush();
@ -379,7 +368,7 @@ public class Wechat {
pw.print("尝试push方式获取uuid..."); pw.print("尝试push方式获取uuid...");
pw.flush(); pw.flush();
JSONObject result = webWeixinApi.pushLogin(httpClient, urlVersion, wxuin); JSONObject result = WebWeixinApiUtil.pushLogin(httpClient, urlVersion, wxuin);
if (result == null) { if (result == null) {
pw.println("\t失败出现异常"); pw.println("\t失败出现异常");
pw.flush(); pw.flush();
@ -412,7 +401,7 @@ public class Wechat {
* @return * @return
*/ */
private boolean wxInit() { private boolean wxInit() {
JSONObject result = webWeixinApi.webWeixinInit(httpClient, urlVersion, passTicket, new BaseRequest(wxsid, skey, wxuin)); JSONObject result = WebWeixinApiUtil.webWeixinInit(httpClient, urlVersion, passTicket, new BaseRequest(wxsid, skey, wxuin));
if (result == null) { if (result == null) {
return false; return false;
} }
@ -476,7 +465,7 @@ public class Wechat {
*/ */
private boolean statusNotify(int time) { private boolean statusNotify(int time) {
for (int i = 0; i < time; i++) { for (int i = 0; i < time; i++) {
JSONObject result = webWeixinApi.statusNotify(httpClient, urlVersion, passTicket, new BaseRequest(wxsid, skey, wxuin), getLoginUserName(false)); JSONObject result = WebWeixinApiUtil.statusNotify(httpClient, urlVersion, passTicket, new BaseRequest(wxsid, skey, wxuin), getLoginUserName(false));
if (result == null) { if (result == null) {
continue; continue;
} }
@ -593,7 +582,7 @@ public class Wechat {
isOnlineLock.lock(); isOnlineLock.lock();
if (isOnline) { if (isOnline) {
webWeixinApi.logout(httpClient, urlVersion, new BaseRequest(wxsid, skey, wxuin)); WebWeixinApiUtil.logout(httpClient, urlVersion, new BaseRequest(wxsid, skey, wxuin));
isOnline = false; isOnline = false;
if (clearAllLoginInfo) { if (clearAllLoginInfo) {
@ -663,8 +652,8 @@ public class Wechat {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
try { try {
JSONObject result = webWeixinApi.syncCheck(httpClient, urlVersion, new BaseRequest(wxsid, skey, wxuin), getSyncKeyList(false)); JSONObject result = WebWeixinApiUtil.syncCheck(httpClient, urlVersion, new BaseRequest(wxsid, skey, wxuin), getSyncKeyList(false));
logger.info("微信同步监听心跳返回数据:{}", result); log.info("微信同步监听心跳返回数据:{}", result);
if (result == null) { if (result == null) {
throw new RuntimeException("微信API调用异常"); throw new RuntimeException("微信API调用异常");
} else { } else {
@ -673,28 +662,28 @@ public class Wechat {
//人为退出 //人为退出
int retcode = result.getIntValue("retcode"); int retcode = result.getIntValue("retcode");
if (retcode != RetcodeEnum.RECODE_0.getCode()) { if (retcode != Retcode.RECODE_0.getCode()) {
logger.info("微信退出或从其它设备登录"); log.info("微信退出或从其它设备登录");
logout(); logout();
processExitEvent(ExitTypeEnum.REMOTE_EXIT, null); processExitEvent(ExitType.REMOTE_EXIT, null);
return; return;
} }
int selector = result.getIntValue("selector"); int selector = result.getIntValue("selector");
processSelector(selector); processSelector(selector);
} catch (Exception e) { } catch (Exception e) {
logger.error("同步监听心跳异常", e); log.error("同步监听心跳异常", e);
if (i == 0) { if (i == 0) {
logger.info("同步监听请求失败,正在重试..."); log.info("同步监听请求失败,正在重试...");
} else if (i > 0) { } else if (i > 0) {
logger.info("第{}次重试失败" + i); log.info("第{}次重试失败" + i);
} }
if (i >= time) { if (i >= time) {
logger.info("重复{}次仍然失败,退出微信", i); log.info("重复{}次仍然失败,退出微信", i);
logout(); logout();
processExitEvent(ExitTypeEnum.ERROR_EXIT, e); processExitEvent(ExitType.ERROR_EXIT, e);
return; return;
} }
@ -708,7 +697,7 @@ public class Wechat {
} }
} }
processExitEvent(ExitTypeEnum.LOCAL_EXIT, null); processExitEvent(ExitType.LOCAL_EXIT, null);
} }
/** /**
@ -717,7 +706,7 @@ public class Wechat {
* @param type 退出类型 * @param type 退出类型
* @param t 异常 * @param t 异常
*/ */
private void processExitEvent(ExitTypeEnum type, Throwable t) { private void processExitEvent(ExitType type, Throwable t) {
try { try {
if (exitEventHandlers == null) { if (exitEventHandlers == null) {
return; return;
@ -729,11 +718,11 @@ public class Wechat {
} }
} }
} catch (Exception e) { } catch (Exception e) {
logger.error("Exit event process error.", e); log.error("Exit event process error.", e);
} }
} }
private void processExitEvent(ExitTypeEnum type, Throwable t, ExitEventHandler handler) { private void processExitEvent(ExitType type, Throwable t, ExitEventHandler handler) {
try { try {
switch (type) { switch (type) {
case ERROR_EXIT: case ERROR_EXIT:
@ -749,13 +738,13 @@ public class Wechat {
break; break;
} }
} catch (Exception e) { } catch (Exception e) {
logger.error("Exit event process error.", e); log.error("Exit event process error.", e);
} }
try { try {
handler.handleAllType(wechat, type, t); handler.handleAllType(wechat, type, t);
} catch (Exception e) { } catch (Exception e) {
logger.error("Exit event process error.", e); log.error("Exit event process error.", e);
} }
} }
@ -766,9 +755,9 @@ public class Wechat {
*/ */
private void processSelector(int selector) { private void processSelector(int selector) {
try { try {
SelectorEnum e = SelectorEnum.valueOf(selector); Selector e = Selector.valueOf(selector);
if (e == null) { if (e == null) {
logger.warn("Cannot process unknow selector {}", selector); log.warn("Cannot process unknow selector {}", selector);
return; return;
} }
@ -788,7 +777,7 @@ public class Wechat {
break; break;
} }
} catch (Exception e) { } catch (Exception e) {
logger.error("Execute processSelector error.", e); log.error("Execute processSelector error.", e);
} }
} }
@ -797,21 +786,21 @@ public class Wechat {
*/ */
private void webWxSync() { private void webWxSync() {
try { try {
JSONObject result = webWeixinApi.webWxSync(httpClient, urlVersion, passTicket, new BaseRequest(wxsid, skey, wxuin), syncKey); JSONObject result = WebWeixinApiUtil.webWxSync(httpClient, urlVersion, passTicket, new BaseRequest(wxsid, skey, wxuin), syncKey);
if (result == null) { if (result == null) {
logger.error("从服务端同步新数据异常"); log.error("从服务端同步新数据异常");
return; return;
} }
JSONObject baseResponse = result.getJSONObject("BaseResponse"); JSONObject baseResponse = result.getJSONObject("BaseResponse");
if (baseResponse == null) { if (baseResponse == null) {
logger.warn("同步接口返回数据格式错误"); log.warn("同步接口返回数据格式错误");
return; return;
} }
int ret = baseResponse.getIntValue("Ret"); int ret = baseResponse.getIntValue("Ret");
if (ret != RetcodeEnum.RECODE_0.getCode()) { if (ret != Retcode.RECODE_0.getCode()) {
logger.warn("同步接口返回错误代码:{}", ret); log.warn("同步接口返回错误代码:{}", ret);
return; return;
} }
@ -827,7 +816,7 @@ public class Wechat {
syncKeyLock.unlock(); syncKeyLock.unlock();
} }
} catch (Exception e) { } catch (Exception e) {
logger.error("Execute webWxSync error.", e); log.error("Execute webWxSync error.", e);
} }
} }
@ -843,10 +832,10 @@ public class Wechat {
} }
int len = addMsgList.size(); int len = addMsgList.size();
logger.debug("收到{}条新消息", len); log.debug("收到{}条新消息", len);
if (receivedMsgHandlers == null || receivedMsgHandlers.isEmpty()) { if (receivedMsgHandlers == null || receivedMsgHandlers.isEmpty()) {
logger.warn("收到{}条新消息,但没有配置消息处理器", len); log.warn("收到{}条新消息,但没有配置消息处理器", len);
return; return;
} }
@ -859,7 +848,7 @@ public class Wechat {
} }
} }
} catch (Exception e) { } catch (Exception e) {
logger.error("Execute processNewMsg error.", e); log.error("Execute processNewMsg error.", e);
} }
} }
@ -867,7 +856,7 @@ public class Wechat {
try { try {
handler.handleAllType(wechat, msg); handler.handleAllType(wechat, msg);
} catch (Exception e) { } catch (Exception e) {
logger.error("Execute processNewMsg error.", e); log.error("Execute processNewMsg error.", e);
} }
} }
} }
@ -879,7 +868,7 @@ public class Wechat {
*/ */
public UserInfo getLoginUser(boolean update) { public UserInfo getLoginUser(boolean update) {
if (loginUser == null || update) { if (loginUser == null || update) {
JSONObject result = webWeixinApi.webWeixinInit(httpClient, urlVersion, passTicket, new BaseRequest(wxsid, skey, wxuin)); JSONObject result = WebWeixinApiUtil.webWeixinInit(httpClient, urlVersion, passTicket, new BaseRequest(wxsid, skey, wxuin));
if (result == null) { if (result == null) {
return loginUser; return loginUser;
} }
@ -954,7 +943,7 @@ public class Wechat {
*/ */
private JSONObject getSyncKey(boolean update) { private JSONObject getSyncKey(boolean update) {
if (syncKey == null || update) { if (syncKey == null || update) {
JSONObject result = webWeixinApi.webWeixinInit(httpClient, urlVersion, passTicket, new BaseRequest(wxsid, skey, wxuin)); JSONObject result = WebWeixinApiUtil.webWeixinInit(httpClient, urlVersion, passTicket, new BaseRequest(wxsid, skey, wxuin));
if (result == null) { if (result == null) {
return syncKey; return syncKey;
} }
@ -1005,7 +994,7 @@ public class Wechat {
*/ */
public List<UserInfo> getContactList(boolean update) { public List<UserInfo> getContactList(boolean update) {
if (contactList == null || update) { if (contactList == null || update) {
JSONObject result = webWeixinApi.getContact(httpClient, urlVersion, passTicket, skey); JSONObject result = WebWeixinApiUtil.getContact(httpClient, urlVersion, passTicket, skey);
if (result == null) { if (result == null) {
return contactList; return contactList;
} }
@ -1162,9 +1151,9 @@ public class Wechat {
} else { } else {
message.setToUserName(userName); message.setToUserName(userName);
} }
message.setType(MsgTypeEnum.TEXT_MSG.getCode()); message.setType(MsgType.TEXT_MSG.getCode());
return webWeixinApi.sendMsg(httpClient, urlVersion, passTicket, baseRequest, message); return WebWeixinApiUtil.sendMsg(httpClient, urlVersion, passTicket, baseRequest, message);
} }
/** /**
@ -1266,7 +1255,7 @@ public class Wechat {
// 上传媒体文件 // 上传媒体文件
String dataTicket = getCookieValue("webwx_data_ticket"); String dataTicket = getCookieValue("webwx_data_ticket");
JSONObject result = webWeixinApi.uploadMedia(httpClient, urlVersion, passTicket, baseRequest, loginUserName, toUserName, dataTicket, mediaData, mediaName, contentType); JSONObject result = WebWeixinApiUtil.uploadMedia(httpClient, urlVersion, passTicket, baseRequest, loginUserName, toUserName, dataTicket, mediaData, mediaName, contentType, MediaType.PICTURE);
if (result == null) { if (result == null) {
return null; return null;
} }
@ -1293,8 +1282,8 @@ public class Wechat {
message.setLocalID(msgId); message.setLocalID(msgId);
message.setMediaId(mediaId); message.setMediaId(mediaId);
message.setToUserName(toUserName); message.setToUserName(toUserName);
message.setType(MsgTypeEnum.IMAGE_MSG.getCode()); message.setType(MsgType.IMAGE_MSG.getCode());
result = webWeixinApi.sendImageMsg(httpClient, urlVersion, passTicket, baseRequest, message); result = WebWeixinApiUtil.sendImageMsg(httpClient, urlVersion, passTicket, baseRequest, message);
return result; return result;
} }
@ -1442,4 +1431,196 @@ public class Wechat {
byte[] mediaData = FileUtil.getBytes(image); byte[] mediaData = FileUtil.getBytes(image);
return sendImage(userName, nickName, remarkName, mediaData, image.getName(), contentType); return sendImage(userName, nickName, remarkName, mediaData, image.getName(), contentType);
} }
/**
* 发送视频消息
*
* @param userName 用户名加密的
* @param mediaData 媒体文件数据
* @param mediaName 媒体文件名
* @param contentType 媒体文件类型
* @return 返回数据
*/
public JSONObject sendVideo(String userName, byte[] mediaData, String mediaName, ContentType contentType) {
String loginUserName = getLoginUserName(false);
String toUserName = StringUtil.isEmpty(userName) ? loginUserName : userName;
BaseRequest baseRequest = new BaseRequest(wxsid, skey, wxuin);
// 上传媒体文件
String dataTicket = getCookieValue("webwx_data_ticket");
JSONObject result = WebWeixinApiUtil.uploadMedia(httpClient, urlVersion, passTicket, baseRequest, loginUserName, toUserName, dataTicket, mediaData, mediaName, contentType, MediaType.VIDEO);
if (result == null) {
return null;
}
JSONObject br = result.getJSONObject("BaseResponse");
if (br == null) {
return result;
}
int ret = br.getIntValue("Ret");
if (ret != 0) {
return result;
}
String mediaId = result.getString("MediaId");
if (StringUtil.isEmpty(mediaId)) {
return result;
}
// 发送视频消息
String msgId = WechatUtil.createMsgId();
MediaMessage message = new MediaMessage();
message.setClientMsgId(msgId);
message.setContent("");
message.setFromUserName(loginUserName);
message.setLocalID(msgId);
message.setMediaId(mediaId);
message.setToUserName(toUserName);
message.setType(MsgType.VIDEO_CALL_MSG.getCode());
result = WebWeixinApiUtil.sendVideoMsg(httpClient, urlVersion, baseRequest, message);
return result;
}
/**
* 发送视频消息
*
* @param userName 用户名加密的
* @param video 视频文件
* @return 返回数据
*/
public JSONObject sendVideo(String userName, File video) {
ContentType contentType = FileUtil.getContentBody(video);
byte[] mediaData = FileUtil.getBytes(video);
return sendVideo(userName, mediaData, video.getName(), contentType);
}
/**
* 发送视频消息根据昵称
*
* @param nickName 昵称
* @param mediaData 媒体文件数据
* @param mediaName 媒体文件名
* @param contentType 媒体文件类型
* @return 返回数据
*/
public JSONObject sendVideoToNickName(String nickName, byte[] mediaData, String mediaName, ContentType contentType) {
if (StringUtil.isEmpty(nickName)) {
return sendVideo(null, mediaData, mediaName, contentType);
}
UserInfo userInfo = getContactByNickName(false, nickName);
if (userInfo == null) {
return null;
}
String userName = userInfo.getUserName();
if (StringUtil.isEmpty(userName)) {
return null;
}
return sendVideo(userName, mediaData, mediaName, contentType);
}
/**
* 发送视频消息根据昵称
*
* @param nickName 昵称
* @param video 视频文件
* @return 返回数据
*/
public JSONObject sendVideoToNickName(String nickName, File video) {
ContentType contentType = FileUtil.getContentBody(video);
byte[] mediaData = FileUtil.getBytes(video);
return sendVideoToNickName(nickName, mediaData, video.getName(), contentType);
}
/**
* 发送视频消息根据备注名
*
* @param remarkName 备注名
* @param mediaData 媒体文件数据
* @param mediaName 媒体文件名
* @param contentType 媒体文件类型
* @return 返回数据
*/
public JSONObject sendVideoToRemarkName(String remarkName, byte[] mediaData, String mediaName, ContentType contentType) {
if (StringUtil.isEmpty(remarkName)) {
return sendVideo(null, mediaData, mediaName, contentType);
}
UserInfo userInfo = getContactByRemarkName(false, remarkName);
if (userInfo == null) {
return null;
}
String userName = userInfo.getUserName();
if (StringUtil.isEmpty(userName)) {
return null;
}
return sendVideo(userName, mediaData, mediaName, contentType);
}
/**
* 发送视频消息根据备注名
*
* @param remarkName 备注名
* @param video 视频文件
* @return 返回数据
*/
public JSONObject sendVideoToRemarkName(String remarkName, File video) {
ContentType contentType = FileUtil.getContentBody(video);
byte[] mediaData = FileUtil.getBytes(video);
return sendVideoToRemarkName(remarkName, mediaData, video.getName(), contentType);
}
/**
* 发送视频消息根据多种名称
*
* @param userName 用户名加密的
* @param nickName 昵称
* @param remarkName 备注名
* @param mediaData 媒体文件数据
* @param mediaName 媒体文件名
* @param contentType 媒体文件类型
* @return 返回数据
*/
public JSONObject sendVideo(String userName, String nickName, String remarkName, byte[] mediaData, String mediaName, ContentType contentType) {
UserInfo userInfo;
if (StringUtil.isNotEmpty(userName)) {
return sendVideo(userName, mediaData, mediaName, contentType);
} else if (StringUtil.isNotEmpty(nickName)) {
userInfo = getContactByNickName(false, nickName);
} else if (StringUtil.isNotEmpty(remarkName)) {
userInfo = getContactByRemarkName(false, remarkName);
} else {
String loginUserName = getLoginUserName(false);
return sendVideo(loginUserName, mediaData, mediaName, contentType);
}
if (userInfo == null) {
return null;
}
userName = userInfo.getUserName();
if (StringUtil.isEmpty(userName)) {
return null;
}
return sendVideo(userName, mediaData, mediaName, contentType);
}
/**
* 发送视频消息根据多种名称
*
* @param userName 用户名加密的
* @param nickName 昵称
* @param remarkName 备注名
* @param video 视频文件
* @return 返回数据
*/
public JSONObject sendVideo(String userName, String nickName, String remarkName, File video) {
ContentType contentType = FileUtil.getContentBody(video);
byte[] mediaData = FileUtil.getBytes(video);
return sendVideo(userName, nickName, remarkName, mediaData, video.getName(), contentType);
}
} }

View File

@ -1,19 +1,17 @@
package com.hotlcc.wechat4j.enums; package com.hotlcc.wechat4j.enums;
import lombok.AllArgsConstructor;
/** /**
* 微信退出类型 * 微信退出类型
* *
* @author Allen * @author Allen
*/ */
public enum ExitTypeEnum { @AllArgsConstructor
public enum ExitType {
ERROR_EXIT("错误退出"), ERROR_EXIT("错误退出"),
LOCAL_EXIT("本地退出"), LOCAL_EXIT("本地退出"),
REMOTE_EXIT("远程退出"); REMOTE_EXIT("远程退出");
private String desc; private String desc;
ExitTypeEnum(String desc) {
this.desc = desc;
}
} }

View File

@ -1,27 +1,23 @@
package com.hotlcc.wechat4j.enums; package com.hotlcc.wechat4j.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/** /**
* 等待确认登录的tip * 等待确认登录的tip
* *
* @author Allen * @author Allen
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
public enum LoginTipEnum { @Getter
@AllArgsConstructor
public enum LoginTip {
TIP_0(0, "扫码登录"), TIP_0(0, "扫码登录"),
TIP_1(1, "确认登录"); TIP_1(1, "确认登录");
private int code; private int code;
private String desc; private String desc;
LoginTipEnum(int code, String desc) {
this.code = code;
this.desc = desc;
}
public int getCode() {
return code;
}
@Override @Override
public String toString() { public String toString() {
return code + ""; return code + "";

View File

@ -0,0 +1,22 @@
package com.hotlcc.wechat4j.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author Allen
* @version 1.0
* @date 2019/4/17 9:51
*/
@Getter
@AllArgsConstructor
public enum MediaType {
PICTURE(4, "pic"),
VIDEO(4, "video");
public static String REQUEST_KEY = "mediatype";
public static String REQUEST_JSON_KEY = "MediaType";
private Integer code;
private String value;
}

View File

@ -1,12 +1,17 @@
package com.hotlcc.wechat4j.enums; package com.hotlcc.wechat4j.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/** /**
* 消息类型enum * 消息类型enum
* *
* @author Allen * @author Allen
*/ */
@SuppressWarnings({"unused"}) @SuppressWarnings({"unused"})
public enum MsgTypeEnum { @AllArgsConstructor
@Getter
public enum MsgType {
TEXT_MSG(1, "文本消息"), TEXT_MSG(1, "文本消息"),
IMAGE_MSG(3, "图片消息"), IMAGE_MSG(3, "图片消息"),
VOICE_MSG(34, "语音消息"), VOICE_MSG(34, "语音消息"),
@ -26,19 +31,6 @@ public enum MsgTypeEnum {
SYSTEM_MSG(10000, "系统消息"), SYSTEM_MSG(10000, "系统消息"),
WITHDRAW_MSG(10002, "撤回消息"); WITHDRAW_MSG(10002, "撤回消息");
MsgTypeEnum(int code, String desc) {
this.code = code;
this.desc = desc;
}
private int code; private int code;
private String desc; private String desc;
public int getCode() {
return code;
}
public String getDesc() {
return desc;
}
} }

View File

@ -0,0 +1,35 @@
package com.hotlcc.wechat4j.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 操作系统enum
*
* @author Allen
*/
@Getter
@AllArgsConstructor
public enum OperatingSystem {
DARWIN("darwin"),
WINDOWS("windows"),
LINUX("linux"),
MAC_OS("mac"),
OTHER("other");
private String value;
public static OperatingSystem currentOperatingSystem() {
String osName = System.getProperty("os.name").toLowerCase();
if (osName.contains(OperatingSystem.DARWIN.getValue())) {
return OperatingSystem.DARWIN;
} else if (osName.contains(OperatingSystem.WINDOWS.getValue())) {
return OperatingSystem.WINDOWS;
} else if (osName.contains(OperatingSystem.LINUX.getValue())) {
return OperatingSystem.LINUX;
} else if (osName.contains(OperatingSystem.MAC_OS.getValue())) {
return OperatingSystem.MAC_OS;
}
return OperatingSystem.OTHER;
}
}

View File

@ -1,38 +0,0 @@
package com.hotlcc.wechat4j.enums;
/**
* 操作系统enum
*
* @author Allen
*/
public enum OperatingSystemEnum {
DARWIN("darwin"),
WINDOWS("windows"),
LINUX("linux"),
MAC_OS("mac"),
OTHER("other");
private String value;
public String getValue() {
return value;
}
OperatingSystemEnum(String value) {
this.value = value;
}
public static OperatingSystemEnum currentOperatingSystem() {
String osName = System.getProperty("os.name").toLowerCase();
if (osName.indexOf(OperatingSystemEnum.DARWIN.getValue()) >= 0) {
return OperatingSystemEnum.DARWIN;
} else if (osName.indexOf(OperatingSystemEnum.WINDOWS.getValue()) >= 0) {
return OperatingSystemEnum.WINDOWS;
} else if (osName.indexOf(OperatingSystemEnum.LINUX.getValue()) >= 0) {
return OperatingSystemEnum.LINUX;
} else if (osName.indexOf(OperatingSystemEnum.MAC_OS.getValue()) >= 0) {
return OperatingSystemEnum.MAC_OS;
}
return OperatingSystemEnum.OTHER;
}
}

View File

@ -1,11 +1,16 @@
package com.hotlcc.wechat4j.enums; package com.hotlcc.wechat4j.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/** /**
* Ret代码 * Ret代码
* *
* @author Allen * @author Allen
*/ */
public enum RetcodeEnum { @AllArgsConstructor
@Getter
public enum Retcode {
RECODE_0(0, "正常"), RECODE_0(0, "正常"),
RECODE_1100(1100, "失败/登出微信"), RECODE_1100(1100, "失败/登出微信"),
RECODE_1101(1101, "从其它设备登录微信"); RECODE_1101(1101, "从其它设备登录微信");
@ -13,18 +18,9 @@ public enum RetcodeEnum {
private int code; private int code;
private String desc; private String desc;
RetcodeEnum(int code, String desc) { public static Retcode valueOf(int code) {
this.code = code; Retcode[] es = values();
this.desc = desc; for (Retcode e : es) {
}
public int getCode() {
return code;
}
public static RetcodeEnum valueOf(int code) {
RetcodeEnum[] es = values();
for (RetcodeEnum e : es) {
if (e.code == code) { if (e.code == code) {
return e; return e;
} }

View File

@ -1,11 +1,14 @@
package com.hotlcc.wechat4j.enums; package com.hotlcc.wechat4j.enums;
import lombok.AllArgsConstructor;
/** /**
* Selector代码 * Selector代码
* *
* @author Allen * @author Allen
*/ */
public enum SelectorEnum { @AllArgsConstructor
public enum Selector {
SELECTOR_0(0, "正常"), SELECTOR_0(0, "正常"),
SELECTOR_2(2, "有新消息"), SELECTOR_2(2, "有新消息"),
SELECTOR_4(4, "目前发现修改了联系人备注会出现"), SELECTOR_4(4, "目前发现修改了联系人备注会出现"),
@ -15,14 +18,9 @@ public enum SelectorEnum {
private int code; private int code;
private String desc; private String desc;
SelectorEnum(int code, String desc) { public static Selector valueOf(int code) {
this.code = code; Selector[] es = values();
this.desc = desc; for (Selector e : es) {
}
public static SelectorEnum valueOf(int code) {
SelectorEnum[] es = values();
for (SelectorEnum e : es) {
if (e.code == code) { if (e.code == code) {
return e; return e;
} }

View File

@ -1,7 +1,7 @@
package com.hotlcc.wechat4j.handler; package com.hotlcc.wechat4j.handler;
import com.hotlcc.wechat4j.Wechat; import com.hotlcc.wechat4j.Wechat;
import com.hotlcc.wechat4j.enums.ExitTypeEnum; import com.hotlcc.wechat4j.enums.ExitType;
/** /**
* 退出事件处理器 * 退出事件处理器
@ -16,7 +16,7 @@ public interface ExitEventHandler {
* @param type 退出类型 * @param type 退出类型
* @param t 异常 * @param t 异常
*/ */
void handleAllType(Wechat wechat, ExitTypeEnum type, Throwable t); void handleAllType(Wechat wechat, ExitType type, Throwable t);
/** /**
* 针对错误导致的退出事件 * 针对错误导致的退出事件

View File

@ -1,16 +1,14 @@
package com.hotlcc.wechat4j.util; package com.hotlcc.wechat4j.util;
import org.slf4j.Logger; import lombok.extern.slf4j.Slf4j;
import org.slf4j.LoggerFactory;
/** /**
* 通用工具类 * 通用工具类
* *
* @author Allen * @author Allen
*/ */
@Slf4j
public final class CommonUtil { public final class CommonUtil {
private static Logger logger = LoggerFactory.getLogger(CommonUtil.class);
private CommonUtil() { private CommonUtil() {
} }

View File

@ -1,8 +1,7 @@
package com.hotlcc.wechat4j.util; package com.hotlcc.wechat4j.util;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.entity.ContentType; import org.apache.http.entity.ContentType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.activation.MimetypesFileTypeMap; import javax.activation.MimetypesFileTypeMap;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@ -15,9 +14,8 @@ import java.io.IOException;
* *
* @author Allen * @author Allen
*/ */
@Slf4j
public final class FileUtil { public final class FileUtil {
private static Logger logger = LoggerFactory.getLogger(FileUtil.class);
private FileUtil() { private FileUtil() {
} }

View File

@ -1,7 +1,6 @@
package com.hotlcc.wechat4j.util; package com.hotlcc.wechat4j.util;
import org.slf4j.Logger; import lombok.extern.slf4j.Slf4j;
import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -12,9 +11,8 @@ import java.util.Properties;
* *
* @author Allen * @author Allen
*/ */
@Slf4j
public final class PropertiesUtil { public final class PropertiesUtil {
private static Logger logger = LoggerFactory.getLogger(PropertiesUtil.class);
private PropertiesUtil() { private PropertiesUtil() {
} }
@ -38,7 +36,7 @@ public final class PropertiesUtil {
is = PropertiesUtil.class.getClassLoader().getResourceAsStream(path); is = PropertiesUtil.class.getClassLoader().getResourceAsStream(path);
prop.load(is); prop.load(is);
} catch (Exception e) { } catch (Exception e) {
logger.error("Loading properties file \"" + path + "\" error.", e); log.error("Loading properties file \"" + path + "\" error.", e);
} finally { } finally {
if (is != null) { if (is != null) {
try { try {

View File

@ -6,9 +6,8 @@ import com.google.zxing.NotFoundException;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource; import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.BitMatrix; import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer; import com.google.zxing.common.HybridBinarizer;
import com.hotlcc.wechat4j.enums.OperatingSystemEnum; import com.hotlcc.wechat4j.enums.OperatingSystem;
import org.slf4j.Logger; import lombok.extern.slf4j.Slf4j;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
@ -23,9 +22,8 @@ import java.io.IOException;
* @author Allen * @author Allen
*/ */
@SuppressWarnings({"unused", "WeakerAccess"}) @SuppressWarnings({"unused", "WeakerAccess"})
@Slf4j
public final class QRCodeUtil { public final class QRCodeUtil {
private static Logger logger = LoggerFactory.getLogger(QRCodeUtil.class);
private QRCodeUtil() { private QRCodeUtil() {
} }
@ -252,7 +250,7 @@ public final class QRCodeUtil {
fos.flush(); fos.flush();
return tmp; return tmp;
} catch (IOException e) { } catch (IOException e) {
logger.error("二维码写入临时文件异常", e); log.error("二维码写入临时文件异常", e);
throw new RuntimeException(e); throw new RuntimeException(e);
} finally { } finally {
if (fos != null) { if (fos != null) {
@ -271,7 +269,7 @@ public final class QRCodeUtil {
* @param data 二维码图片的字节数据 * @param data 二维码图片的字节数据
*/ */
public static void openQRCodeImage(byte[] data) { public static void openQRCodeImage(byte[] data) {
OperatingSystemEnum os = OperatingSystemEnum.currentOperatingSystem(); OperatingSystem os = OperatingSystem.currentOperatingSystem();
Runtime runtime; Runtime runtime;
File tmp; File tmp;
switch (os) { switch (os) {

View File

@ -1,14 +1,13 @@
package com.hotlcc.wechat4j.api; package com.hotlcc.wechat4j.util;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.hotlcc.wechat4j.enums.LoginTipEnum; import com.hotlcc.wechat4j.enums.LoginTip;
import com.hotlcc.wechat4j.enums.MediaType;
import com.hotlcc.wechat4j.model.BaseRequest; import com.hotlcc.wechat4j.model.BaseRequest;
import com.hotlcc.wechat4j.model.MediaMessage; import com.hotlcc.wechat4j.model.MediaMessage;
import com.hotlcc.wechat4j.model.WxMessage; import com.hotlcc.wechat4j.model.WxMessage;
import com.hotlcc.wechat4j.util.PropertiesUtil; import lombok.extern.slf4j.Slf4j;
import com.hotlcc.wechat4j.util.StringUtil;
import com.hotlcc.wechat4j.util.WechatUtil;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.*; import org.apache.http.*;
import org.apache.http.client.HttpClient; import org.apache.http.client.HttpClient;
@ -23,8 +22,6 @@ import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.message.BasicNameValuePair; import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import org.json.XML; import org.json.XML;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.stringtemplate.v4.ST; import org.stringtemplate.v4.ST;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -40,8 +37,10 @@ import java.util.regex.Pattern;
* @author Allen * @author Allen
*/ */
@SuppressWarnings({"Duplicates", "unused"}) @SuppressWarnings({"Duplicates", "unused"})
public class WebWeixinApi { @Slf4j
private static Logger logger = LoggerFactory.getLogger(WebWeixinApi.class); public final class WebWeixinApiUtil {
private WebWeixinApiUtil() {
}
/** /**
* 预编译正则匹配 * 预编译正则匹配
@ -63,7 +62,7 @@ public class WebWeixinApi {
* @param httpClient http客户端 * @param httpClient http客户端
* @return 返回数据 * @return 返回数据
*/ */
public JSONObject getWxUuid(HttpClient httpClient) { public static JSONObject getWxUuid(HttpClient httpClient) {
try { try {
String url = new ST(PropertiesUtil.getProperty("webwx-url.uuid_url")) String url = new ST(PropertiesUtil.getProperty("webwx-url.uuid_url"))
.add("appid", PropertiesUtil.getProperty("webwx.appid")) .add("appid", PropertiesUtil.getProperty("webwx.appid"))
@ -108,7 +107,7 @@ public class WebWeixinApi {
return result; return result;
} catch (Exception e) { } catch (Exception e) {
logger.error("获取uuid异常", e); log.error("获取uuid异常", e);
return null; return null;
} }
} }
@ -120,8 +119,8 @@ public class WebWeixinApi {
* @param uuid uuid * @param uuid uuid
* @return 二维码图片字节数据 * @return 二维码图片字节数据
*/ */
public byte[] getQR(HttpClient httpClient, public static byte[] getQR(HttpClient httpClient,
String uuid) { String uuid) {
try { try {
String url = new ST(PropertiesUtil.getProperty("webwx-url.qrcode_url")) String url = new ST(PropertiesUtil.getProperty("webwx-url.qrcode_url"))
.add("uuid", uuid) .add("uuid", uuid)
@ -144,7 +143,7 @@ public class WebWeixinApi {
return data; return data;
} catch (Exception e) { } catch (Exception e) {
logger.error("获取二维码异常", e); log.error("获取二维码异常", e);
return null; return null;
} }
} }
@ -157,9 +156,9 @@ public class WebWeixinApi {
* @param uuid uuid * @param uuid uuid
* @return 返回数据 * @return 返回数据
*/ */
public JSONObject getRedirectUri(HttpClient httpClient, public static JSONObject getRedirectUri(HttpClient httpClient,
LoginTipEnum tip, LoginTip tip,
String uuid) { String uuid) {
try { try {
long millis = System.currentTimeMillis(); long millis = System.currentTimeMillis();
String url = new ST(PropertiesUtil.getProperty("webwx-url.redirect_uri")) String url = new ST(PropertiesUtil.getProperty("webwx-url.redirect_uri"))
@ -216,7 +215,7 @@ public class WebWeixinApi {
return result; return result;
} catch (Exception e) { } catch (Exception e) {
logger.error("获取跳转uri异常", e); log.error("获取跳转uri异常", e);
return null; return null;
} }
} }
@ -229,8 +228,8 @@ public class WebWeixinApi {
* @param redirectUri 调整uri * @param redirectUri 调整uri
* @return 返回数据 * @return 返回数据
*/ */
public JSONObject getLoginCode(HttpClient httpClient, public static JSONObject getLoginCode(HttpClient httpClient,
String redirectUri) { String redirectUri) {
try { try {
String url = new ST(PropertiesUtil.getProperty("webwx-url.newlogin_url")) String url = new ST(PropertiesUtil.getProperty("webwx-url.newlogin_url"))
.add("redirectUri", redirectUri) .add("redirectUri", redirectUri)
@ -250,7 +249,7 @@ public class WebWeixinApi {
return JSONObject.parseObject(XML.toJSONObject(res).toString()).getJSONObject("error"); return JSONObject.parseObject(XML.toJSONObject(res).toString()).getJSONObject("error");
} catch (Exception e) { } catch (Exception e) {
logger.error("获取登录认证码异常", e); log.error("获取登录认证码异常", e);
return null; return null;
} }
} }
@ -262,9 +261,9 @@ public class WebWeixinApi {
* @param urlVersion url版本号 * @param urlVersion url版本号
* @param baseRequest BaseRequest * @param baseRequest BaseRequest
*/ */
public void logout(HttpClient httpClient, public static void logout(HttpClient httpClient,
String urlVersion, String urlVersion,
BaseRequest baseRequest) { BaseRequest baseRequest) {
try { try {
List<NameValuePair> pairList = new ArrayList<>(); List<NameValuePair> pairList = new ArrayList<>();
pairList.add(new BasicNameValuePair("sid", baseRequest.getSid())); pairList.add(new BasicNameValuePair("sid", baseRequest.getSid()));
@ -287,7 +286,7 @@ public class WebWeixinApi {
httpClient.execute(httpPost); httpClient.execute(httpPost);
} }
} catch (Exception e) { } catch (Exception e) {
logger.error("退出登录异常", e); log.error("退出登录异常", e);
} }
} }
@ -299,9 +298,9 @@ public class WebWeixinApi {
* @param wxuin uin * @param wxuin uin
* @return 返回数据 * @return 返回数据
*/ */
public JSONObject pushLogin(HttpClient httpClient, public static JSONObject pushLogin(HttpClient httpClient,
String urlVersion, String urlVersion,
String wxuin) { String wxuin) {
try { try {
String url = new ST(PropertiesUtil.getProperty("webwx-url.pushlogin_url")) String url = new ST(PropertiesUtil.getProperty("webwx-url.pushlogin_url"))
.add("urlVersion", urlVersion) .add("urlVersion", urlVersion)
@ -322,7 +321,7 @@ public class WebWeixinApi {
return JSONObject.parseObject(res); return JSONObject.parseObject(res);
} catch (Exception e) { } catch (Exception e) {
logger.error("push登录异常", e); log.error("push登录异常", e);
return null; return null;
} }
} }
@ -336,10 +335,10 @@ public class WebWeixinApi {
* @param baseRequest BaseRequest * @param baseRequest BaseRequest
* @return 返回数据 * @return 返回数据
*/ */
public JSONObject webWeixinInit(HttpClient httpClient, public static JSONObject webWeixinInit(HttpClient httpClient,
String urlVersion, String urlVersion,
String passticket, String passticket,
BaseRequest baseRequest) { BaseRequest baseRequest) {
try { try {
String url = new ST(PropertiesUtil.getProperty("webwx-url.webwxinit_url")) String url = new ST(PropertiesUtil.getProperty("webwx-url.webwxinit_url"))
.add("urlVersion", urlVersion) .add("urlVersion", urlVersion)
@ -366,7 +365,7 @@ public class WebWeixinApi {
return JSONObject.parseObject(res); return JSONObject.parseObject(res);
} catch (Exception e) { } catch (Exception e) {
logger.error("获取初始化数据异常", e); log.error("获取初始化数据异常", e);
return null; return null;
} }
} }
@ -381,11 +380,11 @@ public class WebWeixinApi {
* @param loginUserName 当前登录账号用户名 * @param loginUserName 当前登录账号用户名
* @return 返回数据 * @return 返回数据
*/ */
public JSONObject statusNotify(HttpClient httpClient, public static JSONObject statusNotify(HttpClient httpClient,
String urlVersion, String urlVersion,
String passticket, String passticket,
BaseRequest baseRequest, BaseRequest baseRequest,
String loginUserName) { String loginUserName) {
try { try {
String url = new ST(PropertiesUtil.getProperty("webwx-url.statusnotify_url")) String url = new ST(PropertiesUtil.getProperty("webwx-url.statusnotify_url"))
.add("urlVersion", urlVersion) .add("urlVersion", urlVersion)
@ -415,7 +414,7 @@ public class WebWeixinApi {
return JSONObject.parseObject(res); return JSONObject.parseObject(res);
} catch (Exception e) { } catch (Exception e) {
logger.error("开启消息状态通知异常", e); log.error("开启消息状态通知异常", e);
return null; return null;
} }
} }
@ -429,10 +428,10 @@ public class WebWeixinApi {
* @param syncKeyList SyncKeyList * @param syncKeyList SyncKeyList
* @return 返回数据 * @return 返回数据
*/ */
public JSONObject syncCheck(HttpClient httpClient, public static JSONObject syncCheck(HttpClient httpClient,
String urlVersion, String urlVersion,
BaseRequest baseRequest, BaseRequest baseRequest,
JSONArray syncKeyList) { JSONArray syncKeyList) {
try { try {
long millis = System.currentTimeMillis(); long millis = System.currentTimeMillis();
String url = new ST(PropertiesUtil.getProperty("webwx-url.synccheck_url")) String url = new ST(PropertiesUtil.getProperty("webwx-url.synccheck_url"))
@ -474,7 +473,7 @@ public class WebWeixinApi {
return result; return result;
} catch (Exception e) { } catch (Exception e) {
logger.error("服务端状态同步异常", e); log.error("服务端状态同步异常", e);
return null; return null;
} }
} }
@ -488,10 +487,10 @@ public class WebWeixinApi {
* @param skey skey * @param skey skey
* @return 返回数据 * @return 返回数据
*/ */
public JSONObject getContact(HttpClient httpClient, public static JSONObject getContact(HttpClient httpClient,
String urlVersion, String urlVersion,
String passticket, String passticket,
String skey) { String skey) {
try { try {
String url = new ST(PropertiesUtil.getProperty("webwx-url.getcontact_url")) String url = new ST(PropertiesUtil.getProperty("webwx-url.getcontact_url"))
.add("urlVersion", urlVersion) .add("urlVersion", urlVersion)
@ -513,7 +512,7 @@ public class WebWeixinApi {
return JSONObject.parseObject(res); return JSONObject.parseObject(res);
} catch (Exception e) { } catch (Exception e) {
logger.error("获取全部联系人列表异常", e); log.error("获取全部联系人列表异常", e);
return null; return null;
} }
} }
@ -528,11 +527,11 @@ public class WebWeixinApi {
* @param batchContactList 联系人列表 * @param batchContactList 联系人列表
* @return 返回数据 * @return 返回数据
*/ */
public JSONObject batchGetContact(HttpClient httpClient, public static JSONObject batchGetContact(HttpClient httpClient,
String urlVersion, String urlVersion,
String passticket, String passticket,
BaseRequest baseRequest, BaseRequest baseRequest,
JSONArray batchContactList) { JSONArray batchContactList) {
try { try {
String url = new ST(PropertiesUtil.getProperty("webwx-url.batchgetcontact_url")) String url = new ST(PropertiesUtil.getProperty("webwx-url.batchgetcontact_url"))
.add("urlVersion", urlVersion) .add("urlVersion", urlVersion)
@ -561,7 +560,7 @@ public class WebWeixinApi {
return JSONObject.parseObject(res); return JSONObject.parseObject(res);
} catch (Exception e) { } catch (Exception e) {
logger.error("批量获取指定联系人信息异常", e); log.error("批量获取指定联系人信息异常", e);
return null; return null;
} }
} }
@ -576,11 +575,11 @@ public class WebWeixinApi {
* @param syncKey syncKey * @param syncKey syncKey
* @return 返回数据 * @return 返回数据
*/ */
public JSONObject webWxSync(HttpClient httpClient, public static JSONObject webWxSync(HttpClient httpClient,
String urlVersion, String urlVersion,
String passticket, String passticket,
BaseRequest baseRequest, BaseRequest baseRequest,
JSONObject syncKey) { JSONObject syncKey) {
try { try {
String url = new ST(PropertiesUtil.getProperty("webwx-url.webwxsync_url")) String url = new ST(PropertiesUtil.getProperty("webwx-url.webwxsync_url"))
.add("urlVersion", urlVersion) .add("urlVersion", urlVersion)
@ -609,7 +608,7 @@ public class WebWeixinApi {
return JSONObject.parseObject(res); return JSONObject.parseObject(res);
} catch (Exception e) { } catch (Exception e) {
logger.error("从服务端同步新数据异常", e); log.error("从服务端同步新数据异常", e);
return null; return null;
} }
} }
@ -624,11 +623,11 @@ public class WebWeixinApi {
* @param message 消息 * @param message 消息
* @return 返回数据 * @return 返回数据
*/ */
public JSONObject sendMsg(HttpClient httpClient, public static JSONObject sendMsg(HttpClient httpClient,
String urlVersion, String urlVersion,
String passticket, String passticket,
BaseRequest baseRequest, BaseRequest baseRequest,
WxMessage message) { WxMessage message) {
try { try {
String url = new ST(PropertiesUtil.getProperty("webwx-url.webwxsendmsg_url")) String url = new ST(PropertiesUtil.getProperty("webwx-url.webwxsendmsg_url"))
.add("urlVersion", urlVersion) .add("urlVersion", urlVersion)
@ -656,7 +655,7 @@ public class WebWeixinApi {
return JSONObject.parseObject(res); return JSONObject.parseObject(res);
} catch (Exception e) { } catch (Exception e) {
logger.error("发送消息异常", e); log.error("发送消息异常", e);
return null; return null;
} }
} }
@ -674,18 +673,20 @@ public class WebWeixinApi {
* @param mediaData 媒体文件二进制数据 * @param mediaData 媒体文件二进制数据
* @param mediaName 媒体文件名称 * @param mediaName 媒体文件名称
* @param contentType 媒体文件类型 * @param contentType 媒体文件类型
* @param mediaType 媒体类型
* @return 返回数据 * @return 返回数据
*/ */
public JSONObject uploadMedia(HttpClient httpClient, public static JSONObject uploadMedia(HttpClient httpClient,
String urlVersion, String urlVersion,
String passticket, String passticket,
BaseRequest baseRequest, BaseRequest baseRequest,
String fromUserName, String fromUserName,
String toUserName, String toUserName,
String dataTicket, String dataTicket,
byte[] mediaData, byte[] mediaData,
String mediaName, String mediaName,
ContentType contentType) { ContentType contentType,
MediaType mediaType) {
try { try {
String url = new ST(PropertiesUtil.getProperty("webwx-url.uploadmedia_url")) String url = new ST(PropertiesUtil.getProperty("webwx-url.uploadmedia_url"))
.add("urlVersion", urlVersion) .add("urlVersion", urlVersion)
@ -693,7 +694,6 @@ public class WebWeixinApi {
long millis = System.currentTimeMillis(); long millis = System.currentTimeMillis();
int mediaLength = mediaData.length; int mediaLength = mediaData.length;
// String mimeType = contentType.getMimeType();
HttpPost httpPost = new HttpPost(url); HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("Content-type", ContentType.MULTIPART_FORM_DATA.toString()); httpPost.setHeader("Content-type", ContentType.MULTIPART_FORM_DATA.toString());
@ -705,7 +705,7 @@ public class WebWeixinApi {
uploadmediarequest.put("TotalLen", mediaLength); uploadmediarequest.put("TotalLen", mediaLength);
uploadmediarequest.put("StartPos", 0); uploadmediarequest.put("StartPos", 0);
uploadmediarequest.put("DataLen", mediaLength); uploadmediarequest.put("DataLen", mediaLength);
uploadmediarequest.put("MediaType", 4); uploadmediarequest.put(MediaType.REQUEST_JSON_KEY, mediaType.getCode());
uploadmediarequest.put("FromUserName", fromUserName); uploadmediarequest.put("FromUserName", fromUserName);
uploadmediarequest.put("ToUserName", toUserName); uploadmediarequest.put("ToUserName", toUserName);
uploadmediarequest.put("FileMd5", DigestUtils.md5Hex(mediaData)); uploadmediarequest.put("FileMd5", DigestUtils.md5Hex(mediaData));
@ -722,14 +722,9 @@ public class WebWeixinApi {
HttpEntity paramEntity = MultipartEntityBuilder.create() HttpEntity paramEntity = MultipartEntityBuilder.create()
.setMode(HttpMultipartMode.BROWSER_COMPATIBLE) .setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
// .addTextBody("id", StringUtil.getUuid(), ContentType.TEXT_PLAIN)
// .addTextBody("name", mediaName, ContentType.TEXT_PLAIN)
// .addTextBody("type", mimeType, ContentType.TEXT_PLAIN)
// .addTextBody("lastModifieDate", String.valueOf(millis), ContentType.TEXT_PLAIN)
// .addTextBody("size", String.valueOf(mediaLength), ContentType.TEXT_PLAIN)
.addTextBody("chunks", String.valueOf(chunks)) .addTextBody("chunks", String.valueOf(chunks))
.addTextBody("chunk", String.valueOf(chunk)) .addTextBody("chunk", String.valueOf(chunk))
// .addTextBody("mediatype", WechatUtil.getMediatype(mimeType), ContentType.TEXT_PLAIN) .addTextBody(MediaType.REQUEST_KEY, mediaType.getValue(), ContentType.TEXT_PLAIN)
.addTextBody("uploadmediarequest", uploadmediarequest.toJSONString(), ContentType.TEXT_PLAIN) .addTextBody("uploadmediarequest", uploadmediarequest.toJSONString(), ContentType.TEXT_PLAIN)
.addTextBody("webwx_data_ticket", dataTicket, ContentType.TEXT_PLAIN) .addTextBody("webwx_data_ticket", dataTicket, ContentType.TEXT_PLAIN)
.addTextBody("pass_ticket", passticket, ContentType.TEXT_PLAIN) .addTextBody("pass_ticket", passticket, ContentType.TEXT_PLAIN)
@ -763,7 +758,7 @@ public class WebWeixinApi {
return result; return result;
} catch (Exception e) { } catch (Exception e) {
logger.error("上传媒体文件异常", e); log.error("上传媒体文件异常", e);
return null; return null;
} }
} }
@ -778,11 +773,11 @@ public class WebWeixinApi {
* @param message 消息 * @param message 消息
* @return 返回数据 * @return 返回数据
*/ */
public JSONObject sendImageMsg(HttpClient httpClient, public static JSONObject sendImageMsg(HttpClient httpClient,
String urlVersion, String urlVersion,
String passticket, String passticket,
BaseRequest baseRequest, BaseRequest baseRequest,
MediaMessage message) { MediaMessage message) {
try { try {
String url = new ST(PropertiesUtil.getProperty("webwx-url.webwxsendmsgimg_url")) String url = new ST(PropertiesUtil.getProperty("webwx-url.webwxsendmsgimg_url"))
.add("urlVersion", urlVersion) .add("urlVersion", urlVersion)
@ -810,7 +805,51 @@ public class WebWeixinApi {
return JSONObject.parseObject(res); return JSONObject.parseObject(res);
} catch (Exception e) { } catch (Exception e) {
logger.error("发送图片消息异常", e); log.error("发送图片消息异常", e);
return null;
}
}
/**
* 发送视频消息
*
* @param httpClient http客户端
* @param urlVersion url版本号
* @param baseRequest BaseRequest
* @param message 消息
* @return 返回数据
*/
public static JSONObject sendVideoMsg(HttpClient httpClient,
String urlVersion,
BaseRequest baseRequest,
MediaMessage message) {
try {
String url = new ST(PropertiesUtil.getProperty("webwx-url.webwxsendvideomsg_url"))
.add("urlVersion", urlVersion)
.render();
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("Content-type", ContentType.APPLICATION_JSON.toString());
JSONObject paramJson = new JSONObject();
paramJson.put("BaseRequest", baseRequest);
paramJson.put("Msg", message);
paramJson.put("Scene", 0);
HttpEntity paramEntity = new StringEntity(paramJson.toJSONString(), Consts.UTF_8);
httpPost.setEntity(paramEntity);
HttpResponse response = httpClient.execute(httpPost);
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) {
log.error("发送视频消息异常", e);
return null; return null;
} }
} }

View File

@ -31,4 +31,6 @@ webwx-url.webwxsendmsg_url=https://wx<urlVersion>.qq.com/cgi-bin/mmwebwx-bin/web
## 4.3、上传媒体文件 ## 4.3、上传媒体文件
webwx-url.uploadmedia_url=https://file.wx<urlVersion>.qq.com/cgi-bin/mmwebwx-bin/webwxuploadmedia?f=json webwx-url.uploadmedia_url=https://file.wx<urlVersion>.qq.com/cgi-bin/mmwebwx-bin/webwxuploadmedia?f=json
## 4.4、发送图片消息 ## 4.4、发送图片消息
webwx-url.webwxsendmsgimg_url=https://wx<urlVersion>.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsgimg?fun=async&f=json&lang=zh_CN&pass_ticket=<pass_ticket> webwx-url.webwxsendmsgimg_url=https://wx<urlVersion>.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsgimg?fun=async&f=json&lang=zh_CN&pass_ticket=<pass_ticket>
## 4.5、发送视频消息
webwx-url.webwxsendvideomsg_url=https://wx<urlVersion>.qq.com/cgi-bin/mmwebwx-bin/webwxsendvideomsg?fun=async&f=json

View File

@ -1,9 +1,9 @@
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.hotlcc.wechat4j.Wechat; import com.hotlcc.wechat4j.Wechat;
import com.hotlcc.wechat4j.api.WebWeixinApi;
import com.hotlcc.wechat4j.handler.ReceivedMsgHandler; import com.hotlcc.wechat4j.handler.ReceivedMsgHandler;
import com.hotlcc.wechat4j.model.ReceivedMsg; import com.hotlcc.wechat4j.model.ReceivedMsg;
import com.hotlcc.wechat4j.model.UserInfo; import com.hotlcc.wechat4j.model.UserInfo;
import com.hotlcc.wechat4j.util.CommonUtil;
import com.hotlcc.wechat4j.util.StringUtil; import com.hotlcc.wechat4j.util.StringUtil;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -16,8 +16,6 @@ public class TestClass {
@Before @Before
public void initAndLogin() { public void initAndLogin() {
wechat = new Wechat(); wechat = new Wechat();
WebWeixinApi api = new WebWeixinApi();
wechat.setWebWeixinApi(api);
wechat.addReceivedMsgHandler(new ReceivedMsgHandler() { wechat.addReceivedMsgHandler(new ReceivedMsgHandler() {
@Override @Override
public void handleAllType(Wechat wechat, ReceivedMsg msg) { public void handleAllType(Wechat wechat, ReceivedMsg msg) {
@ -37,9 +35,13 @@ public class TestClass {
@Test @Test
public void testSendImage() { public void testSendImage() {
File file = new File("D:\\Downloads\\images\\6600e90b8b0ce2037a5291a7147ffd2b.jpeg"); File file = null;
JSONObject result = null;
JSONObject result = wechat.sendImage(null, file); file = new File("C:\\Users\\Administrator\\Pictures\\壁纸\\9e5f4981099bcf351e0ec18c3654aced.jpg");
result = wechat.sendImage(null, file);
file = new File("C:\\Users\\Administrator\\Videos\\手机QQ视频_20190416170016.mp4");
result = wechat.sendVideo(null, file);
System.out.println(result); System.out.println(result);
while (true) CommonUtil.threadSleep(5000);
} }
} }