添加钉钉机器人
Some checks failed
CI Build and Test / build (push) Has been cancelled
Deploy to Server / build-and-deploy (push) Has been cancelled

This commit is contained in:
2025-10-21 09:05:20 +08:00
parent c176edead5
commit dfdde28aa2
3 changed files with 225 additions and 1 deletions

View File

@@ -7,8 +7,11 @@ import com.corewing.app.common.Result;
import com.corewing.app.dto.FeedbackRequest;
import com.corewing.app.entity.AppFeedback;
import com.corewing.app.service.AppFeedbackService;
import com.corewing.app.util.DingTalkUtil;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
/**
@@ -19,9 +22,11 @@ import java.util.List;
public class AppFeedbackController {
private final AppFeedbackService feedbackService;
private final DingTalkUtil dingTalkUtil;
public AppFeedbackController(AppFeedbackService feedbackService) {
public AppFeedbackController(AppFeedbackService feedbackService, DingTalkUtil dingTalkUtil) {
this.feedbackService = feedbackService;
this.dingTalkUtil = dingTalkUtil;
}
/**
@@ -47,6 +52,8 @@ public class AppFeedbackController {
boolean success = feedbackService.createFeedback(feedback);
if (success) {
// 推送到钉钉
sendFeedbackToDingTalk(feedback);
return Result.success("反馈提交成功");
}
return Result.error("反馈提交失败");
@@ -142,4 +149,53 @@ public class AppFeedbackController {
return Result.error(e.getMessage());
}
}
/**
* 发送反馈信息到钉钉
*/
private void sendFeedbackToDingTalk(AppFeedback feedback) {
try {
String title = "📢 新的用户反馈";
StringBuilder text = new StringBuilder();
text.append("### 📢 新的用户反馈\n\n");
text.append("---\n\n");
// 用户信息
if (feedback.getUserId() != null) {
text.append("**用户ID** ").append(feedback.getUserId()).append("\n\n");
} else {
text.append("**用户ID** 匿名用户\n\n");
}
// 反馈类型
text.append("**问题类型:** ").append(feedback.getFeedbackType()).append("\n\n");
// 反馈标题
text.append("**问题标题:** ").append(feedback.getTitle()).append("\n\n");
// 反馈内容
if (feedback.getContent() != null && !feedback.getContent().trim().isEmpty()) {
text.append("**问题描述:** \n\n").append(feedback.getContent()).append("\n\n");
}
// 联系方式
if (feedback.getContact() != null && !feedback.getContact().trim().isEmpty()) {
text.append("**联系方式:** ").append(feedback.getContact()).append("\n\n");
}
// 提交时间
text.append("**提交时间:** ").append(
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
).append("\n\n");
text.append("---\n\n");
text.append("> 请及时处理用户反馈!");
// 异步发送钉钉消息(避免阻塞用户请求)
new Thread(() -> dingTalkUtil.sendMarkdownMessage(title, text.toString())).start();
} catch (Exception e) {
// 钉钉推送失败不影响反馈提交,只记录日志
// log.error("推送反馈到钉钉失败: {}", e.getMessage(), e);
}
}
}

View File

@@ -0,0 +1,164 @@
package com.corewing.app.util;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
/**
* 钉钉机器人推送工具类
*/
@Slf4j
@Component
public class DingTalkUtil {
@Value("${dingtalk.webhook:}")
private String webhook;
private static final ObjectMapper objectMapper = new ObjectMapper();
/**
* 发送文本消息到钉钉
*
* @param content 消息内容
* @return 是否发送成功
*/
public boolean sendTextMessage(String content) {
return sendTextMessage(content, null);
}
/**
* 发送文本消息到钉钉
*
* @param content 消息内容
* @param atMobiles 需要@的手机号列表
* @return 是否发送成功
*/
public boolean sendTextMessage(String content, String[] atMobiles) {
if (webhook == null || webhook.trim().isEmpty()) {
log.warn("钉钉 Webhook 未配置,跳过消息推送");
return false;
}
try {
Map<String, Object> message = new HashMap<>();
message.put("msgtype", "text");
Map<String, Object> text = new HashMap<>();
text.put("content", content);
message.put("text", text);
// @人员配置
if (atMobiles != null && atMobiles.length > 0) {
Map<String, Object> at = new HashMap<>();
at.put("atMobiles", atMobiles);
at.put("isAtAll", false);
message.put("at", at);
}
return sendRequest(message);
} catch (Exception e) {
log.error("发送钉钉文本消息失败: {}", e.getMessage(), e);
return false;
}
}
/**
* 发送 Markdown 消息到钉钉
*
* @param title 消息标题
* @param text Markdown 内容
* @return 是否发送成功
*/
public boolean sendMarkdownMessage(String title, String text) {
return sendMarkdownMessage(title, text, null);
}
/**
* 发送 Markdown 消息到钉钉
*
* @param title 消息标题
* @param text Markdown 内容
* @param atMobiles 需要@的手机号列表
* @return 是否发送成功
*/
public boolean sendMarkdownMessage(String title, String text, String[] atMobiles) {
if (webhook == null || webhook.trim().isEmpty()) {
log.warn("钉钉 Webhook 未配置,跳过消息推送");
return false;
}
try {
Map<String, Object> message = new HashMap<>();
message.put("msgtype", "markdown");
Map<String, Object> markdown = new HashMap<>();
markdown.put("title", title);
markdown.put("text", text);
message.put("markdown", markdown);
// @人员配置
if (atMobiles != null && atMobiles.length > 0) {
Map<String, Object> at = new HashMap<>();
at.put("atMobiles", atMobiles);
at.put("isAtAll", false);
message.put("at", at);
}
return sendRequest(message);
} catch (Exception e) {
log.error("发送钉钉 Markdown 消息失败: {}", e.getMessage(), e);
return false;
}
}
/**
* 发送 HTTP 请求到钉钉机器人
*
* @param message 消息体
* @return 是否发送成功
*/
private boolean sendRequest(Map<String, Object> message) {
HttpURLConnection connection = null;
try {
URL url = new URL(webhook);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
connection.setDoOutput(true);
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
// 发送请求
String jsonMessage = objectMapper.writeValueAsString(message);
try (OutputStream os = connection.getOutputStream()) {
byte[] input = jsonMessage.getBytes(StandardCharsets.UTF_8);
os.write(input, 0, input.length);
}
// 读取响应
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
log.info("钉钉消息推送成功");
return true;
} else {
log.error("钉钉消息推送失败, HTTP 状态码: {}", responseCode);
return false;
}
} catch (Exception e) {
log.error("钉钉消息推送异常: {}", e.getMessage(), e);
return false;
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}

View File

@@ -79,3 +79,7 @@ spring.mail.properties.mail.smtp.ssl.required=true
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
spring.mail.properties.mail.smtp.socketFactory.port=465
spring.mail.properties.mail.smtp.socketFactory.fallback=false
# 钉钉机器人配置
# 请前往钉钉群设置 -> 智能群助手 -> 添加机器人 -> 自定义机器人,获取 Webhook 地址
dingtalk.webhook=https://oapi.dingtalk.com/robot/send?access_token=7eed4b3483303c9ec71ef37a08c347bb597fd4c64211a96a8f55f72405ff6444