diff --git a/clients/java/wcf-bmc/CHANGELOG.md b/clients/java/wcf-bmc/CHANGELOG.md index a1e325e..8bbc5a9 100644 --- a/clients/java/wcf-bmc/CHANGELOG.md +++ b/clients/java/wcf-bmc/CHANGELOG.md @@ -32,37 +32,45 @@ ___ ### 功能列表 -| 接口名 | 地址 | -|----------------|------------------------| -| 查询登录状态 | /loginStatus | -| 获取登录微信内部识别号UID | /loginWeChatUid | -| 获取登录微信信息 | /loginWeChatInfo | -| 获取消息类型列表 | /list/msgType | -| 获取联系人列表 | /list/contacts | -| 获取数据库表名称列表 | /list/dbTableName | -| 获取指定数据库中的表列表 | /list/dbTable | -| 执行数据库查询SQL | /exec/dbQuerySql | -| 发送消息汇总入口 | /send/msgMaster | -| 发送文本消息 | /send/textMsg | -| 发送富文本消息 | /send/richTextMsg | -| 发送XML消息 | /send/xmlMsg | -| 发送图片消息 | /send/imageMsg | -| 发送表情消息 | /send/emojiMsg | -| 发送文件消息 | /send/fileMsg | -| 拍一拍群友 | /patOnePat | -| 撤回消息 | /revokeMsg | -| 通过好友申请 | /passFriendApply | -| 添加群成员为微信好友 | /addFriend/groupMember | -| 查询群成员 | /groupMember/list | -| 邀请群成员 | /groupMember/invite | -| 删除群成员 | /groupMember/delete | -| 查询朋友圈 | /friendCircle | -| 接收转账 | /receiveTransfer | +| 接口名 | 地址 | +|--------------|------------------------| +| 查询登录状态 | /loginStatus | +| 获取登录微信号 | /loginWeChatUid | +| 获取登录微信信息 | /loginWeChatInfo | +| 获取消息类型列表 | /list/msgType | +| 获取联系人列表 | /list/contacts | +| 获取数据库表名称列表 | /list/dbTableName | +| 获取指定数据库中的表列表 | /list/dbTable | +| 执行数据库查询SQL | /exec/dbQuerySql | +| 发送消息汇总入口 | /send/msgMaster | +| 发送文本消息 | /send/textMsg | +| 发送富文本消息 | /send/richTextMsg | +| 发送XML消息 | /send/xmlMsg | +| 发送图片消息 | /send/imageMsg | +| 发送表情消息 | /send/emojiMsg | +| 发送文件消息 | /send/fileMsg | +| 拍一拍群友 | /patOnePat | +| 撤回消息 | /revokeMsg | +| 通过好友申请 | /passFriendApply | +| 添加群成员为微信好友 | /addFriend/groupMember | +| 查询群成员 | /groupMember/list | +| 邀请群成员 | /groupMember/invite | +| 删除群成员 | /groupMember/delete | +| 查询朋友圈 | /friendCircle | +| 接收转账 | /receiveTransfer | ### 已知bug v39.5.2版本目前会出现注入失败的情况,待排查修复,可先使用v39.5.1,只须替换dll版本即可 +### 2025-05-04 + +- 1.更新拍一拍接口入参 +- 2.客户端内置方法名与PY版本保持一致 +- 3.适配指定参数查询接口 + +
+ ### 2025-05-03 - 1.更新dll为v39.5.2 @@ -87,32 +95,32 @@ ___ ### 功能列表 -| 接口名 | 地址 | 是否支持 | 备注 | -|----------------|------------------------|------|--------| -| 查询登录状态 | /loginStatus | ✔️ | 已测试 | -| 获取登录微信内部识别号UID | /loginWeChatUid | ✔️ | 已测试 | -| 获取登录微信信息 | /loginWeChatInfo | ✔️ | 已测试 | -| 获取消息类型列表 | /list/msgType | ✔️ | 已测试 | -| 获取联系人列表 | /list/contacts | ✔️ | 已测试 | -| 获取数据库表名称列表 | /list/dbTableName | ✔️ | 已测试 | -| 获取指定数据库中的表列表 | /list/dbTable | ✔️ | 已测试 | -| 执行数据库查询SQL | /exec/dbQuerySql | ✔️ | 已测试 | -| 发送消息汇总入口 | /send/msgMaster | ❌ | 预留 | -| 发送文本消息 | /send/textMsg | ✔️ | 已测试 | -| 发送富文本消息 | /send/richTextMsg | ❌ | 已知BUG | -| 发送XML消息 | /send/xmlMsg | ❌ | 该版本不支持 | -| 发送图片消息 | /send/imageMsg | ✔️ | 已测试 | -| 发送表情消息 | /send/emojiMsg | ✔️ | 已测试 | -| 发送文件消息 | /send/fileMsg | ✔️ | 已测试 | -| 拍一拍群友 | /patOnePat | ✔️ | 已测试 | -| 撤回消息 | /revokeMsg | ❌ | 该版本不支持 | -| 通过好友申请 | /passFriendApply | ❌ | 该版本不支持 | -| 添加群成员为微信好友 | /addFriend/groupMember | ❔ | 待测试 | -| 查询群成员 | /groupMember/list | ✔️ | 已测试 | -| 邀请群成员 | /groupMember/invite | ❔ | 待测试 | -| 删除群成员 | /groupMember/delete | ❔ | 待测试 | -| 查询朋友圈 | /friendCircle | ❔ | 待测试 | -| 接收转账 | /receiveTransfer | ❌ | 该版本不支持 | +| 接口名 | 地址 | 是否支持 | 备注 | +|--------------|------------------------|------|--------| +| 查询登录状态 | /loginStatus | ✔️ | 已测试 | +| 获取登录微信号 | /loginWeChatUid | ✔️ | 已测试 | +| 获取登录微信信息 | /loginWeChatInfo | ✔️ | 已测试 | +| 获取消息类型列表 | /list/msgType | ✔️ | 已测试 | +| 获取联系人列表 | /list/contacts | ✔️ | 已测试 | +| 获取数据库表名称列表 | /list/dbTableName | ✔️ | 已测试 | +| 获取指定数据库中的表列表 | /list/dbTable | ✔️ | 已测试 | +| 执行数据库查询SQL | /exec/dbQuerySql | ✔️ | 已测试 | +| 发送消息汇总入口 | /send/msgMaster | ❌ | 预留 | +| 发送文本消息 | /send/textMsg | ✔️ | 已测试 | +| 发送富文本消息 | /send/richTextMsg | ❌ | 该版本不支持 | +| 发送XML消息 | /send/xmlMsg | ❌ | 该版本不支持 | +| 发送图片消息 | /send/imageMsg | ✔️ | 已测试 | +| 发送表情消息 | /send/emojiMsg | ✔️ | 已测试 | +| 发送文件消息 | /send/fileMsg | ✔️ | 已测试 | +| 拍一拍群友 | /patOnePat | ✔️ | 已测试 | +| 撤回消息 | /revokeMsg | ❌ | 该版本不支持 | +| 通过好友申请 | /passFriendApply | ❌ | 该版本不支持 | +| 添加群成员为微信好友 | /addFriend/groupMember | ❔ | 待测试 | +| 查询群成员 | /groupMember/list | ✔️ | 已测试 | +| 邀请群成员 | /groupMember/invite | ❔ | 待测试 | +| 删除群成员 | /groupMember/delete | ❔ | 待测试 | +| 查询朋友圈 | /friendCircle | ❔ | 待测试 | +| 接收转账 | /receiveTransfer | ❌ | 该版本不支持 | ### 提示 diff --git a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/controller/WeChatDllController.java b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/controller/WeChatDllController.java index 48b780c..1ae5a56 100644 --- a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/controller/WeChatDllController.java +++ b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/controller/WeChatDllController.java @@ -72,7 +72,7 @@ public class WeChatDllController { return TResponse.ok(ResponseCodeEnum.SUCCESS, status); } - @ApiOperation(value = "获取登录微信内部识别号UID", notes = "queryLoginWeChatUid") + @ApiOperation(value = "获取登录微信号", notes = "queryLoginWeChatUid") @PostMapping(value = "/loginWeChatUid") public TResponse queryLoginWeChatUid() { String weChatUid = weChatDllService.queryLoginWeChatUid(); @@ -186,6 +186,7 @@ public class WeChatDllController { @ApiOperation(value = "撤回消息", notes = "revokeMsg") @PostMapping(value = "/revokeMsg") public TResponse revokeMsg(@Validated @RequestBody WxPpWcfRevokeMsgReq request) { + weChatDllService.revokeMsg(request); return TResponse.ok(ResponseCodeEnum.SUCCESS); } @@ -246,7 +247,7 @@ public class WeChatDllController { @ApiOperation(value = "查询朋友圈", notes = "queryFriendCircle") @PostMapping(value = "/friendCircle") public TResponse queryFriendCircle() { - weChatDllService.queryFriendCircle(); + weChatDllService.queryFriendCircle(0); return TResponse.ok(ResponseCodeEnum.SUCCESS); } diff --git a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfPassFriendApplyReq.java b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfPassFriendApplyReq.java index 1c801c5..5e8bef6 100644 --- a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfPassFriendApplyReq.java +++ b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfPassFriendApplyReq.java @@ -17,23 +17,22 @@ import lombok.Data; public class WxPpWcfPassFriendApplyReq { /** - * 申请人 + * 加密用户名 * v3 xml.attrib["encryptusername"] * 加密用户名 (好友申请消息里 v3 开头的字符串) */ - @NotBlank(message = "申请人不能为空") - @ApiModelProperty(value = "申请人") - private String applicant; + @NotBlank(message = "加密用户名不能为空") + @ApiModelProperty(value = "加密用户名") + private String encryptUsername; /** - * 审核人 + * ticket * v4 xml.attrib["ticket"] * Ticket (好友申请消息里 v4 开头的字符串) - * 一般指自己,别人申请添加,自己审核是否通过 */ - @NotBlank(message = "审核人不能为空") - @ApiModelProperty(value = "审核人") - private String reviewer; + @NotBlank(message = "ticket不能为空") + @ApiModelProperty(value = "ticket") + private String ticket; /** * 场景 diff --git a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfRevokeMsgReq.java b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfRevokeMsgReq.java index 81abd17..fe84b09 100644 --- a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfRevokeMsgReq.java +++ b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfRevokeMsgReq.java @@ -19,7 +19,7 @@ public class WxPpWcfRevokeMsgReq { /** * 消息编号 */ - @ApiModelProperty(value = "场景") + @ApiModelProperty(value = "消息编号") private String msgId; } diff --git a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendEmojiMsgReq.java b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendEmojiMsgReq.java index 653724a..69b269c 100644 --- a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendEmojiMsgReq.java +++ b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendEmojiMsgReq.java @@ -16,14 +16,6 @@ import lombok.Data; @ApiModel(value = "wxPpWcfSendEmojiMsgReq", description = "个微WCF发送表情消息请求入参") public class WxPpWcfSendEmojiMsgReq { - /** - * 资源路径-本地表情路径 - * 需要确保图片路径正确,建议使用绝对路径(使用双斜杠\\) - */ - @NotBlank(message = "资源路径不能为空") - @ApiModelProperty(value = "资源路径-本地表情路径") - private String resourcePath; - /** * 消息接收人 * 消息接收人,私聊为 wxid(wxid_xxxxxxxxxxxxxx) @@ -33,4 +25,12 @@ public class WxPpWcfSendEmojiMsgReq { @ApiModelProperty(value = "消息接收人") private String recipient; + /** + * 资源路径-本地表情路径 + * 需要确保图片路径正确,建议使用绝对路径(使用双斜杠\\) + */ + @NotBlank(message = "资源路径不能为空") + @ApiModelProperty(value = "资源路径-本地表情路径") + private String resourcePath; + } diff --git a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendFileMsgReq.java b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendFileMsgReq.java index 4ba4c35..620b219 100644 --- a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendFileMsgReq.java +++ b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendFileMsgReq.java @@ -16,13 +16,6 @@ import lombok.Data; @ApiModel(value = "wxPpWcfSendFileMsgReq", description = "个微WCF发送文件消息请求入参") public class WxPpWcfSendFileMsgReq { - /** - * 资源路径-本地文件路径 - */ - @NotBlank(message = "资源路径不能为空") - @ApiModelProperty(value = "资源路径-本地文件路径") - private String resourcePath; - /** * 消息接收人 * 消息接收人,私聊为 wxid(wxid_xxxxxxxxxxxxxx) @@ -32,4 +25,11 @@ public class WxPpWcfSendFileMsgReq { @ApiModelProperty(value = "消息接收人") private String recipient; + /** + * 资源路径-本地文件路径 + */ + @NotBlank(message = "资源路径不能为空") + @ApiModelProperty(value = "资源路径-本地文件路径") + private String resourcePath; + } diff --git a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendImageMsgReq.java b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendImageMsgReq.java index 3498b5e..37f81e9 100644 --- a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendImageMsgReq.java +++ b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendImageMsgReq.java @@ -16,6 +16,15 @@ import lombok.Data; @ApiModel(value = "wxPpWcfSendImageMsgReq", description = "个微WCF发送图片消息请求入参") public class WxPpWcfSendImageMsgReq { + /** + * 消息接收人 + * 消息接收人,私聊为 wxid(wxid_xxxxxxxxxxxxxx) + * 群聊为 roomid(xxxxxxxxxx@chatroom) + */ + @NotBlank(message = "消息接收人不能为空") + @ApiModelProperty(value = "消息接收人") + private String recipient; + /** * 资源路径-本地图片地址 * 需要确保图片路径正确,建议使用绝对路径(使用双斜杠\\) @@ -26,13 +35,4 @@ public class WxPpWcfSendImageMsgReq { @ApiModelProperty(value = "资源路径-本地图片地址") private String resourcePath; - /** - * 消息接收人 - * 消息接收人,私聊为 wxid(wxid_xxxxxxxxxxxxxx) - * 群聊为 roomid(xxxxxxxxxx@chatroom) - */ - @NotBlank(message = "消息接收人不能为空") - @ApiModelProperty(value = "消息接收人") - private String recipient; - } diff --git a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendTextMsgReq.java b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendTextMsgReq.java index 042efe5..bfdfd3d 100644 --- a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendTextMsgReq.java +++ b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendTextMsgReq.java @@ -18,15 +18,6 @@ import lombok.Data; @ApiModel(value = "wxPpWcfSendTextMsgReq", description = "个微WCF发送文本消息请求入参") public class WxPpWcfSendTextMsgReq { - /** - * 消息文本 - * 消息内容(如果是 @ 消息则需要有跟 @ 的人数量相同的 @) - * 换行使用 `\\\\n` (单杠) - */ - @NotBlank(message = "消息文本不能为空") - @ApiModelProperty(value = "消息文本") - private String msgText; - /** * 消息接收人 * 消息接收人,私聊为 wxid(wxid_xxxxxxxxxxxxxx) @@ -36,6 +27,15 @@ public class WxPpWcfSendTextMsgReq { @ApiModelProperty(value = "消息接收人") private String recipient; + /** + * 消息文本 + * 消息内容(如果是 @ 消息则需要有跟 @ 的人数量相同的 @) + * 换行使用 `\\\\n` (单杠) + */ + @NotBlank(message = "消息文本不能为空") + @ApiModelProperty(value = "消息文本") + private String msgText; + /** * 要艾特的用户 * 群聊时要 @ 的人(私聊时为空字符串),多个用逗号分隔。 diff --git a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/response/WxPpWcfDatabaseTableResp.java b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/response/WxPpWcfDatabaseTableResp.java index 00369c1..c73f86e 100644 --- a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/response/WxPpWcfDatabaseTableResp.java +++ b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/response/WxPpWcfDatabaseTableResp.java @@ -21,7 +21,7 @@ public class WxPpWcfDatabaseTableResp { private String tableName; /** - * SQL + * 该数据库下的所有表名及对应建表语句 */ @ApiModelProperty(value = "SQL") private String sql; diff --git a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/handle/WeChatSocketClient.java b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/handle/WeChatSocketClient.java index 40fbf10..4e85961 100644 --- a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/handle/WeChatSocketClient.java +++ b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/handle/WeChatSocketClient.java @@ -4,6 +4,7 @@ import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ArrayBlockingQueue; @@ -16,9 +17,9 @@ import com.alibaba.fastjson2.JSONObject; import com.google.protobuf.ByteString; import com.sun.jna.Native; import com.wechat.ferry.entity.dto.WxPpMsgDTO; +import com.wechat.ferry.entity.proto.Wcf; import com.wechat.ferry.entity.proto.Wcf.DbQuery; import com.wechat.ferry.entity.proto.Wcf.DbRow; -import com.wechat.ferry.entity.proto.Wcf.DecPath; import com.wechat.ferry.entity.proto.Wcf.Functions; import com.wechat.ferry.entity.proto.Wcf.Request; import com.wechat.ferry.entity.proto.Wcf.Response; @@ -60,7 +61,7 @@ public class WeChatSocketClient { private Socket msgSocket = null; /** - * 是否收到消息 + * 是否已启动接收消息 */ private boolean isReceivingMsg = false; @@ -171,6 +172,21 @@ public class WeChatSocketClient { } /** + * 获取登录二维码,已经登录则返回空字符串 + * + * @return 是否登录结果 + */ + public Response getQrcode() { + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_REFRESH_QRCODE_VALUE).build(); + Response rsp = sendCmd(req); + if (rsp != null) { + return rsp; + } + return null; + } + + /** + * 是否已经登录 * 当前微信客户端是否登录微信号 * * @return 是否登录结果 @@ -185,9 +201,309 @@ public class WeChatSocketClient { } /** - * 获取sql执行结果 + * 获取登录账户的wxid + * + * @return 自己的微信号 + */ + public String getSelfWxId() { + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_GET_SELF_WXID_VALUE).build(); + Response rsp = sendCmd(req); + if (rsp != null) { + return rsp.getStr(); + } + return ""; + } + + /** + * 获取所有消息类型 + * + * @return 消息类型集合 + */ + public Map getMsgTypes() { + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_GET_MSG_TYPES_VALUE).build(); + Response rsp = sendCmd(req); + if (rsp != null) { + return rsp.getTypes().getTypesMap(); + } + return Wcf.MsgTypes.newBuilder().build().getTypesMap(); + } + + /** + * 获取完整通讯录 + * "fmessage": "朋友推荐消息", + * "medianote": "语音记事本", + * "floatbottle": "漂流瓶", + * "filehelper": "文件传输助手", + * "newsapp": "新闻", + * + * @return 联系人列表 + */ + public List getContacts() { + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_GET_CONTACTS_VALUE).build(); + Response rsp = sendCmd(req); + if (rsp != null) { + return rsp.getContacts().getContactsList(); + } + return Wcf.RpcContacts.newBuilder().build().getContactsList(); + } + + /** + * 获取所有数据库 + * + * @return + */ + public List getDbNames() { + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_GET_DB_NAMES_VALUE).build(); + Response rsp = sendCmd(req); + if (rsp != null) { + return rsp.getDbs().getNamesList(); + } + return Wcf.DbNames.newBuilder().build().getNamesList(); + } + + /** + * 获取 db 中所有表 * * @param db 数据库名 + * @return 该数据库下的所有表名及对应建表语句 + */ + public Map getDbTables(String db) { + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_GET_DB_TABLES_VALUE).setStr(db).build(); + Response rsp = sendCmd(req); + Map tables = new LinkedHashMap<>(); + if (rsp != null) { + for (Wcf.DbTable tbl : rsp.getTables().getTablesList()) { + tables.put(tbl.getName(), tbl.getSql()); + } + } + return tables; + } + + /** + * 获取登录账号个人信息 + * + * @return 个人信息 + */ + public Wcf.UserInfo getUserInfo() { + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_GET_USER_INFO_VALUE).build(); + Response rsp = sendCmd(req); + if (rsp != null) { + return rsp.getUi(); + } + return null; + } + + /** + * 获取语音消息并转成 MP3 + * + * @param id 语音消息 id + * @param dir MP3 保存目录(目录不存在会出错) + * @param timeout MP3 超时时间(秒) + * @return 成功返回存储路径;空字符串为失败,原因见日志。 + */ + public String getAudioMsg(Integer id, String dir, Integer timeout) { + Wcf.AudioMsg audioMsg = Wcf.AudioMsg.newBuilder().setId(id).setDir(dir).build(); + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_GET_AUDIO_MSG_VALUE).setAm(audioMsg).build(); + Response rsp = sendCmd(req); + if (rsp != null) { + return rsp.getStr(); + } + return null; + } + + /** + * 发送文本消息 + * + * @param msg: 消息内容(如果是 @ 消息则需要有跟 @ 的人数量相同的 @) + * @param receiver: 消息接收人,私聊为 wxid(wxid_xxxxxxxxxxxxxx),群聊为 + * roomid(xxxxxxxxxx@chatroom) + * @param aters: 群聊时要 @ 的人(私聊时为空字符串),多个用逗号分隔。@所有人 用 + * notify@all(必须是群主或者管理员才有权限) + * @return int 0 为成功,其他失败 + * @author Changhua + * @example sendText(" Hello @ 某人1 @ 某人2 ", " xxxxxxxx @ chatroom ", + * "wxid_xxxxxxxxxxxxx1,wxid_xxxxxxxxxxxxx2"); + **/ + public int sendText(String msg, String receiver, String aters) { + Wcf.TextMsg textMsg = Wcf.TextMsg.newBuilder().setMsg(msg).setReceiver(receiver).setAters(aters).build(); + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_SEND_TXT_VALUE).setTxt(textMsg).build(); + log.debug("sendText: {}", bytesToHex(req.toByteArray())); + Response rsp = sendCmd(req); + int ret = -1; + if (rsp != null) { + ret = rsp.getStatus(); + } + return ret; + } + + /** + * 发送图片消息 + * + * @param path 图片地址,如:`C:/Projs/WeChatRobot/TEQuant.jpeg` 或 + * `https://raw.githubusercontent.com/lich0821/WeChatFerry/master/assets/TEQuant.jpg` + * @param receiver 消息接收人,wxid 或者 roomid + * @return 发送结果状态码 0 为成功,其他失败 + */ + public int sendImage(String path, String receiver) { + Wcf.PathMsg pathMsg = Wcf.PathMsg.newBuilder().setPath(path).setReceiver(receiver).build(); + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_SEND_IMG_VALUE).setFile(pathMsg).build(); + log.debug("sendImage: {}", bytesToHex(req.toByteArray())); + Response rsp = sendCmd(req); + int ret = -1; + if (rsp != null) { + ret = rsp.getStatus(); + } + return ret; + } + + /** + * 发送文件消息 + * + * @param path 本地文件路径,如:`C:/Projs/WeChatRobot/README.MD` 或 + * `https://raw.githubusercontent.com/lich0821/WeChatFerry/master/README.MD` + * @param receiver 消息接收人,wxid 或者 roomid + * @return 发送结果状态码 0 为成功,其他失败 + */ + public int sendFile(String path, String receiver) { + Wcf.PathMsg pathMsg = Wcf.PathMsg.newBuilder().setPath(path).setReceiver(receiver).build(); + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_SEND_FILE_VALUE).setFile(pathMsg).build(); + log.debug("sendFile: {}", bytesToHex(req.toByteArray())); + Response rsp = sendCmd(req); + int ret = -1; + if (rsp != null) { + ret = rsp.getStatus(); + } + return ret; + } + + /** + * 发送Xml消息 + * + * @param receiver 消息接收人,wxid 或者 roomid + * @param xml xml内容 + * @param path 封面图片路径 + * @param type xml 类型,如:0x21 为小程序 + * @return 发送结果状态码 0 为成功,其他失败 + */ + public int sendXml(String receiver, String xml, String path, int type) { + Wcf.XmlMsg xmlMsg = Wcf.XmlMsg.newBuilder().setContent(xml).setReceiver(receiver).setPath(path).setType(type).build(); + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_SEND_XML_VALUE).setXml(xmlMsg).build(); + log.debug("sendXml: {}", bytesToHex(req.toByteArray())); + Response rsp = sendCmd(req); + int ret = -1; + if (rsp != null) { + ret = rsp.getStatus(); + } + return ret; + } + + /** + * 发送表情消息 + * + * @param path 本地表情路径,如:`C:/Projs/WeChatRobot/emo.gif` + * @param receiver 消息接收人,wxid 或者 roomid + * @return 发送结果状态码 0 为成功,其他失败 + */ + public int sendEmotion(String path, String receiver) { + Wcf.PathMsg pathMsg = Wcf.PathMsg.newBuilder().setPath(path).setReceiver(receiver).build(); + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_SEND_EMOTION_VALUE).setFile(pathMsg).build(); + log.debug("sendEmotion: {}", bytesToHex(req.toByteArray())); + Response rsp = sendCmd(req); + int ret = -1; + if (rsp != null) { + ret = rsp.getStatus(); + } + return ret; + } + + /** + * 发送富文本消息 + * + * @param name 左下显示的名字 + * @param account 填公众号 id 可以显示对应的头像(gh_ 开头的) + * @param title 标题,最多两行 + * @param digest 摘要,三行 + * @param url 点击后跳转的链接 + * @param thumbUrl 缩略图的链接 + * @param receiver 接收人, wxid 或者 roomid + * @return 发送结果状态码 0 为成功,其他失败 + * + * @example 卡片样式: + * |-------------------------------------| + * |title, 最长两行 + * |(长标题, 标题短的话这行没有) + * |digest, 最多三行,会占位 |--------| + * |digest, 最多三行,会占位 |thumbUrl| + * |digest, 最多三行,会占位 |--------| + * |(account logo) name + * |-------------------------------------| + */ + public int sendRichText(String name, String account, String title, String digest, String url, String thumbUrl, String receiver) { + Wcf.RichText richTextMsg = Wcf.RichText.newBuilder().setName(name).setAccount(account).setTitle(title).setDigest(digest).setUrl(url) + .setThumburl(thumbUrl).setReceiver(receiver).build(); + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_SEND_RICH_TXT_VALUE).setRt(richTextMsg).build(); + log.debug("sendRichText: {}", bytesToHex(req.toByteArray())); + Response rsp = sendCmd(req); + int ret = -1; + if (rsp != null) { + ret = rsp.getStatus(); + } + return ret; + } + + /** + * 拍一拍群友 + * + * @param roomid 群 id + * @param wxid 要拍的群友的 wxid + * @return 发送结果状态码 0 为成功,其他失败 + */ + public int sendPatMsg(String roomid, String wxid) { + Wcf.PatMsg patMsg = Wcf.PatMsg.newBuilder().setRoomid(roomid).setWxid(wxid).build(); + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_SEND_PAT_MSG_VALUE).setPm(patMsg).build(); + log.debug("sendPatMsg: {}", bytesToHex(req.toByteArray())); + Response rsp = sendCmd(req); + int ret = -1; + if (rsp != null) { + // 接口中 1 为成功,其他失败 + ret = rsp.getStatus(); + if (ret == 1) { + // 转为通用值 + ret = 0; + } + } + return ret; + } + + /** + * 转发消息。可以转发文本、图片、表情、甚至各种 XML; + * 语音也行,不过效果嘛,自己验证吧。 + * + * @param id 待转发消息的 id + * @param receiver 消息接收者,wxid 或者 roomid + * @return 结果状态码 0 为成功,其他失败 + */ + public int forwardMsg(Integer id, String receiver) { + Wcf.ForwardMsg forwardMsg = Wcf.ForwardMsg.newBuilder().setId(id).setReceiver(receiver).build(); + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_FORWARD_MSG_VALUE).setFm(forwardMsg).build(); + log.debug("forwardMsg: {}", bytesToHex(req.toByteArray())); + Response rsp = sendCmd(req); + int ret = -1; + if (rsp != null) { + // 接口中 1 为成功,其他失败 + ret = rsp.getStatus(); + if (ret == 1) { + // 转为通用值 + ret = 0; + } + } + return ret; + } + + /** + * 获取sql执行结果 + * + * @param db 数据库名,要查询的数据库 * @param sql 执行的sql语句 * @return 数据记录列表 */ @@ -202,23 +518,241 @@ public class WeChatSocketClient { } /** - * 解密图片 + * 通过好友申请 * - * @param srcPath 加密的图片路径 - * @param dstPath 解密的图片路径 - * @return 是否成功 + * @param v3 加密用户名 (好友申请消息里 v3 开头的字符串) xml.attrib["encryptusername"] + * @param v4 Ticket (好友申请消息里 v4 开头的字符串) xml.attrib["ticket"] + * @param scene 申请方式 (好友申请消息里的 scene); 为了兼容旧接口,默认为扫码添加 (30) + * @return 结果状态码 0 为成功,其他失败 */ - public boolean decryptImage(String srcPath, String dstPath) { + public int acceptNewFriend(String v3, String v4, Integer scene) { + if (ObjectUtils.isEmpty(scene)) { + scene = 30; + } int ret = -1; - DecPath build = DecPath.newBuilder().setSrc(srcPath).setDst(dstPath).build(); + Wcf.Verification verification = Wcf.Verification.newBuilder().setV3(v3).setV4(v4).setScene(scene).build(); + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_ACCEPT_FRIEND_VALUE).setV(verification).build(); + Response rsp = sendCmd(req); + if (rsp != null) { + // 接口中 1 为成功,其他失败 + ret = rsp.getStatus(); + if (ret == 1) { + // 转为通用值 + ret = 0; + } + } + return ret; + } + + /** + * 接收转账 + * + * @param wxid 转账消息里的发送人 wxid + * @param transferid 转账消息里的 transferid + * @param transactionid 转账消息里的 transactionid + * @return 结果状态码 0 为成功,其他失败 + */ + public int receiveTransfer(String wxid, String transferid, String transactionid) { + int ret = -1; + Wcf.Transfer transfer = Wcf.Transfer.newBuilder().setWxid(wxid).setTfid(transferid).setTaid(transactionid).build(); + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_RECV_TRANSFER_VALUE).setTf(transfer).build(); + Response rsp = sendCmd(req); + if (rsp != null) { + // 接口中 1 为成功,其他失败 + ret = rsp.getStatus(); + if (ret == 1) { + // 转为通用值 + ret = 0; + } + } + return ret; + } + + /** + * 刷新朋友圈 + * + * @param id 开始 id,0 为最新页 + * @return 结果状态码 0 为成功,其他失败 + */ + public int refreshPyq(Integer id) { + int ret = -1; + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_REFRESH_PYQ_VALUE).setUi64(id).build(); + Response rsp = sendCmd(req); + if (rsp != null) { + // 接口中 1 为成功,其他失败 + ret = rsp.getStatus(); + if (ret == 1) { + // 转为通用值 + ret = 0; + } + } + return ret; + } + + /** + * 下载附件(图片、视频、文件)。这方法别直接调用,下载图片使用 `download_image`。 + * + * @param id 消息中 id + * @param thumb 消息中的 thumb + * @param extra 消息中的 extra + * @return 结果状态码 0 为成功,其他失败 + */ + public int downloadAttach(Integer id, String thumb, String extra) { + int ret = -1; + Wcf.AttachMsg attachMsg = Wcf.AttachMsg.newBuilder().setId(id).setThumb(thumb).setExtra(extra).build(); + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_DOWNLOAD_ATTACH_VALUE).setAtt(attachMsg).build(); + Response rsp = sendCmd(req); + if (rsp != null) { + // 接口中 1 为成功,其他失败 + ret = rsp.getStatus(); + if (ret == 1) { + // 转为通用值 + ret = 0; + } + } + return ret; + } + + /** + * 通过 wxid 查询微信号昵称等信息 + * + * @param wxid 联系人 wxid + * @return 结果信息 + */ + public Wcf.RpcContact getInfoByWxId(String wxid) { + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_GET_CONTACT_INFO_VALUE).setStr(wxid).build(); + Response rsp = sendCmd(req); + if (rsp != null && !ObjectUtils.isEmpty(rsp.getContacts())) { + return rsp.getContacts().getContacts(0); + } + return null; + } + + /** + * 撤回消息 + * + * @param id 待撤回消息的 id + * @return 结果状态码 0 为成功,其他失败 + */ + public int revokeMsg(Integer id) { + int ret = -1; + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_REVOKE_MSG_VALUE).setUi64(id).build(); + Response rsp = sendCmd(req); + if (rsp != null) { + // 接口中 1 为成功,其他失败 + ret = rsp.getStatus(); + if (ret == 1) { + // 转为通用值 + ret = 0; + } + } + return ret; + } + + /** + * 解密图片。这方法别直接调用,下载图片使用 `download_image`。 + * + * @param src 加密的图片路径 + * @param dir 保存图片的目录 + * @return 解密图片的保存路径 + */ + public String decryptImage(String src, String dir) { + Wcf.DecPath build = Wcf.DecPath.newBuilder().setSrc(src).setDst(dir).build(); Request req = Request.newBuilder().setFuncValue(Functions.FUNC_DECRYPT_IMAGE_VALUE).setDec(build).build(); Response rsp = sendCmd(req); if (rsp != null) { - ret = rsp.getStatus(); + return rsp.getStr(); } - return ret == 1; + return ""; } + /** + * 获取 OCR 结果。鸡肋,需要图片能自动下载;通过下载接口下载的图片无法识别。 + * + * @param extra 待识别的图片路径,消息里的 extra + * @return OCR 结果 + */ + public Wcf.OcrMsg getOcrResult(String extra, Integer timeout) { + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_EXEC_OCR_VALUE).setStr(extra).build(); + Response rsp = sendCmd(req); + if (rsp != null) { + return rsp.getOcr(); + } + return null; + } + + /** + * 添加群成员 + * + * @param roomid 待加群的 id + * @param wxids 要加到群里的 wxid,多个用逗号分隔 + * @return 结果状态码 0 为成功,其他失败 + */ + public int addChatroomMembers(String roomid, String wxids) { + int ret = -1; + Wcf.MemberMgmt memberMgmt = Wcf.MemberMgmt.newBuilder().setRoomid(roomid).setWxids(wxids).build(); + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_ADD_ROOM_MEMBERS_VALUE).setM(memberMgmt).build(); + Response rsp = sendCmd(req); + if (rsp != null) { + // 接口中 1 为成功,其他失败 + ret = rsp.getStatus(); + if (ret == 1) { + // 转为通用值 + ret = 0; + } + } + return ret; + } + + /** + * 删除群成员 + * + * @param roomid 群的 id + * @param wxids 要删除成员的 wxid,多个用逗号分隔 + * @return 结果状态码 0 为成功,其他失败 + */ + public int delChatroomMembers(String roomid, String wxids) { + int ret = -1; + Wcf.MemberMgmt memberMgmt = Wcf.MemberMgmt.newBuilder().setRoomid(roomid).setWxids(wxids).build(); + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_DEL_ROOM_MEMBERS_VALUE).setM(memberMgmt).build(); + Response rsp = sendCmd(req); + if (rsp != null) { + // 接口中 1 为成功,其他失败 + ret = rsp.getStatus(); + if (ret == 1) { + // 转为通用值 + ret = 0; + } + } + return ret; + } + + /** + * 邀请群成员 + * + * @param roomid 群的 id + * @param wxids 要邀请成员的 wxid, 多个用逗号`,`分隔 + * @return 结果状态码 0 为成功,其他失败 + */ + public int inviteChatroomMembers(String roomid, String wxids) { + int ret = -1; + Wcf.MemberMgmt memberMgmt = Wcf.MemberMgmt.newBuilder().setRoomid(roomid).setWxids(wxids).build(); + Request req = Request.newBuilder().setFuncValue(Functions.FUNC_INV_ROOM_MEMBERS_VALUE).setM(memberMgmt).build(); + Response rsp = sendCmd(req); + if (rsp != null) { + // 接口中 1 为成功,其他失败 + ret = rsp.getStatus(); + if (ret == 1) { + // 转为通用值 + ret = 0; + } + } + return ret; + } + + /** + * 是否已启动接收消息功能 + */ public boolean getIsReceivingMsg() { return isReceivingMsg; } @@ -249,11 +783,13 @@ public class WeChatSocketClient { return false; } + /** + * 允许接收消息 + */ public void enableRecvMsg(int qSize) { if (isReceivingMsg) { return; } - Request req = Request.newBuilder().setFuncValue(Functions.FUNC_ENABLE_RECV_TXT_VALUE).build(); Response rsp = sendCmd(req); if (rsp == null) { @@ -269,6 +805,9 @@ public class WeChatSocketClient { thread.start(); } + /** + * 停止接收消息 + */ public int diableRecvMsg() { if (!isReceivingMsg) { return 1; @@ -281,7 +820,6 @@ public class WeChatSocketClient { if (ret == 0) { isReceivingMsg = false; } - } return ret; } diff --git a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/service/WeChatDllService.java b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/service/WeChatDllService.java index 3290b42..1c1cdca 100644 --- a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/service/WeChatDllService.java +++ b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/service/WeChatDllService.java @@ -44,14 +44,14 @@ public interface WeChatDllService { * 当前微信客户端是否登录微信号 * * @return true-已登录 false-未登录 - * + * * @author chandler * @date 2024-10-01 21:20 */ Boolean loginStatus(); /** - * 获取登录微信内部识别号UID + * 获取登录微信号 * 获得微信客户端登录的微信ID * * @return 微信内部识别号UID @@ -112,17 +112,40 @@ public interface WeChatDllService { */ List queryDbTableList(WxPpWcfDatabaseTableReq request); + /** + * 获取指定数据库中的所有表 + * + * @param databaseName 数据库名称 + * @return 数据库记录 + * + * @author chandler + * @date 2025-05-04 13:25 + */ + List queryDbTableList(String databaseName); + /** * 执行数据库查询SQL - * + * * @param request 请求入参 * @return 数据库记录 - * + * * @author chandler * @date 2024-10-02 17:52 */ List execDbQuerySql(WxPpWcfDatabaseSqlReq request); + /** + * 执行数据库查询SQL + * + * @param databaseName 数据库名称 + * @param sqlText SQL语句 + * @return 数据库记录 + * + * @author chandler + * @date 2025-05-04 13:26 + */ + List execDbQuerySql(String databaseName, String sqlText); + /** * 发送文本消息(可 @) * @@ -136,6 +159,20 @@ public interface WeChatDllService { */ WxPpWcfSendTextMsgResp sendTextMsg(WxPpWcfSendTextMsgReq request); + /** + * 发送文本消息(可 @) + * + * @param recipient 消息接收人 + * @param msgText 消息文本 + * @param atUsers 要艾特的用户 + * @param isAtAll 是否艾特全体,默认为false + * @return 消息发送返回 + * + * @author chandler + * @date 2025-05-04 13:27 + */ + WxPpWcfSendTextMsgResp sendTextMsg(String recipient, String msgText, List atUsers, Boolean isAtAll); + /** * 发送富文本消息 * @@ -147,6 +184,24 @@ public interface WeChatDllService { */ WxPpWcfSendRichTextMsgResp sendRichTextMsg(WxPpWcfSendRichTextMsgReq request); + /** + * 发送富文本消息 + * + * @param recipient 消息接收人 + * @param name 左下显示的名字 + * @param account 资源路径-封面图片路径 + * @param title 标题,最多两行 + * @param digest 摘要,三行 + * @param jumpUrl 点击后跳转的链接 + * @param thumbnailUrl 缩略图的链接 + * @return 消息发送返回 + * + * @author chandler + * @date 2025-05-04 13:28 + */ + WxPpWcfSendRichTextMsgResp sendRichTextMsg(String recipient, String name, String account, String title, String digest, String jumpUrl, + String thumbnailUrl); + /** * 发送XML消息 * @@ -158,6 +213,20 @@ public interface WeChatDllService { */ WxPpWcfSendXmlMsgResp sendXmlMsg(WxPpWcfSendXmlMsgReq request); + /** + * 发送XML消息 + * + * @param recipient 消息接收人 + * @param xmlContent XML报文内容 + * @param resourcePath 资源路径-封面图片路径 + * @param xmlType XML类型,如:21 为小程序 + * @return 消息发送返回 + * + * @author chandler + * @date 2025-05-04 13:32 + */ + WxPpWcfSendXmlMsgResp sendXmlMsg(String recipient, String xmlContent, String resourcePath, String xmlType); + /** * 发送图片消息 * @@ -169,6 +238,18 @@ public interface WeChatDllService { */ WxPpWcfSendImageMsgResp sendImageMsg(WxPpWcfSendImageMsgReq request); + /** + * 发送图片消息 + * + * @param recipient 消息接收人 + * @param resourcePath 资源路径-本地图片地址 + * @return 消息发送返回 + * + * @author chandler + * @date 2025-05-04 13:34 + */ + WxPpWcfSendImageMsgResp sendImageMsg(String recipient, String resourcePath); + /** * 发送表情消息 * @@ -180,6 +261,17 @@ public interface WeChatDllService { */ WxPpWcfSendEmojiMsgResp sendEmojiMsg(WxPpWcfSendEmojiMsgReq request); + /** + * 发送表情消息 + * + * @param recipient 消息接收人 + * @param resourcePath 资源路径-本地图片地址 + * + * @author chandler + * @date 2025-05-04 13:36 + */ + WxPpWcfSendEmojiMsgResp sendEmojiMsg(String recipient, String resourcePath); + /** * 发送文件消息 * @@ -191,6 +283,17 @@ public interface WeChatDllService { */ WxPpWcfSendFileMsgResp sendFileMsg(WxPpWcfSendFileMsgReq request); + /** + * 发送文件消息 + * + * @param recipient 消息接收人 + * @param resourcePath 资源路径-本地图片地址 + * + * @author chandler + * @date 2025-05-04 13:37 + */ + WxPpWcfSendFileMsgResp sendFileMsg(String recipient, String resourcePath); + /** * 拍一拍 * @@ -202,9 +305,21 @@ public interface WeChatDllService { */ WxPpWcfSendPatOnePatMsgResp patOnePat(WxPpWcfPatOnePatMsgReq request); + /** + * 拍一拍 + * + * @param recipient 消息接收人 + * @param patUser 要拍的人的wxid + * + * @author chandler + * @date 2025-05-04 13:39 + */ + WxPpWcfSendPatOnePatMsgResp patOnePat(String recipient, String patUser); + /** * 撤回消息 * + * @param request 请求入参 * @return 结果状态 * * @author chandler @@ -212,6 +327,17 @@ public interface WeChatDllService { */ String revokeMsg(WxPpWcfRevokeMsgReq request); + /** + * 撤回消息 + * + * @param msgId 消息编号 + * @return 结果状态 + * + * @author chandler + * @date 2025-05-04 13:40 + */ + String revokeMsg(String msgId); + /** * 通过好友申请 * @@ -223,6 +349,19 @@ public interface WeChatDllService { */ String passFriendApply(WxPpWcfPassFriendApplyReq request); + /** + * 通过好友申请 + * + * @param encryptUsername 加密用户名 + * @param ticket ticket + * @param scene 场景 + * @return 结果状态 + * + * @author chandler + * @date 2025-05-04 13:41 + */ + String passFriendApply(String encryptUsername, String ticket, String scene); + /** * 添加群成员为微信好友 * @@ -234,6 +373,18 @@ public interface WeChatDllService { */ String addFriendGroupMember(WxPpWcfAddFriendGroupMemberReq request); + /** + * 添加群成员为微信好友 + * + * @param groupNo 群编号 + * @param groupMembers 待添加的群成员列表 + * @return 结果状态 + * + * @author chandler + * @date 2025-05-04 13:42 + */ + String addFriendGroupMember(String groupNo, List groupMembers); + /** * 查询群成员列表 * @@ -245,6 +396,17 @@ public interface WeChatDllService { */ List queryGroupMemberList(WxPpWcfGroupMemberReq request); + /** + * 查询群成员列表 + * + * @param groupNo 群编号 + * @return 数据库记录 + * + * @author chandler + * @date 2025-05-04 13:43 + */ + List queryGroupMemberList(String groupNo); + /** * 邀请群成员 * @@ -256,6 +418,18 @@ public interface WeChatDllService { */ String inviteGroupMember(WxPpWcfInviteGroupMemberReq request); + /** + * 邀请群成员 + * + * @param groupNo 群编号 + * @param groupMembers 待添加的群成员列表 + * @return 结果状态 + * + * @author chandler + * @date 2025-05-04 13:45 + */ + String inviteGroupMember(String groupNo, List groupMembers); + /** * 删除群成员 * @@ -267,6 +441,18 @@ public interface WeChatDllService { */ String deleteGroupMember(WxPpWcfDeleteGroupMemberReq request); + /** + * 删除群成员 + * + * @param groupNo 群编号 + * @param groupMembers 待添加的群成员列表 + * @return 结果状态 + * + * @author chandler + * @date 2025-05-04 13:46 + */ + String deleteGroupMember(String groupNo, List groupMembers); + /** * 查询朋友圈 * @@ -275,7 +461,7 @@ public interface WeChatDllService { * @author chandler * @date 2024-12-25 11:11 */ - String queryFriendCircle(); + String queryFriendCircle(Integer id); /** * 接收转账 @@ -288,4 +474,17 @@ public interface WeChatDllService { */ String receiveTransfer(WxPpWcfReceiveTransferReq request); + /** + * 接收转账 + * + * @param weChatUid 转账人 + * @param transferId 转账编号 + * @param transactionId 交易编号 + * @return 结果状态 + * + * @author chandler + * @date 2025-05-04 13:50 + */ + String receiveTransfer(String weChatUid, String transferId, String transactionId); + } diff --git a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/service/impl/WeChatDllServiceImpl.java b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/service/impl/WeChatDllServiceImpl.java index b9e7ca8..1a7c31a 100644 --- a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/service/impl/WeChatDllServiceImpl.java +++ b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/service/impl/WeChatDllServiceImpl.java @@ -81,61 +81,43 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public Boolean loginStatus() { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); - Boolean status = wechatSocketClient.isLogin(); - long endTime = System.currentTimeMillis(); - log.info("[查询]-[登录状态]-耗时:{}ms,status:{}", (endTime - startTime), status); - return status; + return wechatSocketClient.isLogin(); } @Override public String queryLoginWeChatUid() { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); - String weChatUid = ""; - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_GET_SELF_WXID_VALUE).build(); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - if (!ObjectUtils.isEmpty(rsp)) { - weChatUid = rsp.getStr(); - } - long endTime = System.currentTimeMillis(); - log.info("[查询]-[登录微信UID]-耗时:{}ms, weChatUid:{}", (endTime - startTime), weChatUid); - return weChatUid; + // FUNC_GET_SELF_WXID_VALUE + return wechatSocketClient.getSelfWxId(); } @Override public WxPpWcfLoginInfoResp queryLoginWeChatInfo() { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); WxPpWcfLoginInfoResp resp = new WxPpWcfLoginInfoResp(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_GET_USER_INFO_VALUE).build(); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - if (!ObjectUtils.isEmpty(rsp) && !ObjectUtils.isEmpty(rsp.getUi())) { - Wcf.UserInfo userInfo = rsp.getUi(); + // FUNC_GET_USER_INFO_VALUE + Wcf.UserInfo userInfo = wechatSocketClient.getUserInfo(); + if (!ObjectUtils.isEmpty(userInfo)) { resp.setWeChatUid(userInfo.getWxid()); resp.setWeChatNickname(userInfo.getName()); resp.setPhone(userInfo.getMobile()); resp.setHomePath(userInfo.getHome()); } - long endTime = System.currentTimeMillis(); - log.info("[查询]-[获取登录微信信息]-耗时:{}ms,登录信息:{}", (endTime - startTime), resp); return resp; } @Override public List queryMsgTypeList() { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); List list = new ArrayList<>(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_GET_MSG_TYPES_VALUE).build(); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - if (!ObjectUtils.isEmpty(rsp)) { - Map msgTypeMap = rsp.getTypes().getTypesMap(); + // FUNC_GET_MSG_TYPES_VALUE + Map msgTypeMap = wechatSocketClient.getMsgTypes(); + if (!msgTypeMap.isEmpty()) { WxPpWcfMsgTypeResp resp; for (Map.Entry entry : msgTypeMap.entrySet()) { resp = new WxPpWcfMsgTypeResp(); @@ -144,21 +126,17 @@ public class WeChatDllServiceImpl implements WeChatDllService { list.add(resp); } } - long endTime = System.currentTimeMillis(); - log.info("[查询]-[所有消息类型]-共查到:{}条,耗时:{}ms", list.size(), (endTime - startTime)); return list; } @Override public List queryContactsList() { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); List list = new ArrayList<>(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_GET_CONTACTS_VALUE).build(); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - if (!ObjectUtils.isEmpty(rsp) && !ObjectUtils.isEmpty(rsp.getContacts()) && !CollectionUtils.isEmpty(rsp.getContacts().getContactsList())) { - List rpcContactList = rsp.getContacts().getContactsList(); + // FUNC_GET_CONTACTS_VALUE + List rpcContactList = wechatSocketClient.getContacts(); + if (!CollectionUtils.isEmpty(rpcContactList)) { for (Wcf.RpcContact rpcContact : rpcContactList) { WxPpWcfContactsResp vo = new WxPpWcfContactsResp(); vo.setWeChatUid(rpcContact.getWxid()); @@ -193,53 +171,45 @@ public class WeChatDllServiceImpl implements WeChatDllService { list.add(vo); } } - long endTime = System.currentTimeMillis(); - log.info("[查询]-[联系人]-共查到:{}条,耗时:{}ms", list.size(), (endTime - startTime)); return list; } @Override public List queryDbTableNameList() { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); - List list = new ArrayList<>(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_GET_DB_NAMES_VALUE).build(); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - if (!ObjectUtils.isEmpty(rsp) && !ObjectUtils.isEmpty(rsp.getDbs()) && !CollectionUtils.isEmpty(rsp.getDbs().getNamesList())) { - list = rsp.getDbs().getNamesList(); - } - long endTime = System.currentTimeMillis(); - log.info("[查询]-[数据库名称列表]-共查到:{}条,耗时:{}ms", list.size(), (endTime - startTime)); - return list; + // FUNC_GET_DB_NAMES_VALUE + return wechatSocketClient.getDbNames(); } @Override public List queryDbTableList(WxPpWcfDatabaseTableReq request) { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); - log.info("[查询]-[数据库表列表]-request:{}", request); List list = new ArrayList<>(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_GET_DB_TABLES_VALUE).setStr(request.getDatabaseName()).build(); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - if (!ObjectUtils.isEmpty(rsp) && !ObjectUtils.isEmpty(rsp.getTables()) && !CollectionUtils.isEmpty(rsp.getTables().getTablesList())) { + // FUNC_GET_DB_TABLES_VALUE + Map tableMap = wechatSocketClient.getDbTables(request.getDatabaseName()); + if (!tableMap.isEmpty()) { WxPpWcfDatabaseTableResp resp; - for (Wcf.DbTable tbl : rsp.getTables().getTablesList()) { + for (Map.Entry entry : tableMap.entrySet()) { resp = new WxPpWcfDatabaseTableResp(); - resp.setTableName(tbl.getName()); - resp.setSql(tbl.getSql()); + resp.setTableName(entry.getKey()); + resp.setSql(entry.getValue()); list.add(resp); } } - long endTime = System.currentTimeMillis(); - log.info("[查询]-[数据库表列表]-共查到:{}条,耗时:{}ms", list.size(), (endTime - startTime)); return list; } + @Override + public List queryDbTableList(String databaseName) { + WxPpWcfDatabaseTableReq request = new WxPpWcfDatabaseTableReq(); + request.setDatabaseName(databaseName); + return this.queryDbTableList(request); + } + @Override public List execDbQuerySql(WxPpWcfDatabaseSqlReq request) { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); List list = new ArrayList<>(); @@ -266,14 +236,19 @@ public class WeChatDllServiceImpl implements WeChatDllService { list.add(rowVo); } } - long endTime = System.currentTimeMillis(); - log.info("[查询]-[执行数据库查询SQL]-共查到:{}条,耗时:{}ms", list.size(), (endTime - startTime)); return list; } + @Override + public List execDbQuerySql(String databaseName, String sqlText) { + WxPpWcfDatabaseSqlReq request = new WxPpWcfDatabaseSqlReq(); + request.setDatabaseName(databaseName); + request.setSqlText(sqlText); + return this.execDbQuerySql(request); + } + @Override public WxPpWcfSendTextMsgResp sendTextMsg(WxPpWcfSendTextMsgReq request) { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); log.info("[发送消息]-[文本消息]-入参打印:{}", request); @@ -287,44 +262,57 @@ public class WeChatDllServiceImpl implements WeChatDllService { atUser = String.join(",", request.getAtUsers()); } } - Wcf.TextMsg textMsg = Wcf.TextMsg.newBuilder().setMsg(request.getMsgText()).setReceiver(request.getRecipient()).setAters(atUser).build(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_TXT_VALUE).setTxt(textMsg).build(); - log.debug("sendText: {}", wechatSocketClient.bytesToHex(req.toByteArray())); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - // 0 为成功,其他失败 - int state = judgeWcfCmdState(rsp); + // FUNC_SEND_TXT_VALUE + int state = wechatSocketClient.sendText(request.getMsgText(), request.getRecipient(), atUser); // 回调处理 String stringJson = JSON.toJSONString(request); sendMsgCallback(stringJson, state); - long endTime = System.currentTimeMillis(); - log.info("[发送消息]-[文本消息]-处理结束,耗时:{}ms", (endTime - startTime)); return null; } + @Override + public WxPpWcfSendTextMsgResp sendTextMsg(String recipient, String msgText, List atUsers, Boolean isAtAll) { + if (ObjectUtils.isEmpty(isAtAll)) { + isAtAll = false; + } + WxPpWcfSendTextMsgReq request = new WxPpWcfSendTextMsgReq(); + request.setRecipient(recipient); + request.setMsgText(msgText); + request.setAtUsers(atUsers); + request.setIsAtAll(isAtAll); + return this.sendTextMsg(request); + } + @Override public WxPpWcfSendRichTextMsgResp sendRichTextMsg(WxPpWcfSendRichTextMsgReq request) { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); log.info("[发送消息]-[富文本消息]-入参打印:{}", request); - Wcf.RichText richTextMsg = Wcf.RichText.newBuilder().setName(request.getName()).setAccount(request.getAccount()).setTitle(request.getTitle()) - .setDigest(request.getDigest()).setUrl(request.getJumpUrl()).setThumburl(request.getThumbnailUrl()).setReceiver(request.getRecipient()) - .build(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_RICH_TXT_VALUE).setRt(richTextMsg).build(); - log.debug("sendRichText: {}", wechatSocketClient.bytesToHex(req.toByteArray())); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - int state = judgeWcfCmdState(rsp); + // FUNC_SEND_RICH_TXT_VALUE + int state = wechatSocketClient.sendRichText(request.getName(), request.getAccount(), request.getTitle(), request.getDigest(), + request.getJumpUrl(), request.getThumbnailUrl(), request.getRecipient()); // 回调处理 String stringJson = JSON.toJSONString(request); sendMsgCallback(stringJson, state); - long endTime = System.currentTimeMillis(); - log.info("[发送消息]-[富文本消息]-处理结束,耗时:{}ms", (endTime - startTime)); return null; } + @Override + public WxPpWcfSendRichTextMsgResp sendRichTextMsg(String recipient, String name, String account, String title, String digest, String jumpUrl, + String thumbnailUrl) { + WxPpWcfSendRichTextMsgReq request = new WxPpWcfSendRichTextMsgReq(); + request.setRecipient(recipient); + request.setName(name); + request.setAccount(account); + request.setTitle(title); + request.setDigest(digest); + request.setJumpUrl(jumpUrl); + request.setThumbnailUrl(thumbnailUrl); + return this.sendRichTextMsg(request); + } + @Override public WxPpWcfSendXmlMsgResp sendXmlMsg(WxPpWcfSendXmlMsgReq request) { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); log.info("[发送消息]-[XML消息]-入参打印:{}", request); @@ -335,132 +323,151 @@ public class WeChatDllServiceImpl implements WeChatDllService { } else { xmlType = Integer.parseInt(request.getXmlType()); } - Wcf.XmlMsg xmlMsg = Wcf.XmlMsg.newBuilder().setContent(request.getXmlContent()).setReceiver(request.getRecipient()) - .setPath(request.getResourcePath()).setType(xmlType).build(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_XML_VALUE).setXml(xmlMsg).build(); - log.debug("sendXml: {}", wechatSocketClient.bytesToHex(req.toByteArray())); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - int state = judgeWcfCmdState(rsp); + // FUNC_SEND_XML_VALUE + int state = wechatSocketClient.sendXml(request.getRecipient(), request.getXmlContent(), request.getResourcePath(), xmlType); // 回调处理 String stringJson = JSON.toJSONString(request); sendMsgCallback(stringJson, state); - long endTime = System.currentTimeMillis(); - log.info("[发送消息]-[XML消息]-处理结束,耗时:{}ms", (endTime - startTime)); return null; } + @Override + public WxPpWcfSendXmlMsgResp sendXmlMsg(String recipient, String xmlContent, String resourcePath, String xmlType) { + WxPpWcfSendXmlMsgReq request = new WxPpWcfSendXmlMsgReq(); + request.setRecipient(recipient); + request.setXmlContent(xmlContent); + request.setResourcePath(resourcePath); + request.setXmlType(xmlType); + return this.sendXmlMsg(request); + } + @Override public WxPpWcfSendImageMsgResp sendImageMsg(WxPpWcfSendImageMsgReq request) { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); log.info("[发送消息]-[图片消息]-入参打印:{}", request); WxPpWcfSendImageMsgResp resp = new WxPpWcfSendImageMsgResp(); - Wcf.PathMsg pathMsg = Wcf.PathMsg.newBuilder().setPath(request.getResourcePath()).setReceiver(request.getRecipient()).build(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_IMG_VALUE).setFile(pathMsg).build(); - log.debug("sendImage: {}", wechatSocketClient.bytesToHex(req.toByteArray())); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - int state = judgeWcfCmdState(rsp); + // FUNC_SEND_IMG_VALUE + int state = wechatSocketClient.sendImage(request.getResourcePath(), request.getRecipient()); // 回调处理 String stringJson = JSON.toJSONString(request); sendMsgCallback(stringJson, state); - long endTime = System.currentTimeMillis(); - log.info("[发送消息]-[图片消息]-处理结束,耗时:{}ms", (endTime - startTime)); return null; } + @Override + public WxPpWcfSendImageMsgResp sendImageMsg(String recipient, String resourcePath) { + WxPpWcfSendImageMsgReq request = new WxPpWcfSendImageMsgReq(); + request.setRecipient(recipient); + request.setResourcePath(resourcePath); + return this.sendImageMsg(request); + } + @Override public WxPpWcfSendEmojiMsgResp sendEmojiMsg(WxPpWcfSendEmojiMsgReq request) { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); log.info("[发送消息]-[表情消息]-入参打印:{}", request); - Wcf.PathMsg pathMsg = Wcf.PathMsg.newBuilder().setPath(request.getResourcePath()).setReceiver(request.getRecipient()).build(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_EMOTION_VALUE).setFile(pathMsg).build(); - log.debug("sendEmotion: {}", wechatSocketClient.bytesToHex(req.toByteArray())); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - int state = judgeWcfCmdState(rsp); + // FUNC_SEND_EMOTION_VALUE + int state = wechatSocketClient.sendEmotion(request.getResourcePath(), request.getRecipient()); // 回调处理 String stringJson = JSON.toJSONString(request); sendMsgCallback(stringJson, state); - long endTime = System.currentTimeMillis(); - log.info("[发送消息]-[表情消息]-处理结束,耗时:{}ms", (endTime - startTime)); return null; } + @Override + public WxPpWcfSendEmojiMsgResp sendEmojiMsg(String recipient, String resourcePath) { + WxPpWcfSendEmojiMsgReq request = new WxPpWcfSendEmojiMsgReq(); + request.setRecipient(recipient); + request.setResourcePath(resourcePath); + return this.sendEmojiMsg(request); + } + @Override public WxPpWcfSendFileMsgResp sendFileMsg(WxPpWcfSendFileMsgReq request) { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); log.info("[发送消息]-[文件消息]-入参打印:{}", request); - Wcf.PathMsg pathMsg = Wcf.PathMsg.newBuilder().setPath(request.getResourcePath()).setReceiver(request.getRecipient()).build(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_FILE_VALUE).setFile(pathMsg).build(); - log.debug("sendFile: {}", wechatSocketClient.bytesToHex(req.toByteArray())); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - int state = judgeWcfCmdState(rsp); + // FUNC_SEND_FILE_VALUE + int state = wechatSocketClient.sendFile(request.getResourcePath(), request.getRecipient()); // 回调处理 String stringJson = JSON.toJSONString(request); sendMsgCallback(stringJson, state); - long endTime = System.currentTimeMillis(); - log.info("[发送消息]-[文件消息]-处理结束,耗时:{}ms", (endTime - startTime)); return null; } + @Override + public WxPpWcfSendFileMsgResp sendFileMsg(String recipient, String resourcePath) { + WxPpWcfSendFileMsgReq request = new WxPpWcfSendFileMsgReq(); + request.setRecipient(recipient); + request.setResourcePath(resourcePath); + return this.sendFileMsg(request); + } + @Override public WxPpWcfSendPatOnePatMsgResp patOnePat(WxPpWcfPatOnePatMsgReq request) { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); log.info("[发送消息]-[拍一拍消息]-入参打印:{}", request); - Wcf.PatMsg patMsg = Wcf.PatMsg.newBuilder().setRoomid(request.getRecipient()).setWxid(request.getPatUser()).build(); - Wcf.Request wcfReq = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_PAT_MSG_VALUE).setPm(patMsg).build(); - Wcf.Response rsp = wechatSocketClient.sendCmd(wcfReq); - int state = judgeWcfCmdState(rsp); + // FUNC_SEND_PAT_MSG_VALUE + int state = wechatSocketClient.sendPatMsg(request.getRecipient(), request.getPatUser()); // 回调处理 String stringJson = JSON.toJSONString(request); sendMsgCallback(stringJson, state); - long endTime = System.currentTimeMillis(); - log.info("[发送消息]-[拍一拍消息]-处理结束,耗时:{}ms", (endTime - startTime)); return null; } + @Override + public WxPpWcfSendPatOnePatMsgResp patOnePat(String recipient, String patUser) { + WxPpWcfPatOnePatMsgReq request = new WxPpWcfPatOnePatMsgReq(); + request.setRecipient(recipient); + request.setPatUser(patUser); + return this.patOnePat(request); + } + @Override public String revokeMsg(WxPpWcfRevokeMsgReq request) { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); log.info("[撤回消息]-[消息撤回]-入参打印:{}", request); - long msgId = Long.parseLong(request.getMsgId()); - Wcf.Request wcfReq = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_REVOKE_MSG_VALUE).setUi64(msgId).build(); - Wcf.Response rsp = wechatSocketClient.sendCmd(wcfReq); - int state = judgeWcfCmdState(rsp); + Integer msgId = Integer.valueOf(request.getMsgId()); + // FUNC_REVOKE_MSG_VALUE + int state = wechatSocketClient.revokeMsg(msgId); // 回调处理 String stringJson = JSON.toJSONString(request); sendMsgCallback(stringJson, state); - long endTime = System.currentTimeMillis(); - log.info("[撤回消息]-[消息撤回]-处理结束,耗时:{}ms", (endTime - startTime)); return ""; } + @Override + public String revokeMsg(String msgId) { + WxPpWcfRevokeMsgReq request = new WxPpWcfRevokeMsgReq(); + request.setMsgId(msgId); + return this.revokeMsg(request); + } + @Override public String passFriendApply(WxPpWcfPassFriendApplyReq request) { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); log.info("[好友申请]-[通过好友申请]-入参打印:{}", request); - Wcf.Verification verification = Wcf.Verification.newBuilder().setV3(request.getApplicant()).setV4(request.getReviewer()).build(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_ACCEPT_FRIEND_VALUE).setV(verification).build(); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - int state = judgeWcfCmdState(rsp); - long endTime = System.currentTimeMillis(); - log.info("[好友申请]-[通过好友申请]-处理结束,耗时:{}ms", (endTime - startTime)); + // FUNC_ACCEPT_FRIEND_VALUE + int state = wechatSocketClient.acceptNewFriend(request.getEncryptUsername(), request.getTicket(), Integer.parseInt(request.getScene())); return ""; } + @Override + public String passFriendApply(String encryptUsername, String ticket, String scene) { + WxPpWcfPassFriendApplyReq request = new WxPpWcfPassFriendApplyReq(); + request.setEncryptUsername(encryptUsername); + request.setTicket(ticket); + request.setScene(scene); + return this.passFriendApply(request); + } + @Override public String addFriendGroupMember(WxPpWcfAddFriendGroupMemberReq request) { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); log.info("[添加好友]-[添加群成员为好友]-入参打印:{}", request); @@ -469,18 +476,21 @@ public class WeChatDllServiceImpl implements WeChatDllService { return ""; } String groupMembersStr = String.join(",", request.getGroupMembers()); - Wcf.MemberMgmt memberMgmt = Wcf.MemberMgmt.newBuilder().setRoomid(request.getGroupNo()).setWxids(groupMembersStr).build(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_ADD_ROOM_MEMBERS_VALUE).setM(memberMgmt).build(); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - int state = judgeWcfCmdState(rsp); - long endTime = System.currentTimeMillis(); - log.info("[添加好友]-[添加群成员为好友]-处理结束,耗时:{}ms", (endTime - startTime)); + // FUNC_ADD_ROOM_MEMBERS_VALUE + int state = wechatSocketClient.addChatroomMembers(request.getGroupNo(), groupMembersStr); return ""; } + @Override + public String addFriendGroupMember(String groupNo, List groupMembers) { + WxPpWcfAddFriendGroupMemberReq request = new WxPpWcfAddFriendGroupMemberReq(); + request.setGroupNo(groupNo); + request.setGroupMembers(groupMembers); + return this.addFriendGroupMember(request); + } + @Override public List queryGroupMemberList(WxPpWcfGroupMemberReq request) { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); List list = new ArrayList<>(); @@ -550,14 +560,18 @@ public class WeChatDllServiceImpl implements WeChatDllService { } } } - long endTime = System.currentTimeMillis(); - log.info("[查询]-[查询群成员]-共查到:{}条,耗时:{}ms", list.size(), (endTime - startTime)); return list; } + @Override + public List queryGroupMemberList(String groupNo) { + WxPpWcfGroupMemberReq request = new WxPpWcfGroupMemberReq(); + request.setGroupNo(groupNo); + return this.queryGroupMemberList(request); + } + @Override public String inviteGroupMember(WxPpWcfInviteGroupMemberReq request) { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); log.info("[群成员]-[邀请群成员加入]-入参打印:{}", request); @@ -565,19 +579,22 @@ public class WeChatDllServiceImpl implements WeChatDllService { log.error("[群成员]-[邀请群成员加入]-待邀请进群的人员为空,本次操作取消"); return ""; } + // FUNC_INV_ROOM_MEMBERS_VALUE String groupMembersStr = String.join(",", request.getGroupMembers()); - Wcf.MemberMgmt memberMgmt = Wcf.MemberMgmt.newBuilder().setRoomid(request.getGroupNo()).setWxids(groupMembersStr).build(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_INV_ROOM_MEMBERS_VALUE).setM(memberMgmt).build(); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - int state = judgeWcfCmdState(rsp); - long endTime = System.currentTimeMillis(); - log.info("[群成员]-[邀请群成员加入]-处理结束,耗时:{}ms", (endTime - startTime)); + int state = wechatSocketClient.inviteChatroomMembers(request.getGroupNo(), groupMembersStr); return ""; } + @Override + public String inviteGroupMember(String groupNo, List groupMembers) { + WxPpWcfInviteGroupMemberReq request = new WxPpWcfInviteGroupMemberReq(); + request.setGroupNo(groupNo); + request.setGroupMembers(groupMembers); + return this.inviteGroupMember(request); + } + @Override public String deleteGroupMember(WxPpWcfDeleteGroupMemberReq request) { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); log.info("[群成员]-[删除群成员]-入参打印:{}", request); @@ -585,47 +602,47 @@ public class WeChatDllServiceImpl implements WeChatDllService { log.error("[群成员]-[删除群成员]-待删除的人员为空,本次操作取消"); return ""; } + // FUNC_DEL_ROOM_MEMBERS_VALUE String groupMembersStr = String.join(",", request.getGroupMembers()); - Wcf.MemberMgmt memberMgmt = Wcf.MemberMgmt.newBuilder().setRoomid(request.getGroupNo()).setWxids(groupMembersStr).build(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_DEL_ROOM_MEMBERS_VALUE).setM(memberMgmt).build(); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - int state = judgeWcfCmdState(rsp); - long endTime = System.currentTimeMillis(); - log.info("[群成员]-[删除群成员]-处理结束,耗时:{}ms", (endTime - startTime)); + int state = wechatSocketClient.delChatroomMembers(request.getGroupNo(), groupMembersStr); return ""; } @Override - public String queryFriendCircle() { - long startTime = System.currentTimeMillis(); + public String deleteGroupMember(String groupNo, List groupMembers) { + WxPpWcfDeleteGroupMemberReq request = new WxPpWcfDeleteGroupMemberReq(); + request.setGroupNo(groupNo); + request.setGroupMembers(groupMembers); + return this.deleteGroupMember(request); + } + + @Override + public String queryFriendCircle(Integer id) { // 公共校验 checkClientStatus(); - log.info("[查询]-[刷新朋友圈]-开始"); - // id 开始 id,0 为最新页 (string based uint64) - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_REFRESH_PYQ_VALUE).setUi64(0).build(); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - int state = judgeWcfCmdState(rsp); - long endTime = System.currentTimeMillis(); - log.info("[查询]-[刷新朋友圈]-处理结束,耗时:{}ms", (endTime - startTime)); + // FUNC_REFRESH_PYQ_VALUE + int state = wechatSocketClient.refreshPyq(id); return ""; } @Override public String receiveTransfer(WxPpWcfReceiveTransferReq request) { - long startTime = System.currentTimeMillis(); // 公共校验 checkClientStatus(); - log.info("[转账]-[接收转账]-开始"); - Wcf.Transfer transfer = - Wcf.Transfer.newBuilder().setWxid(request.getWeChatUid()).setTfid(request.getTransferId()).setTaid(request.getTransferId()).build(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_RECV_TRANSFER_VALUE).setTf(transfer).build(); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - int state = judgeWcfCmdState(rsp); - long endTime = System.currentTimeMillis(); - log.info("[转账]-[接收转账]-处理结束,耗时:{}ms", (endTime - startTime)); + // FUNC_RECV_TRANSFER_VALUE + int state = wechatSocketClient.receiveTransfer(request.getWeChatUid(), request.getTransferId(), request.getTransactionId()); return ""; } + @Override + public String receiveTransfer(String weChatUid, String transferId, String transactionId) { + WxPpWcfReceiveTransferReq request = new WxPpWcfReceiveTransferReq(); + request.setWeChatUid(weChatUid); + request.setTransferId(transferId); + request.setTransactionId(transactionId); + return this.receiveTransfer(request); + } + /** * 消息回调 * diff --git a/clients/java/wcf-bmc/src/main/resources/application.yml b/clients/java/wcf-bmc/src/main/resources/application.yml index 7bfd3ec..4624f41 100644 --- a/clients/java/wcf-bmc/src/main/resources/application.yml +++ b/clients/java/wcf-bmc/src/main/resources/application.yml @@ -23,7 +23,7 @@ logging: wechat: ferry: # DLL文件位置 - dll-path: E:\WeChatFerry\clients\java\wcf-bmc\dll\sdk.dll + dll-path: E:\workspace\project\me\wcf\WeChatFerry\cdl\WeChatFerry-cdl-master\clients\java\wcf-bmc\dll\sdk.dll # socket端口 socket-port: 10086 # SDK是否调试模式