package org.linxidev.utils;
import com.alibaba.fastjson2.JSONObject;
import lombok.Data;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
public class NoticeUtils {
@Data
private static class EmailConfig {
private String host;
private String port;
private String username;
private String password;
private String auth;
private String protocol;
private String debug;
private String sslEnable;
}
@Data
private static class DingTalkConfig {
private String host;
private String secret;
}
private static EmailConfig emailConfig;
private static DingTalkConfig dingTalkConfig;
public static String sendEmail(String title, String content, List<String> toUsers) {
checkEmailConfig();
Properties props = new Properties();
props.setProperty("mail.smtp.host", emailConfig.host);
props.setProperty("mail.smtp.port", emailConfig.port);
props.setProperty("mail.smtp.auth", emailConfig.auth);
props.put("mail.smtp.ssl.enable", emailConfig.sslEnable);
props.put("mail.smtp.debug", emailConfig.debug);
props.put("mail.transport.protocol",emailConfig.protocol);
Session session = Session.getInstance(props);
Message message = new MimeMessage(session);
try {
message.setFrom(new InternetAddress(emailConfig.username, "告警通知平台", "UTF-8"));
Address[] addresses = toUsers.stream().map(email -> {try { return new InternetAddress(email); } catch (AddressException e) {}return null;}).filter(java.util.Objects::nonNull).toArray(Address[]::new);
message.setRecipients(Message.RecipientType.TO, addresses);
message.setSubject(title);
String body = "<!DOCTYPE html><html xmlns:th=\"http://www.thymeleaf.org\"><head><meta charset=\"utf-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"><meta name=\"description\" content=\"email code\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><style>/* 默认样式 */table.main-table { width: 50%; height: 100%; margin: 0px auto; text-align: left; position: relative; border-radius: 5px; font-size: 14px; font-family: '微软雅黑', '黑体', Arial, sans-serif; line-height: 1.5; box-shadow: rgb(153, 153, 153) 0px 0px 5px; border-collapse: collapse; background-color: #fff;}/* 媒体查询,适用于手机端 */@media only screen and (max-width: 600px) { table.main-table { width: 100% !important; /* 使用!important提高优先级 */ }}</style></head><body><div style=\"background-color:#fff; padding: 0px;\"><table class=\"main-table\" cellpadding=\"0\" align=\"center\"><tbody><tr><th valign=\"middle\" style=\"height: 25px; line-height: 25px; padding: 15px 35px; border-bottom: 1px solid RGB(148,0,211); background-color: #3A71E6; border-top-left-radius: 5px; border-top-right-radius: 5px;\"><font face=\"微软雅黑\" size=\"5\" style=\"color: rgb(255, 255, 255); \">"+title+"</font></th></tr><tr><td style=\"word-break:break-all\"><div style=\"padding:25px 35px 40px; background-color:#fff;opacity:0.8;\"><h2 style=\"margin: 5px 0px; \"><font color=\"#333333\" style=\"line-height: 20px; \"><font style=\"line-height: 22px; \" size=\"4\">尊敬的用户:</font></font></h2><p>"+content+"</p><br><div style=\"width:100%;margin:0 auto;\"><div style=\"padding:10px 10px 0;border-top:1px solid #ccc;color:#747474;margin-bottom:20px;line-height:1.3em;font-size:12px;\"><p>林夕科技团队</p><p>联系我们:linxi@linxi.tk</p><p>此为系统邮件,请勿回复<br>Please do not reply to this system email</p></div></div></div></td></tr></tbody></table></div></body></html>";
message.setContent(body,"text/html;charset=UTF-8");
Transport transport = session.getTransport();
transport.connect(emailConfig.username, emailConfig.password);
transport.sendMessage(message, message.getAllRecipients());
transport.close();
return "邮件通知: 成功!";
} catch (Exception e) {
return "邮件通知: 异常 "+e.getMessage();
}
}
public static String sendDingTalk(String title, String content, List<String> toUsers,boolean isAtAll) {
checkDingTalkConfig();
JSONObject json = new JSONObject();
json.put("msgtype", "text");
json.put("text", new JSONObject().fluentPut("content", title + ":\n" +content));
json.put("at", new JSONObject().fluentPut("atMobiles", toUsers).fluentPut("isAtAll", isAtAll));
long timestamp = System.currentTimeMillis();
try {
String sign = dingSign(timestamp,dingTalkConfig.secret);
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
String response = HttpsUtils.urlSend(dingTalkConfig.host + "×tamp=" + timestamp + "&sign=" + sign, "POST", false, json.toString(),headers);
JSONObject object = JSONObject.parseObject(response);
if (object.getInteger("errcode") == 0){
return "钉钉通知: 成功 " + object.getString("errmsg");
}
return "钉钉通知: 失败" + object.getString("errmsg");
} catch (Exception e) {
return "钉钉通知: 异常 " + e.getMessage();
}
}
public static String dingSign(long timestamp, String secret) 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));
String base64Sign = Base64.getEncoder().encodeToString(signData);
return URLEncoder.encode(base64Sign, StandardCharsets.UTF_8);
}
private static void checkEmailConfig() {
if (emailConfig.host == null || emailConfig.host.isEmpty()) {
throw new IllegalStateException("邮件配置未初始化");
}
}
private static void checkDingTalkConfig() {
if (dingTalkConfig.host == null || dingTalkConfig.host.isEmpty()) {
throw new IllegalStateException("钉钉配置未初始化");
}
}
public static void main(String[] args) {
String email = "{\"host\":\"smtp.qq.com\",\"port\":\"465\",\"username\":\"xxx@qq.com\",\"password\":\"xxxx\",\"protocol\":\"smtp\",\"auth\":\"true\",\"debug\":\"false\",\"sslEnable\":\"true\"}";
String ding = "{\"host\": \"https://oapi.dingtalk.com/robot/send?access_token=\",\"secret\" : \"secret\"}";
emailConfig = JSONObject.parseObject(email,EmailConfig.class);
dingTalkConfig = JSONObject.parseObject(ding,DingTalkConfig.class);
// 测试邮件
List<String> toEmails = List.of("linxi@linxi.tk");
System.out.println(sendEmail("测试邮件", "测试", toEmails));
List<String> toDings = List.of("123456789");
System.out.println(sendDingTalk("测试钉钉", "测试", toDings,false));
}
}