Files
ruoyi-java/ruoyi-admin/src/main/java/com/ruoyi/jarvis/wecom/WxSendWeComPushClient.java
2026-04-02 20:09:31 +08:00

118 lines
4.1 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.ruoyi.jarvis.wecom;
import com.alibaba.fastjson2.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* 调用 wxSend 的企微应用文本主动推送POST /wecom/active-push
*/
@Component
public class WxSendWeComPushClient {
private static final Logger log = LoggerFactory.getLogger(WxSendWeComPushClient.class);
public static final String HEADER_PUSH_SECRET = "X-WxSend-WeCom-Push-Secret";
@Value("${jarvis.wecom.wxsend-base-url:}")
private String wxsendBaseUrl;
@Value("${jarvis.wecom.push-secret:}")
private String pushSecret;
/**
* 在被动回复返回后延迟再发,保证企微侧先出现首条被动消息。
*/
public void scheduleActivePushes(String toUser, List<String> contents) {
if (!StringUtils.hasText(wxsendBaseUrl) || !StringUtils.hasText(pushSecret)
|| !StringUtils.hasText(toUser) || contents == null || contents.isEmpty()) {
return;
}
final String userId = toUser.trim();
final List<String> list = new ArrayList<>(contents);
CompletableFuture.runAsync(() -> {
try {
Thread.sleep(450);
String base = normalizeBase(wxsendBaseUrl);
String url = base + "/wecom/active-push";
for (String c : list) {
if (!StringUtils.hasText(c)) {
continue;
}
postJson(url, userId, c.trim());
Thread.sleep(120);
}
} catch (Exception e) {
log.warn("企微主动推送任务异常 userId={} msg={}", userId, e.toString());
}
});
}
private static String normalizeBase(String base) {
String b = base.trim();
if (b.endsWith("/")) {
return b.substring(0, b.length() - 1);
}
return b;
}
private void postJson(String url, String toUser, String content) {
JSONObject body = new JSONObject();
body.put("toUser", toUser);
body.put("content", content);
byte[] bytes = body.toJSONString().getBytes(StandardCharsets.UTF_8);
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) new URL(url).openConnection();
conn.setRequestMethod("POST");
conn.setConnectTimeout(15000);
conn.setReadTimeout(60000);
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
conn.setRequestProperty(HEADER_PUSH_SECRET, pushSecret);
try (OutputStream os = conn.getOutputStream()) {
os.write(bytes);
}
int code = conn.getResponseCode();
InputStream is = code >= 200 && code < 300 ? conn.getInputStream() : conn.getErrorStream();
String resp = readAll(is);
if (code < 200 || code >= 300) {
log.warn("wxSend active-push HTTP {} body={}", code, resp);
} else {
log.debug("wxSend active-push OK http={} resp={}", code, resp);
}
} catch (Exception e) {
log.warn("wxSend active-push 请求失败 url={} err={}", url, e.toString());
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
private static String readAll(InputStream is) throws java.io.IOException {
if (is == null) {
return "";
}
byte[] buf = new byte[4096];
StringBuilder sb = new StringBuilder();
int n;
while ((n = is.read(buf)) >= 0) {
sb.append(new String(buf, 0, n, StandardCharsets.UTF_8));
}
return sb.toString();
}
}