微信公众平台
配置自动回复的服务器
application.properties中的配置
验证服务器接口配置
其实就两个接口(相同的url地址,只不过请求方式不一样)
1.验证接口(get请求)
2.自动回复接口(post请求)
完整代码 这个地址就是上面URL配置的地址 如果使用Nginx的话自动配置
将该代码先部署到服务器才可以验证通过
@RestController
@RequestMapping("/xxxx")
@Slf4j
public class WeChatController {
@Value("${weixin.token}")
private String token;
@GetMapping("/XXXXX")
public String handleMessage(@RequestParam("signature") String signature,
@RequestParam("timestamp") String timestamp,
@RequestParam("nonce") String nonce,
@RequestParam("echostr") String echostr) throws AesException {
log.info("signature:{},timestamp{},nonce:{},echostr:{}", signature, timestamp, nonce, echostr);
String[] params = new String[]{token, timestamp, nonce};
Arrays.sort(params);
StringBuilder sb = new StringBuilder();
for (String param : params) {
sb.append(param);
}
String checkSignature = getSHA1(sb.toString());
if (checkSignature.equals(signature)) {
log.info("校验成功");
return echostr; // 确认请求来自微信服务器
} else {
log.info("校验失败");
return "error";
}
}
private static String getSHA1(String str) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(str.getBytes());
byte[] bytes = md.digest();
StringBuilder hexStr = new StringBuilder();
for (byte b : bytes) {
String shaHex = Integer.toHexString(b & 0xFF);
if (shaHex.length() < 2) {
hexStr.append(0);
}
hexStr.append(shaHex);
}
return hexStr.toString();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}
第二部编写自动回复的代码
这里我只看了文本
@PostMapping("/xxxx")//和get验证请求相同的path只不过请求方式变了
public String receiveMessage(@RequestBody String requestBody,
@RequestParam("signature") String signature,
@RequestParam("timestamp") String timestamp,
@RequestParam("nonce") String nonce,
@RequestParam("openid") String openid,
@RequestParam(name = "encrypt_type", required = false) String encryptType,
@RequestParam(name = "msg_signature", required = false) String msgSignature) throws Exception{
// 记录接收到的消息和参数
log.info("Received message with requestBody: {}, signature: {}, timestamp: {}, nonce: {}, openid: {}, encryptType: {}, msgSignature: {}",
requestBody, signature, timestamp, nonce, openid, encryptType, msgSignature);
// WXBizMsgCrypt wxBizMsgCrypt = new WXBizMsgCrypt(token, encodingAesKey, appid);
// String decryptedMessage = "";
//
// if ("aes".equals(encryptType)) {
// decryptedMessage = wxBizMsgCrypt.decryptMsg(msgSignature, timestamp, nonce, requestBody);
// log.info("解密后的消息是:{}", decryptedMessage);
// } else {
// decryptedMessage = requestBody; // 非加密模式,直接使用请求体
// }
//
// // 从解密后的消息中解析出 FromUserName 和 ToUserName
// DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// DocumentBuilder db = dbf.newDocumentBuilder();
// Document doc = db.parse(new InputSource(new StringReader(decryptedMessage)));
// String fromUserName = doc.getElementsByTagName("FromUserName").item(0).getTextContent();
// String toUserName = doc.getElementsByTagName("ToUserName").item(0).getTextContent();
// String userMessage = doc.getElementsByTagName("Content").item(0).getTextContent(); // 用户发送的内容
// log.info("fromUserName:{},toUserName:{},userMessage:{}",fromUserName,toUserName,userMessage);
// String response = TYQWUtils.callWithMessage(userMessage);
//
//
// // 解析XML、处理消息并构建响应消息
// String responseContent = "Hello, this is a response";
//
//
// log.info("调用通义千问的结果:{}", response);
//
// //这里解析通义千问的结果
// Pattern pattern = Pattern.compile("content=([^,]+),");
// Matcher matcher = pattern.matcher(response);
// //matcher.find()必须要留
// if (matcher.find()) {
// System.out.println("匹配: " + matcher.group(1));
// responseContent= matcher.group(1);
// } else {
// System.out.println("不匹配");
// }
//
//
// String responseXml = "<xml>" +
// "<ToUserName><![CDATA[" + fromUserName + "]]></ToUserName>" + // 发送到原消息的发送者
// "<FromUserName><![CDATA[" + toUserName + "]]></FromUserName>" + // 您的公众号
// "<CreateTime>" + System.currentTimeMillis() / 1000 + "</CreateTime>" +
// "<MsgType><![CDATA[text]]></MsgType>" +
// "<Content><![CDATA[" + responseContent + "]]></Content>" +
// "</xml>";
//
// // 加密响应消息
// if ("aes".equals(encryptType)) {
// String encryptedResponse = wxBizMsgCrypt.encryptMsg(responseXml, timestamp, nonce);
// log.info("返回的加密内容是:{}", encryptedResponse);
// return encryptedResponse;
// } else {
// return responseXml; // 非加密模式,直接返回
// }
如果用上面这种回复方式 时间不能超过5秒 微信会连续3次 超过5秒就会断开连接
因此调用大模型回答的话建议是用异步客服消息方式 这也是官方给出的合理方式
关于这个加解密文档
关于加密文档 里面明确了Base64需要覆盖原先的 要用 1.8或者1.9
因为这里我调用了通义千问测试
引入通义千问依赖时候 发生了两种日志依赖冲突的问题
通义千问依赖中 和SpringBoot web依赖里的日志依赖冲突 需要排除下