package com.codechecker.common; import java.io.IOException; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.time.Duration; /** * 企微 Markdown 发送(与具体变更类型解耦)。 */ public class WeComMarkdownSender { private static final int MAX_LENGTH = 3800; private final HttpClient client = HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(10)) .build(); public boolean send(String webhookUrl, String content) { return postMarkdown(webhookUrl, truncate(content)); } public void logPreview(String title, String content) { System.out.println("========== " + title + " =========="); System.out.println(content); System.out.println("========== 结束 =========="); } private boolean postMarkdown(String webhookUrl, String content) { if (webhookUrl == null || webhookUrl.isBlank() || webhookUrl.contains("YOUR_WECOM")) { System.out.println("[警告] 未配置有效的企业微信 Webhook URL"); System.out.println("--- 通知预览 ---"); System.out.println(content.length() > 1000 ? content.substring(0, 1000) : content); return false; } String payload = "{\"msgtype\":\"markdown\",\"markdown\":{\"content\":" + jsonEscape(content) + "}}"; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(webhookUrl)) .timeout(Duration.ofSeconds(10)) .header("Content-Type", "application/json; charset=utf-8") .POST(HttpRequest.BodyPublishers.ofString(payload)) .build(); try { HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); int statusCode = response.statusCode(); if (statusCode >= 200 && statusCode < 300) { String body = response.body(); return body != null && body.contains("\"errcode\":0"); } String body = response.body(); System.out.println("[错误] 企微返回异常: " + statusCode + (body != null ? " " + body : "")); return false; } catch (InterruptedException e) { Thread.currentThread().interrupt(); System.out.println("[错误] 发送企微消息失败: " + e.getMessage()); return false; } catch (IOException e) { System.out.println("[错误] 发送企微消息失败: " + e.getMessage()); return false; } } private String truncate(String text) { if (text.length() <= MAX_LENGTH) { return text; } return text.substring(0, MAX_LENGTH) + "\n\n... 消息过长,已截断"; } private String jsonEscape(String text) { String escaped = text .replace("\\", "\\\\") .replace("\"", "\\\"") .replace("\n", "\\n") .replace("\r", ""); return "\"" + escaped + "\""; } }