diff --git a/clients/java/wcf-bmc/CHANGELOG.md b/clients/java/wcf-bmc/CHANGELOG.md index 8bbc5a95..45a3d21d 100644 --- a/clients/java/wcf-bmc/CHANGELOG.md +++ b/clients/java/wcf-bmc/CHANGELOG.md @@ -63,11 +63,17 @@ ___ v39.5.2版本目前会出现注入失败的情况,待排查修复,可先使用v39.5.1,只须替换dll版本即可 +### 2025-05-05 + +- 1.新增消息转发功能 + ### 2025-05-04 - 1.更新拍一拍接口入参 - 2.客户端内置方法名与PY版本保持一致 - 3.适配指定参数查询接口 +- 4.新增图片下载功能 +- 5.新增视频下载功能
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 488d6765..036e8eb7 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 @@ -11,36 +11,8 @@ import org.springframework.web.bind.annotation.RestController; import com.wechat.ferry.entity.TResponse; -import com.wechat.ferry.entity.vo.request.WxPpWcfAddFriendGroupMemberReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfDatabaseSqlReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfDatabaseTableReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfDeleteGroupMemberReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfDownloadAttachReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfGroupMemberReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfInviteGroupMemberReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfPassFriendApplyReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfPatOnePatMsgReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfReceiveTransferReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfRevokeMsgReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfSendEmojiMsgReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfSendFileMsgReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfSendImageMsgReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfSendRichTextMsgReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfSendTextMsgReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfSendXmlMsgReq; -import com.wechat.ferry.entity.vo.response.WxPpWcfContactsResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfDatabaseRowResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfDatabaseTableResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfGroupMemberResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfLoginInfoResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfMsgTypeResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfSendEmojiMsgResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfSendFileMsgResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfSendImageMsgResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfSendPatOnePatMsgResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfSendRichTextMsgResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfSendTextMsgResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfSendXmlMsgResp; +import com.wechat.ferry.entity.vo.request.*; +import com.wechat.ferry.entity.vo.response.*; import com.wechat.ferry.enums.ResponseCodeEnum; import com.wechat.ferry.service.WeChatDllService; import com.wechat.ferry.utils.PathUtils; @@ -173,6 +145,25 @@ public TResponse sendFileMsg(@Validated @RequestBody WxP WxPpWcfSendFileMsgResp resp = weChatDllService.sendFileMsg(request); return TResponse.ok(ResponseCodeEnum.SUCCESS, resp); } + + /** + * 转发微信消息 add by mz 2025-05-05 + * + * @param request + * @return + * @throws Exception + */ + @ApiOperation(value = "转发微信消息", notes = "forward_msg") + @PostMapping(value = "/send/forwardMsg") + public TResponse forwardMsg(@Validated @RequestBody WxPpWcfForwardMsgReq request) throws Exception { + // int: 1 为成功,其他失败 + int res = weChatDllService.forwardMsg(request); + if (res == 1) { + return TResponse.ok(ResponseCodeEnum.SUCCESS); + } + return TResponse.fail("转发失败"); + } + @ApiOperation(value = "拍一拍群友", notes = "patOnePat") @PostMapping(value = "/patOnePat") @@ -314,16 +305,14 @@ public TResponse downloadPicture(@Validated @RequestBody WxPpWcfDownload /** * 暂未实现 add by mz 2025-05-01 * - * @param request * @return * @throws Exception */ @ApiOperation(value = "登陆二维码", notes = "loginQR") @PostMapping(value = "/loginQR") - public TResponse loginQR(@Validated @RequestBody WxPpWcfDownloadAttachReq request) throws Exception { + public TResponse loginQR() throws Exception { String path = weChatDllService.loginQR(); return TResponse.ok(ResponseCodeEnum.SUCCESS, path); } - - + } diff --git a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfDownloadAttachReq.java b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfDownloadAttachReq.java index be2fc177..42f13e42 100644 --- a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfDownloadAttachReq.java +++ b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfDownloadAttachReq.java @@ -4,7 +4,7 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; -import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; /** * 请求入参-下载附件信息 @@ -17,11 +17,9 @@ public class WxPpWcfDownloadAttachReq { /** - * 消息接收人 - * 消息接收人,私聊为 wxid(wxid_xxxxxxxxxxxxxx) - * 群聊为 roomid(xxxxxxxxxx@chatroom) + * 消息id */ - @NotBlank(message = "消息id不能为空") + @NotNull(message = "消息id不能为空") @ApiModelProperty(value = "消息id") private Long id; diff --git a/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfForwardMsgReq.java b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfForwardMsgReq.java new file mode 100644 index 00000000..e8b87e41 --- /dev/null +++ b/clients/java/wcf-bmc/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfForwardMsgReq.java @@ -0,0 +1,34 @@ +package com.wechat.ferry.entity.vo.request; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 转发微信消息入参 + * + * @author wmz + * @date 2025-05-05 + */ +@Data +@ApiModel(value = "wxPpWcfForwardMsgReq", description = "转发微信消息入参") +public class WxPpWcfForwardMsgReq { + + /** + * 消息id + */ + @NotNull(message = "消息id不能为空") + @ApiModelProperty(value = "消息id") + private Long id; + + /** + * 消息接收人 消息接收人,私聊为 wxid(wxid_xxxxxxxxxxxxxx) 群聊为 roomid(xxxxxxxxxx@chatroom) + */ + @NotBlank(message = "消息接收人") + @ApiModelProperty(value = "receiver") + private String receiver; + +} 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 9e80826b..65565b03 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 @@ -2,36 +2,8 @@ import java.util.List; -import com.wechat.ferry.entity.vo.request.WxPpWcfAddFriendGroupMemberReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfDatabaseSqlReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfDatabaseTableReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfDeleteGroupMemberReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfDownloadAttachReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfGroupMemberReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfInviteGroupMemberReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfPassFriendApplyReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfPatOnePatMsgReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfReceiveTransferReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfRevokeMsgReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfSendEmojiMsgReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfSendFileMsgReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfSendImageMsgReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfSendRichTextMsgReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfSendTextMsgReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfSendXmlMsgReq; -import com.wechat.ferry.entity.vo.response.WxPpWcfContactsResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfDatabaseRowResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfDatabaseTableResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfGroupMemberResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfLoginInfoResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfMsgTypeResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfSendEmojiMsgResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfSendFileMsgResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfSendImageMsgResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfSendPatOnePatMsgResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfSendRichTextMsgResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfSendTextMsgResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfSendXmlMsgResp; +import com.wechat.ferry.entity.vo.request.*; +import com.wechat.ferry.entity.vo.response.*; /** * 业务接口-对接原本DLL的接口 @@ -522,5 +494,17 @@ WxPpWcfSendRichTextMsgResp sendRichTextMsg(String recipient, String name, String * @date 2025-05-02 */ String loginQR() throws Exception; + + /** + * 转发微信消息 + * id (str): 待转发消息的 id + * receiver (str): 消息接收者,wxid 或者 roomid + * @author wmz + * @param request + * @return + * @throws java.lang.Exception + * @date 2025-05-05 + */ + int forwardMsg(WxPpWcfForwardMsgReq request) throws Exception; } 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 e3c8ab1c..cb671cb1 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 @@ -18,37 +18,8 @@ import com.wechat.ferry.aggregation.facade.ContactDo; import com.wechat.ferry.config.WeChatFerryProperties; import com.wechat.ferry.entity.proto.Wcf; -import com.wechat.ferry.entity.vo.request.WxPpWcfAddFriendGroupMemberReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfDatabaseSqlReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfDatabaseTableReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfDeleteGroupMemberReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfDownloadAttachReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfGroupMemberReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfInviteGroupMemberReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfPassFriendApplyReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfPatOnePatMsgReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfReceiveTransferReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfRevokeMsgReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfSendEmojiMsgReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfSendFileMsgReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfSendImageMsgReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfSendRichTextMsgReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfSendTextMsgReq; -import com.wechat.ferry.entity.vo.request.WxPpWcfSendXmlMsgReq; -import com.wechat.ferry.entity.vo.response.WxPpWcfContactsResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfDatabaseFieldResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfDatabaseRowResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfDatabaseTableResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfGroupMemberResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfLoginInfoResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfMsgTypeResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfSendEmojiMsgResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfSendFileMsgResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfSendImageMsgResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfSendPatOnePatMsgResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfSendRichTextMsgResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfSendTextMsgResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfSendXmlMsgResp; +import com.wechat.ferry.entity.vo.request.*; +import com.wechat.ferry.entity.vo.response.*; import com.wechat.ferry.enums.DatabaseNameEnum; import com.wechat.ferry.enums.MsgCallbackTypeEnum; import com.wechat.ferry.enums.SexEnum; @@ -61,6 +32,7 @@ import java.io.File; import lombok.extern.slf4j.Slf4j; +import org.springframework.util.StopWatch; /** * 业务实现层-对接原本DLL的接口 @@ -259,8 +231,8 @@ public WxPpWcfSendTextMsgResp sendTextMsg(WxPpWcfSendTextMsgReq request) { if (request.getIsAtAll()) { // 艾特全体,仅管理员有效 atUser = "@all"; - } else { - // 处理艾特的人员 + } else // 处理艾特的人员 + { if (!CollectionUtils.isEmpty(request.getAtUsers())) { atUser = String.join(",", request.getAtUsers()); } @@ -293,7 +265,7 @@ public WxPpWcfSendRichTextMsgResp sendRichTextMsg(WxPpWcfSendRichTextMsgReq requ log.info("[发送消息]-[富文本消息]-入参打印:{}", request); // FUNC_SEND_RICH_TXT_VALUE int state = wechatSocketClient.sendRichText(request.getName(), request.getAccount(), request.getTitle(), request.getDigest(), - request.getJumpUrl(), request.getThumbnailUrl(), request.getRecipient()); + request.getJumpUrl(), request.getThumbnailUrl(), request.getRecipient()); // 回调处理 String stringJson = JSON.toJSONString(request); sendMsgCallback(stringJson, state); @@ -302,7 +274,7 @@ public WxPpWcfSendRichTextMsgResp sendRichTextMsg(WxPpWcfSendRichTextMsgReq requ @Override public WxPpWcfSendRichTextMsgResp sendRichTextMsg(String recipient, String name, String account, String title, String digest, String jumpUrl, - String thumbnailUrl) { + String thumbnailUrl) { WxPpWcfSendRichTextMsgReq request = new WxPpWcfSendRichTextMsgReq(); request.setRecipient(recipient); request.setName(name); @@ -502,7 +474,7 @@ public List queryGroupMemberList(WxPpWcfGroupMemberReq r List wcfList = new ArrayList<>(); if (!ObjectUtils.isEmpty(request.getGroupNo())) { wcfList = wechatSocketClient.querySql(DatabaseNameEnum.MICRO_MSG.getCode(), - "SELECT RoomData FROM ChatRoom WHERE ChatRoomName = '" + request.getGroupNo() + "';"); + "SELECT RoomData FROM ChatRoom WHERE ChatRoomName = '" + request.getGroupNo() + "';"); } // 查询联系人 List dbList = wechatSocketClient.querySql(DatabaseNameEnum.MICRO_MSG.getCode(), "SELECT UserName, NickName, Type FROM Contact;"); @@ -515,11 +487,11 @@ public List queryGroupMemberList(WxPpWcfGroupMemberReq r for (Wcf.DbField dbField : dbFieldList) { if ("UserName".equals(dbField.getColumn())) { vo = new WxPpWcfGroupMemberResp(); - String content = (String)wechatSocketClient.convertSqlVal(dbField.getType(), dbField.getContent()); + String content = (String) wechatSocketClient.convertSqlVal(dbField.getType(), dbField.getContent()); vo.setWeChatUid(content); } if ("NickName".equals(dbField.getColumn())) { - String content = (String)wechatSocketClient.convertSqlVal(dbField.getType(), dbField.getContent()); + String content = (String) wechatSocketClient.convertSqlVal(dbField.getType(), dbField.getContent()); vo.setGroupNickName(content); dbMap.put(vo.getWeChatUid(), vo.getGroupNickName()); } @@ -658,7 +630,7 @@ public String receiveTransfer(String weChatUid, String transferId, String transa private void sendMsgCallback(String jsonString, Integer state) { // 根据配置文件决定是否回调 if (MsgCallbackTypeEnum.CLOSE.getCode().equals(weChatFerryProperties.getSendMsgCallbackFlag()) - || (MsgCallbackTypeEnum.SUCCESS.getCode().equals(weChatFerryProperties.getSendMsgCallbackFlag()) && 0 != state)) { + || (MsgCallbackTypeEnum.SUCCESS.getCode().equals(weChatFerryProperties.getSendMsgCallbackFlag()) && 0 != state)) { // 如果是关闭 或者 配置为成功才回调但发送状态为失败 的情况则取消发送 return; } @@ -709,8 +681,7 @@ private Boolean judgeSuccess(String responseStr) { } /** - * 判断WCF的CMD调用状态 - * 有值 为成功,其他失败 + * 判断WCF的CMD调用状态 有值 为成功,其他失败 * * @param rsp 响应参数 * @return 状态 @@ -765,8 +736,7 @@ private void checkClientStatus() { throw new BizException("微信客户端未登录或状态异常,请人工关闭本服务之后,退出微信客户端在重启本服务!"); } } - - + @Override public String loginQR() throws Exception { @@ -882,7 +852,7 @@ private int attachDownload(long id, String extra, String thumb) { * @param dir 保存图片的目录 * @return 是否成功 */ - public String decryptImage(String srcPath, String dir) { + private String decryptImage(String srcPath, String dir) { Wcf.DecPath build = Wcf.DecPath.newBuilder().setSrc(srcPath).setDst(dir).build(); Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_DECRYPT_IMAGE_VALUE).setDec(build).build(); Wcf.Response rsp = wechatSocketClient.sendCmd(req); @@ -892,4 +862,31 @@ public String decryptImage(String srcPath, String dir) { return null; } + //int forwardMsg(long id,String receiver) throws Exception; + @Override + public int forwardMsg(WxPpWcfForwardMsgReq request) throws Exception { + + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + // 公共校验 + checkClientStatus(); + log.info("[发送消息]-[转发消息]-入参打印:{}", request); + long id = request.getId(); + String receiver = request.getReceiver(); + //第一步,下载 + Wcf.ForwardMsg msg = Wcf.ForwardMsg.newBuilder().setId(id) + .setReceiver(receiver) + .build(); + Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_FORWARD_MSG_VALUE) + .setFm(msg) + .build(); + Wcf.Response rsp = wechatSocketClient.sendCmd(req); + + int status = rsp.getStatus(); + + stopWatch.stop(); + log.info("[发送消息]-[转发消息]-处理结束,耗时:{}ms", stopWatch.getTotalTimeMillis()); + return status; + } + }