task-reminder/src/main/java/com/zeodao/reminder/service/WechatWebhookService.java
2025-05-28 10:10:37 +08:00

298 lines
11 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.zeodao.reminder.service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zeodao.reminder.config.TaskReminderConfig;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 企业微信Webhook服务
*
* @author Zeodao
* @version 1.0.0
*/
@Service
public class WechatWebhookService {
private static final Logger logger = LoggerFactory.getLogger(WechatWebhookService.class);
@Autowired
private TaskReminderConfig taskReminderConfig;
private final ObjectMapper objectMapper = new ObjectMapper();
/**
* 发送文本消息到指定群组
*
* @param groupId 群组ID
* @param message 消息内容
* @return 是否发送成功
*/
public boolean sendTextMessage(String groupId, String message) {
try {
TaskReminderConfig.Group group = taskReminderConfig.getGroupById(groupId);
if (group == null) {
logger.error("未找到群组配置: {}", groupId);
return false;
}
Map<String, Object> messageBody = createTextMessage(message);
return sendMessage(group.getWebhook().getUrl(), messageBody);
} catch (Exception e) {
logger.error("发送企业微信消息失败, 群组: {}", groupId, e);
return false;
}
}
/**
* 发送Markdown格式消息到指定群组
*
* @param groupId 群组ID
* @param content Markdown内容
* @return 是否发送成功
*/
public boolean sendMarkdownMessage(String groupId, String content) {
try {
TaskReminderConfig.Group group = taskReminderConfig.getGroupById(groupId);
if (group == null) {
logger.error("未找到群组配置: {}", groupId);
return false;
}
Map<String, Object> messageBody = createMarkdownMessage(content);
return sendMessage(group.getWebhook().getUrl(), messageBody);
} catch (Exception e) {
logger.error("发送企业微信Markdown消息失败, 群组: {}", groupId, e);
return false;
}
}
/**
* 兼容旧版本的方法 - 发送到第一个启用的群组
*/
@Deprecated
public boolean sendMarkdownMessage(String content) {
List<TaskReminderConfig.Group> enabledGroups = taskReminderConfig.getEnabledGroups();
if (enabledGroups.isEmpty()) {
logger.error("没有启用的群组配置");
return false;
}
return sendMarkdownMessage(enabledGroups.get(0).getId(), content);
}
/**
* 创建文本消息体
*/
private Map<String, Object> createTextMessage(String content) {
Map<String, Object> message = new HashMap<>();
message.put("msgtype", "text");
Map<String, Object> text = new HashMap<>();
text.put("content", content);
message.put("text", text);
return message;
}
/**
* 创建Markdown消息体
*/
private Map<String, Object> createMarkdownMessage(String content) {
Map<String, Object> message = new HashMap<>();
message.put("msgtype", "markdown");
Map<String, Object> markdown = new HashMap<>();
markdown.put("content", content);
message.put("markdown", markdown);
return message;
}
/**
* 发送消息到企业微信
*/
private boolean sendMessage(String webhookUrl, Map<String, Object> messageBody) throws IOException {
int timeout = taskReminderConfig.getGlobal().getTimeout();
logger.info("准备发送消息到企业微信URL: {}", webhookUrl);
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpPost httpPost = new HttpPost(webhookUrl);
// 设置请求配置
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(timeout)
.setSocketTimeout(timeout)
.setConnectionRequestTimeout(timeout)
.build();
httpPost.setConfig(requestConfig);
// 设置请求头
httpPost.setHeader("Content-Type", "application/json; charset=utf-8");
// 设置请求体
String jsonBody = objectMapper.writeValueAsString(messageBody);
StringEntity entity = new StringEntity(jsonBody, StandardCharsets.UTF_8);
httpPost.setEntity(entity);
logger.debug("发送消息内容: {}", jsonBody);
// 执行请求
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
int statusCode = response.getStatusLine().getStatusCode();
String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
if (statusCode == 200) {
logger.info("企业微信消息发送成功,响应: {}", responseBody);
return true;
} else {
logger.error("企业微信消息发送失败,状态码: {}, 响应: {}", statusCode, responseBody);
return false;
}
}
}
}
/**
* 创建带时间戳的任务提醒消息
*/
public String createTaskReminderMessage(String groupId, String baseMessage, String timeType) {
TaskReminderConfig.Group group = taskReminderConfig.getGroupById(groupId);
if (group == null) {
logger.error("未找到群组配置: {}", groupId);
return baseMessage;
}
LocalDateTime now = LocalDateTime.now();
String timestamp = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
String dayOfWeek = getDayOfWeekInChinese(now.getDayOfWeek().getValue());
StringBuilder message = new StringBuilder();
// 根据任务管理系统类型生成不同的标题和操作指引
String systemName = getTaskSystemDisplayName(group.getTaskSystem());
String systemIcon = getTaskSystemIcon(group.getTaskSystem());
message.append("## ").append(systemIcon).append(" ").append(systemName).append("任务状态提醒\n\n");
message.append("**⏰ 时间:** ").append(timestamp).append(" (").append(dayOfWeek).append(")\n");
message.append("**📝 提醒类型:** ").append(timeType).append("\n\n");
message.append("### 📢 重要提醒\n");
message.append(baseMessage).append("\n\n");
message.append("### 🔗 操作指引\n");
message.append(getTaskSystemInstructions(group.getTaskSystem()));
message.append("---\n");
message.append("💡 **温馨提示:** 及时更新任务状态有助于团队协作和项目管理");
return message.toString();
}
/**
* 兼容旧版本的方法
*/
@Deprecated
public String createTaskReminderMessage(String baseMessage, String timeType) {
List<TaskReminderConfig.Group> enabledGroups = taskReminderConfig.getEnabledGroups();
if (enabledGroups.isEmpty()) {
return baseMessage;
}
return createTaskReminderMessage(enabledGroups.get(0).getId(), baseMessage, timeType);
}
/**
* 获取任务管理系统的显示名称
*/
private String getTaskSystemDisplayName(String taskSystem) {
switch (taskSystem.toLowerCase()) {
case "zentao": return "禅道";
case "smartsheet": return "智能表格";
case "jira": return "Jira";
case "trello": return "Trello";
case "asana": return "Asana";
case "notion": return "Notion";
default: return "任务管理系统";
}
}
/**
* 获取任务管理系统的图标
*/
private String getTaskSystemIcon(String taskSystem) {
switch (taskSystem.toLowerCase()) {
case "zentao": return "📋";
case "smartsheet": return "📊";
case "jira": return "🎯";
case "trello": return "📌";
case "asana": return "";
case "notion": return "📝";
default: return "📋";
}
}
/**
* 获取任务管理系统的操作指引
*/
private String getTaskSystemInstructions(String taskSystem) {
switch (taskSystem.toLowerCase()) {
case "zentao":
return "1. 登录禅道系统\n" +
"2. 查看分配给自己的任务\n" +
"3. 更新任务状态和进度\n" +
"4. 添加必要的工作日志\n\n";
case "smartsheet":
return "1. 打开智能表格\n" +
"2. 找到自己负责的任务行\n" +
"3. 更新任务状态和完成百分比\n" +
"4. 添加备注说明进展情况\n\n";
case "jira":
return "1. 登录Jira系统\n" +
"2. 查看分配给自己的Issue\n" +
"3. 更新Issue状态\n" +
"4. 记录工作日志和时间\n\n";
case "trello":
return "1. 打开Trello看板\n" +
"2. 找到自己的任务卡片\n" +
"3. 移动卡片到对应状态列\n" +
"4. 添加评论记录进展\n\n";
default:
return "1. 登录任务管理系统\n" +
"2. 查看分配给自己的任务\n" +
"3. 更新任务状态和进度\n" +
"4. 添加必要的工作记录\n\n";
}
}
/**
* 获取中文星期
*/
private String getDayOfWeekInChinese(int dayOfWeek) {
switch (dayOfWeek) {
case 1: return "星期一";
case 2: return "星期二";
case 3: return "星期三";
case 4: return "星期四";
case 5: return "星期五";
case 6: return "星期六";
case 7: return "星期日";
default: return "未知";
}
}
}