获取会话记录 - 获取图片资源
企业微信会话内容存档 - 获取图片资源
准备工作、参数配置、工具类等,请参照:https://blog.csdn.net/J3332679908/article/details/140822405
运行环境
SpringBoot2 + Mybatis-Plus
MySQL 8.0+
OpenJDK 1.8
一、数据表
decrypted_image_message
: 保存会话内容的明文数据(图片)
CREATE TABLE `decrypted_image_message` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
`msg_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '消息id,消息的唯一标识,企业可以使用此字段进行消息去重。',
`file_path` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '文件路径',
`sdkfileid` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '媒体资源的id信息',
`md5sum` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '图片资源的md5值,供进行校验',
`filesize` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '图片资源的文件大小',
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
`create_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '更新人',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_id` (`id`) USING BTREE COMMENT '逐渐索引',
KEY `idx_msg_id` (`msg_id`) USING BTREE COMMENT '消息ID索引'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='明文消息数据(图片)';
二、代码
- 新建
DecryptedImageResponseDto
类,解密后的文本类型的消息 - 继承
DecryptedResponseBaseDto
类 - 注意包名
package com.xxxx.modules.wecom.domain.dto.response;
import com.xxxx.modules.wecom.domain.dto.data.DecryptedTextDataDto;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
/**
* 解密会话信息(响应类)
*
* @author jiayq
* @version 1.0.0
* @date 2024-07-15 08:59:19
* @since v1.1.0
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class DecryptedTextResponseDto extends DecryptedResponseBaseDto {
/**
* 版本ID
*/
private static final long serialVersionUID = 2066698914539808072L;
/**
* 消息内容
*/
private JsonObject image;
}
- 新建
EncryptImageMessage
类,继承DecryptBaseMessage
类,泛型指定:DecryptedImageResponseDto
- 重写
decryptChatData(long sdk, String encryptKey, String encryptMsg)
和saveDecryptedChatData(List<T> t, String accessToken)
方法 - 保存图片文件时,先确定是否存在文件夹,如不存在请创建相应文件夹(代码创建)
package com.xxxx.modules.wecom.util.message;
import com.xxxx.config.AbstractParamConfig;
import com.xxxx.modules.wecom.domain.dto.response.DecryptedTextResponseDto;
import com.xxxx.modules.wecom.domain.entity.XxxxXxxxMessageEntity;
import com.xxxx.modules.wecom.service.IXxxxXxxxMessageService;
import com.xxxx.modules.wecom.util.DecryptUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.tencent.wework.Finance;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
/**
* 解析密文.企业微信自有解密内容(图像消息)
*
* @author jiayq
* @version 1.0.0
* @date 2024-07-15 08:59:20
*/
@Slf4j
@Component
public class EncryptImageMessage extends DecryptBaseMessage<DecryptedImageResponseDto> {
/**
* 日志
*/
private final static Logger logger = LoggerFactory.getLogger(EncryptImageMessage.class);
/**
* 明文消息数据(ClearTextMessage)表服务接口
*/
private IClearTextMessageService clearTextMessageService;
/**
* 设定 EncryptedSessionMessage 服务对象
*/
@Autowired
public void setClearTextMessageService(IClearTextMessageService clearTextMessageService) {
this.clearTextMessageService = clearTextMessageService;
}
/**
* 企业微信外部服务接口
*/
private IWeComService weComService;
/**
* 设定 EncryptedSessionMessage 服务对象
*/
@Autowired
public void setWeComService(IWeComService weComService) {
this.weComService = weComService;
}
/**
* 明文消息数据(图片)(DecryptedImageMessage)表服务接口
*/
private IDecryptedImageMessageService decryptedImageMessageService;
/**
* 设定 IDecryptedImageMessageService 服务对象
*/
@Autowired
public void setDecryptedImageMessageService(IDecryptedImageMessageService decryptedImageMessageService) {
this.decryptedImageMessageService = decryptedImageMessageService;
}
/**
* 解析密文.企业微信自有解密内容
*
* @param sdk 企业微信 SDK 对象
* @param encryptKey getchatdata返回的encrypt_random_key,使用企业自持对应版本秘钥RSA解密后的内容
* @param encryptMsg getchatdata返回的encrypt_chat_msg(消息密文)
* @return 解密的消息明文
*/
@Override
public DecryptedImageResponseDto decryptChatData(long sdk, String encryptKey, String encryptMsg) {
// 解密 encryptKey
String decryptedKey = DecryptUtil.decryptByRsa(encryptKey);
// 获取 slice 对象
long response = Finance.NewSlice();
int result = Finance.DecryptData(sdk, decryptedKey, encryptMsg, response);
// 验证SDK调用结果
if (result != 0) {
logger.error("[image]密文解密失败, res = {}", result);
// 释放 slice 对象,和NewSlice成对使用
Finance.FreeSlice(response);
return null;
}
// 获取JSON文本
String decryptedChatDataJson = Finance.GetContentFromSlice(response);
// 释放 slice 对象,和NewSlice成对使用
Finance.FreeSlice(response);
// 验证JSON文本
JsonUtil.interfaceRequest(decryptedChatDataJson);
// 获取会话内容
return JsonUtil.parseJson(decryptedChatDataJson, DecryptedImageResponseDto.class);
}
/**
* 保存消息明文
*
* @param sdk 企业微信sdk
* @param decryptedImageResponseDtoList 消息明文
*/
@Transactional(rollbackFor = Exception.class)
@Override
public void saveDecryptedChatData(long sdk, List<DecryptedImageResponseDto> decryptedImageResponseDtoList) {
// 剔除非图像类型数据
decryptedImageResponseDtoList.removeIf(dto -> !Objects.equals(MsgTypeEnum.IMAGE.getMsgType(), dto.getMsgtype()));
if (CollectionUtil.isEmpty(decryptedImageResponseDtoList)) {
AbstractParamConfig.logger.warn("本次拉取为查询到图像类型数据");
return;
}
// 获取accessToken
String accessToken = this.weComService.getToken();
List<ClearTextMessageBo> clearTextMessageBos = new ArrayList<>();
List<DecryptedImageMessageBo> decryptedImageMessageBoList = new ArrayList<>();
final String finalAccessToken = accessToken;
decryptedImageResponseDtoList.forEach(e -> {
ClearTextMessageBo clearTextMessageBo = super.setEntity(e, finalAccessToken);
clearTextMessageBo.setContent(e.getImage() == null ? null : e.getImage().toString());
clearTextMessageBos.add(clearTextMessageBo);
String sdkfileid = JsonUtil.getJsonNodeValue(e.getImage(), "sdkfileid", String.class);
// 保存图片
String fileName = e.getMsgid() + ".png";
String filePath = super.saveMediaData(sdk, sdkfileid, AbstractParamConfig.imageSavePath, fileName);
// 保存明文消息数据(文本)(DecryptedTextMessage)表
DecryptedImageMessageBo decryptedImageMessageBo = JsonUtil.parseJson(e.getImage(), DecryptedImageMessageBo.class);
// 省略参数设定...
decryptedImageMessageBoList.add(decryptedImageMessageBo);
});
// 保存明文消息数据(图片)(CLearTextMessage)表
this.clearTextMessageService.insertBatch(clearTextMessageBos);
// 保存明文消息数据(图片)(DecryptedTextMessage)表
this.saveDecryptedImageMessage(decryptedImageMessageBoList);
}
/**
* 保存明文消息数据(图片)(DecryptedImageMessage)表
*
* @param decryptedImageMessageBoList 明文消息数据(图片)
*/
private void saveDecryptedImageMessage(List<DecryptedImageMessageBo> decryptedImageMessageBoList) {
this.decryptedImageMessageService.insertBatch(decryptedImageMessageBoList);
}
}