添加钉钉机器人
This commit is contained in:
@@ -150,6 +150,27 @@ public class AppFeedbackController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试钉钉推送
|
||||||
|
*/
|
||||||
|
@GetMapping("/test-dingtalk")
|
||||||
|
public Result<String> testDingTalk() {
|
||||||
|
try {
|
||||||
|
String title = "测试消息";
|
||||||
|
String text = "### 🔔 钉钉推送测试\n\n这是一条测试消息,用于验证钉钉推送功能是否正常工作。\n\n**测试时间:** " +
|
||||||
|
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||||
|
|
||||||
|
boolean success = dingTalkUtil.sendMarkdownMessage(title, text);
|
||||||
|
if (success) {
|
||||||
|
return Result.success("钉钉推送测试成功,请检查钉钉群消息");
|
||||||
|
} else {
|
||||||
|
return Result.error("钉钉推送测试失败,请检查配置和日志");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error("测试异常: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送反馈信息到钉钉
|
* 发送反馈信息到钉钉
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -5,10 +5,14 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.crypto.Mac;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Base64;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -22,6 +26,9 @@ public class DingTalkUtil {
|
|||||||
@Value("${dingtalk.webhook:}")
|
@Value("${dingtalk.webhook:}")
|
||||||
private String webhook;
|
private String webhook;
|
||||||
|
|
||||||
|
@Value("${dingtalk.secret:}")
|
||||||
|
private String secret;
|
||||||
|
|
||||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -119,6 +126,20 @@ public class DingTalkUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成钉钉签名
|
||||||
|
*
|
||||||
|
* @param timestamp 时间戳
|
||||||
|
* @return 签名
|
||||||
|
*/
|
||||||
|
private String generateSign(long timestamp) throws Exception {
|
||||||
|
String stringToSign = timestamp + "\n" + secret;
|
||||||
|
Mac mac = Mac.getInstance("HmacSHA256");
|
||||||
|
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
|
||||||
|
byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
|
||||||
|
return URLEncoder.encode(Base64.getEncoder().encodeToString(signData), "UTF-8");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送 HTTP 请求到钉钉机器人
|
* 发送 HTTP 请求到钉钉机器人
|
||||||
*
|
*
|
||||||
@@ -128,7 +149,17 @@ public class DingTalkUtil {
|
|||||||
private boolean sendRequest(Map<String, Object> message) {
|
private boolean sendRequest(Map<String, Object> message) {
|
||||||
HttpURLConnection connection = null;
|
HttpURLConnection connection = null;
|
||||||
try {
|
try {
|
||||||
URL url = new URL(webhook);
|
String finalWebhook = webhook;
|
||||||
|
|
||||||
|
// 如果配置了 secret,需要添加签名
|
||||||
|
if (secret != null && !secret.trim().isEmpty()) {
|
||||||
|
long timestamp = System.currentTimeMillis();
|
||||||
|
String sign = generateSign(timestamp);
|
||||||
|
finalWebhook = webhook + "×tamp=" + timestamp + "&sign=" + sign;
|
||||||
|
log.info("使用加签模式,timestamp: {}", timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
URL url = new URL(finalWebhook);
|
||||||
connection = (HttpURLConnection) url.openConnection();
|
connection = (HttpURLConnection) url.openConnection();
|
||||||
connection.setRequestMethod("POST");
|
connection.setRequestMethod("POST");
|
||||||
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
|
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
|
||||||
@@ -138,6 +169,8 @@ public class DingTalkUtil {
|
|||||||
|
|
||||||
// 发送请求
|
// 发送请求
|
||||||
String jsonMessage = objectMapper.writeValueAsString(message);
|
String jsonMessage = objectMapper.writeValueAsString(message);
|
||||||
|
log.info("发送钉钉消息: {}", jsonMessage);
|
||||||
|
|
||||||
try (OutputStream os = connection.getOutputStream()) {
|
try (OutputStream os = connection.getOutputStream()) {
|
||||||
byte[] input = jsonMessage.getBytes(StandardCharsets.UTF_8);
|
byte[] input = jsonMessage.getBytes(StandardCharsets.UTF_8);
|
||||||
os.write(input, 0, input.length);
|
os.write(input, 0, input.length);
|
||||||
@@ -145,11 +178,26 @@ public class DingTalkUtil {
|
|||||||
|
|
||||||
// 读取响应
|
// 读取响应
|
||||||
int responseCode = connection.getResponseCode();
|
int responseCode = connection.getResponseCode();
|
||||||
|
|
||||||
|
// 读取响应体(包含错误信息)
|
||||||
|
java.io.BufferedReader br = new java.io.BufferedReader(
|
||||||
|
new java.io.InputStreamReader(
|
||||||
|
responseCode >= 400 ? connection.getErrorStream() : connection.getInputStream(),
|
||||||
|
StandardCharsets.UTF_8
|
||||||
|
)
|
||||||
|
);
|
||||||
|
StringBuilder response = new StringBuilder();
|
||||||
|
String responseLine;
|
||||||
|
while ((responseLine = br.readLine()) != null) {
|
||||||
|
response.append(responseLine.trim());
|
||||||
|
}
|
||||||
|
br.close();
|
||||||
|
|
||||||
if (responseCode == HttpURLConnection.HTTP_OK) {
|
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||||||
log.info("钉钉消息推送成功");
|
log.info("钉钉消息推送成功, 响应: {}", response.toString());
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
log.error("钉钉消息推送失败, HTTP 状态码: {}", responseCode);
|
log.error("钉钉消息推送失败, HTTP 状态码: {}, 响应: {}", responseCode, response.toString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -81,5 +81,7 @@ spring.mail.properties.mail.smtp.socketFactory.port=465
|
|||||||
spring.mail.properties.mail.smtp.socketFactory.fallback=false
|
spring.mail.properties.mail.smtp.socketFactory.fallback=false
|
||||||
|
|
||||||
# 钉钉机器人配置
|
# 钉钉机器人配置
|
||||||
# 请前往钉钉群设置 -> 智能群助手 -> 添加机器人 -> 自定义机器人,获取 Webhook 地址
|
# 请前往钉钉群设置 -> 智能群助手 -> 添加机器人 -> 自定义机器人,获取 Webhook 地址和密钥
|
||||||
dingtalk.webhook=https://oapi.dingtalk.com/robot/send?access_token=7eed4b3483303c9ec71ef37a08c347bb597fd4c64211a96a8f55f72405ff6444
|
dingtalk.webhook=https://oapi.dingtalk.com/robot/send?access_token=7eed4b3483303c9ec71ef37a08c347bb597fd4c64211a96a8f55f72405ff6444
|
||||||
|
# 如果使用加签安全设置,请填写密钥(secret)
|
||||||
|
dingtalk.secret=SEC0f2b835f28139905e3c0b5be979b215df1735f1154f36514aafbae8708014148
|
||||||
|
|||||||
Reference in New Issue
Block a user