Files
schemaCheck/src/main/java/com/codechecker/cache/notify/WeComNotifier.java
dongzi e7aa970ef8
All checks were successful
缓存序列化结构检查 / cache-schema-check (push) Has been skipped
feat:
1、多 key 默认拼成 1 条企微通知
2、UTF-8 超过 4096 字节 → 按 key 拆开,每条带完整抬头,依次发送
3、条间间隔 200ms,降低机器人限频风险
4、CI 控制台会标明「超长已按 key 拆为 N 条」并逐条打印
2026-07-14 14:30:24 +08:00

101 lines
3.8 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.codechecker.cache.notify;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* 企业微信群机器人通知markdown 消息)。
*/
public class WeComNotifier {
private final ObjectMapper mapper = new ObjectMapper();
private final HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.build();
/**
* @return 是否发送成功
*/
public boolean sendMarkdown(String webhookUrl, String markdown) {
if (webhookUrl == null || webhookUrl.trim().isEmpty()) {
System.err.println("[WeComNotifier] 未配置 webhook跳过通知");
return false;
}
try {
Map<String, Object> md = new LinkedHashMap<>();
md.put("content", markdown);
Map<String, Object> payload = new LinkedHashMap<>();
payload.put("msgtype", "markdown");
payload.put("markdown", md);
String body = mapper.writeValueAsString(payload);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(webhookUrl))
.timeout(Duration.ofSeconds(15))
.header("Content-Type", "application/json; charset=utf-8")
.POST(HttpRequest.BodyPublishers.ofString(body, StandardCharsets.UTF_8))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
// 企微成功时 body 一般为 {"errcode":0,...}
if (response.body() != null && response.body().contains("\"errcode\":0")) {
return true;
}
if (response.body() != null && response.body().contains("errcode")
&& !response.body().contains("\"errcode\":0")) {
System.err.println("[WeComNotifier] 通知失败: " + response.body());
return false;
}
return true;
}
System.err.println("[WeComNotifier] 通知失败, HTTP " + response.statusCode() + ": " + response.body());
return false;
} catch (Exception e) {
System.err.println("[WeComNotifier] 通知异常: " + e.getMessage());
return false;
}
}
/**
* 按序发送多条 Markdown用于超长按 key 拆分后的通知)。
*
* @return 成功条数
*/
public int sendMarkdownMessages(String webhookUrl, List<String> markdownMessages) {
if (markdownMessages == null || markdownMessages.isEmpty()) {
return 0;
}
int ok = 0;
for (int i = 0; i < markdownMessages.size(); i++) {
String content = markdownMessages.get(i);
boolean success = sendMarkdown(webhookUrl, content);
if (success) {
ok++;
}
System.out.println("[WeComNotifier] 第 " + (i + 1) + "/" + markdownMessages.size()
+ " 条发送" + (success ? "成功" : "失败")
+ " (" + content.getBytes(StandardCharsets.UTF_8).length + " bytes)");
// 避免触发机器人频率限制(约 20 条/分钟)
if (i < markdownMessages.size() - 1) {
try {
Thread.sleep(200L);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}
return ok;
}
}