mirror of
https://github.com/ttttupup/wxhelper.git
synced 2024-11-24 19:29:25 +08:00
commit
8229a15089
@ -11,6 +11,9 @@ com.example.wxhk.tcp.vertx.VertxTcp 这个是tcp服务端,接受信息
|
||||
com.example.wxhk.tcp.vertx.InitWeChat 微信环境初始化
|
||||
|
||||
com.example.wxhk.tcp.vertx.ArrHandle 循环消息处理
|
||||
|
||||
com.example.wxhk.server.WxSmgServer 为消息处理接口,实现其中的方法即可
|
||||
|
||||
![image](https://github.com/sglmsn/wxhelper/assets/36943585/59d49401-a492-46a9-8ed9-dab7fb1822b4)
|
||||
|
||||
|
||||
|
@ -17,6 +17,8 @@ public enum WxMsgType {
|
||||
表情(47),
|
||||
转账和收款(49),
|
||||
收到转账之后或者文件助手等信息(51),
|
||||
|
||||
入群(10000),
|
||||
/**
|
||||
* 扫码触发,会触发2次, 有一次有编号,一次没有,还有登陆之后也有,很多情况都会调用这个
|
||||
*/
|
||||
|
@ -0,0 +1,21 @@
|
||||
package com.example.wxhk.model.dto;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 支付信息
|
||||
*
|
||||
* @author wt
|
||||
* @param receiverUsername 付款人
|
||||
* @param decimal 收款金额
|
||||
* @param remark 备注
|
||||
* @param transcationid
|
||||
* @param transferid
|
||||
* @date 2023/06/06
|
||||
*/
|
||||
public record PayoutInformation(String receiverUsername, BigDecimal decimal, String remark,String transcationid,String transferid) implements java.io.Serializable {
|
||||
|
||||
public PayoutInformation(String receiverUsername, BigDecimal decimal, String remark) {
|
||||
this(receiverUsername, decimal, remark, null, null);
|
||||
}
|
||||
}
|
@ -2,15 +2,13 @@ package com.example.wxhk.msg;
|
||||
|
||||
import com.example.wxhk.constant.WxMsgType;
|
||||
import com.example.wxhk.model.PrivateChatMsg;
|
||||
import com.example.wxhk.model.dto.PayoutInformation;
|
||||
import com.example.wxhk.server.WxSmgServer;
|
||||
import com.example.wxhk.tcp.vertx.InitWeChat;
|
||||
import com.example.wxhk.util.HttpAsyncUtil;
|
||||
import com.example.wxhk.util.HttpSendUtil;
|
||||
import com.example.wxhk.util.HttpSyncUtil;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.core.util.XmlUtil;
|
||||
import org.dromara.hutool.log.Log;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
@ -20,7 +18,6 @@ import org.w3c.dom.NodeList;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
@ -38,40 +35,36 @@ public class WxMsgHandle {
|
||||
*/
|
||||
public static ConcurrentHashMap<String, String> collection_code_caching = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
public static WxSmgServer wxSmgServer;
|
||||
/**
|
||||
* 看
|
||||
*/
|
||||
public static final ReentrantReadWriteLock LOOK = new ReentrantReadWriteLock();
|
||||
|
||||
@Autowired
|
||||
public void setWxSmgServer(WxSmgServer wxSmgServer) {
|
||||
WxMsgHandle.wxSmgServer = wxSmgServer;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
add(chatMsg -> {
|
||||
if (Objects.equals(chatMsg.getIsSendMsg(), 1) && Objects.equals(chatMsg.getIsSendByPhone(), 1)) {
|
||||
log.info("手机端对:{}发出:{}", chatMsg.getFromUser(), chatMsg.getContent());
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
wxSmgServer.私聊(chatMsg);
|
||||
return null;
|
||||
}, WxMsgType.私聊信息);
|
||||
add(chatMsg -> {
|
||||
if (FILEHELPER.equals(chatMsg.getFromUser())) {
|
||||
log.info("文件助手:{},", chatMsg.getContent());
|
||||
wxSmgServer.文件助手(chatMsg);
|
||||
}
|
||||
return 1;
|
||||
}, WxMsgType.收到转账之后或者文件助手等信息);
|
||||
add(chatMsg -> {
|
||||
if (FILEHELPER.equals(chatMsg.getFromUser())) {
|
||||
Document document = XmlUtil.parseXml(chatMsg.getContent());
|
||||
Element documentElement = document.getDocumentElement();
|
||||
String username = documentElement.getAttribute("username");
|
||||
if (StrUtil.isNotBlank(username)) {
|
||||
HttpSendUtil.发送文本(username);
|
||||
}
|
||||
}
|
||||
wxSmgServer.收到名片(chatMsg);
|
||||
return 1;
|
||||
}, WxMsgType.收到名片);
|
||||
add(chatMsg -> {
|
||||
HttpSendUtil.通过好友请求(chatMsg);
|
||||
wxSmgServer.收到好友请求(chatMsg);
|
||||
return 1;
|
||||
}, WxMsgType.好友请求);// 好友请求
|
||||
add(chatMsg -> {
|
||||
@ -148,7 +141,7 @@ public class WxMsgHandle {
|
||||
String substring = monery.substring(1);
|
||||
BigDecimal decimal = new BigDecimal(substring);
|
||||
log.info("扫码收款:{},付款人:{},付款备注:{}", decimal.stripTrailingZeros().toPlainString(), next.getValue(), remark);
|
||||
HttpSendUtil.发送文本(next.getValue(), StrUtil.format("扫码收款:{},备注:{}", decimal.stripTrailingZeros().toPlainString(), remark));
|
||||
wxSmgServer.扫码收款(new PayoutInformation(next.getValue(),decimal,remark));
|
||||
iterator.remove();
|
||||
return false;
|
||||
}
|
||||
@ -174,18 +167,18 @@ public class WxMsgHandle {
|
||||
String remark = documentElement.getElementsByTagName("pay_memo").item(0).getTextContent();
|
||||
String monery = documentElement.getElementsByTagName("feedesc").item(0).getTextContent();
|
||||
String receiver_username = documentElement.getElementsByTagName("receiver_username").item(0).getTextContent();
|
||||
// 如果是机器人发出的,则跳过解析
|
||||
if (InitWeChat.WXID_MAP.contains(receiver_username) ) {
|
||||
// 如果是自己转出去的,则不需要解析了
|
||||
return false;
|
||||
}
|
||||
|
||||
if (monery.startsWith("¥")) {
|
||||
String substring = monery.substring(1);
|
||||
BigDecimal decimal = new BigDecimal(substring);
|
||||
log.info("收款:{},付款人:{},付款备注:{}", decimal.stripTrailingZeros().toPlainString(), receiver_username, remark);
|
||||
HttpSendUtil.发送文本(receiver_username, StrUtil.format("收到款项:{},备注:{}", decimal.stripTrailingZeros().toPlainString(), remark));
|
||||
log.info("收款:{},付款人:{},付款备注:{}", decimal.stripTrailingZeros().toPlainString(), chatMsg.getFromUser(), remark);
|
||||
wxSmgServer.收款之后(new PayoutInformation(chatMsg.getFromUser(), decimal, remark));
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -218,13 +211,19 @@ public class WxMsgHandle {
|
||||
// 如果不是机器人收款,则认为不需要解析了,大概率是机器人自己发出去的
|
||||
return false;
|
||||
}
|
||||
|
||||
String remark = document.getElementsByTagName("pay_memo").item(0).getTextContent();
|
||||
String monery = document.getElementsByTagName("feedesc").item(0).getTextContent();
|
||||
String receiver_username = document.getElementsByTagName("receiver_username").item(0).getTextContent();
|
||||
if (monery.startsWith("¥")) {
|
||||
String substring = monery.substring(1);
|
||||
BigDecimal decimal = new BigDecimal(substring);
|
||||
Node transcationid = document.getDocumentElement().getElementsByTagName("transcationid").item(0);
|
||||
Node transferid = document.getDocumentElement().getElementsByTagName("transferid").item(0);
|
||||
HttpSyncUtil.exec(HttpAsyncUtil.Type.确认收款, new JsonObject().put("wxid", chatMsg.getFromUser())
|
||||
.put("transcationId", transcationid.getTextContent())
|
||||
.put("transferId", transferid.getTextContent()));
|
||||
wxSmgServer.接到收款(new PayoutInformation(chatMsg.getFromUser(), decimal, remark, transcationid.getTextContent(), transferid.getTextContent()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error(e);
|
||||
|
@ -0,0 +1,30 @@
|
||||
package com.example.wxhk.server;
|
||||
|
||||
import com.example.wxhk.model.PrivateChatMsg;
|
||||
import com.example.wxhk.model.dto.PayoutInformation;
|
||||
|
||||
/**
|
||||
* 微信消息处理提取
|
||||
* @author wt
|
||||
* @date 2023/06/06
|
||||
*/
|
||||
public interface WxSmgServer {
|
||||
/**
|
||||
* 接到收款
|
||||
*
|
||||
* @param payoutInformation 支付信息
|
||||
*/
|
||||
void 接到收款(PayoutInformation payoutInformation);
|
||||
|
||||
void 收款之后(PayoutInformation pay);
|
||||
|
||||
void 私聊(PrivateChatMsg chatMsg);
|
||||
|
||||
void 文件助手(PrivateChatMsg chatMsg);
|
||||
|
||||
void 收到名片(PrivateChatMsg chatMsg);
|
||||
|
||||
void 收到好友请求(PrivateChatMsg chatMsg);
|
||||
|
||||
void 扫码收款(PayoutInformation payoutInformation);
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package com.example.wxhk.server.impl;
|
||||
|
||||
import com.example.wxhk.model.PrivateChatMsg;
|
||||
import com.example.wxhk.model.dto.PayoutInformation;
|
||||
import com.example.wxhk.model.request.ConfirmThePayment;
|
||||
import com.example.wxhk.util.HttpSendUtil;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.core.util.XmlUtil;
|
||||
import org.dromara.hutool.log.Log;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Service
|
||||
public class WxSmgServerImpl implements com.example.wxhk.server.WxSmgServer {
|
||||
|
||||
protected static final Log log=Log.get();
|
||||
|
||||
public static final String FILEHELPER = "filehelper";
|
||||
@Override
|
||||
public void 接到收款(PayoutInformation payoutInformation) {
|
||||
HttpSendUtil.确认收款(new ConfirmThePayment().setWxid(payoutInformation.receiverUsername()).setTranscationId(payoutInformation.transcationid()).setTransferId(payoutInformation.transferid()));
|
||||
}
|
||||
@Override
|
||||
public void 收款之后(PayoutInformation pay) {
|
||||
HttpSendUtil.发送文本(pay.receiverUsername(), StrUtil.format("收到款项:{},备注:{}", pay.decimal().stripTrailingZeros().toPlainString(), pay.remark()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void 私聊(PrivateChatMsg chatMsg) {
|
||||
if (Objects.equals(chatMsg.getIsSendMsg(), 1) && Objects.equals(chatMsg.getIsSendByPhone(), 1)) {
|
||||
log.info("手机端对:{}发出:{}", chatMsg.getFromUser(), chatMsg.getContent());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void 文件助手(PrivateChatMsg chatMsg) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void 收到名片(PrivateChatMsg chatMsg) {
|
||||
if (FILEHELPER.equals(chatMsg.getFromUser())) {
|
||||
Document document = XmlUtil.parseXml(chatMsg.getContent());
|
||||
Element documentElement = document.getDocumentElement();
|
||||
String username = documentElement.getAttribute("username");
|
||||
if (StrUtil.isNotBlank(username)) {
|
||||
HttpSendUtil.发送文本(username);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void 收到好友请求(PrivateChatMsg chatMsg) {
|
||||
HttpSendUtil.通过好友请求(chatMsg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void 扫码收款(PayoutInformation payoutInformation) {
|
||||
HttpSendUtil.发送文本(payoutInformation.receiverUsername(), StrUtil.format("扫码收款:{},备注:{}", payoutInformation.decimal().stripTrailingZeros().toPlainString(), payoutInformation.remark()));
|
||||
}
|
||||
}
|
@ -150,9 +150,8 @@ public class InitWeChat implements CommandLineRunner {
|
||||
}
|
||||
|
||||
});
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
HttpSyncUtil.exec(HttpAsyncUtil.Type.关闭hook, new JsonObject());
|
||||
}));
|
||||
// FIXME: 2023/6/2 程序结束后关闭hook会偶尔出现微信闪退情况,暂时禁用
|
||||
// Runtime.getRuntime().addShutdownHook(new Thread(HttpSendUtil::关闭hook));
|
||||
//netstat -aon|findstr "端口号"
|
||||
// c.exe -I 4568 -p D:\exec\wxhelper.dll -m 4568
|
||||
}
|
||||
|
@ -117,6 +117,11 @@ public class HttpSendUtil {
|
||||
}
|
||||
|
||||
|
||||
public static JsonObject 确认收款(ConfirmThePayment payment){
|
||||
return HttpSyncUtil.exec(HttpAsyncUtil.Type.确认收款, payment.toJson());
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
public static com.example.wxhk.infe.SendMsg of(HttpAsyncUtil.Type type) {
|
||||
switch (type) {
|
||||
|
@ -81,4 +81,12 @@ public class XmlTest {
|
||||
String alias = documentElement.getAttribute("alias");
|
||||
Console.log(alias,username);
|
||||
}
|
||||
|
||||
@Test
|
||||
void 公众号(){
|
||||
String con = "{\"content\":\"请问您指的是账单的什么问题呢?请回复数字选择:\\n1.如何导出微信账单记录\\n2.如何查看已删除账单\\n3.怎么删除交易记录\",\"fromGroup\":\"gh_3dfda90e39d6\",\"fromUser\":\"gh_3dfda90e39d6\",\"isSendMsg\":0,\"msgId\":9025889923001869810,\"pid\":9920,\"sign\":\"0a66d3dab6b64ca646f512cd278d5f3d\",\"signature\":\"<msgsource>\\n\\t<tips>3</tips>\\n\\t<bizmsg>\\n\\t\\t<bizmsgshowtype>3</bizmsgshowtype>\\n\\t\\t<bizmsgfromuser><![CDATA[gh_3dfda90e39d6]]></bizmsgfromuser>\\n\\t</bizmsg>\\n\\t<msg_cluster_type>1</msg_cluster_type>\\n\\t<service_type>1</service_type>\\n\\t<scene>13</scene>\\n\\t<signature>v1_iJNyfNLb</signature>\\n\\t<tmp_node>\\n\\t\\t<publisher-id><![CDATA[]]></publisher-id>\\n\\t</tmp_node>\\n</msgsource>\\n\",\"time\":\"2023-06-05 11:32:17\",\"timestamp\":1685935937,\"type\":1}";
|
||||
PrivateChatMsg privateChatMsg = new JsonObject(con).mapTo(PrivateChatMsg.class);
|
||||
Document document = XmlUtil.parseXml(privateChatMsg.getSignature());
|
||||
Element documentElement = document.getDocumentElement();
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,10 @@ class HttpSendUtilTest {
|
||||
void 开启hook() {
|
||||
|
||||
}
|
||||
@Test
|
||||
void 关闭ook() {
|
||||
HttpSendUtil.关闭hook();
|
||||
}
|
||||
|
||||
@Test
|
||||
void 获取群成员() {
|
||||
|
Loading…
Reference in New Issue
Block a user