1. 发送企业微信消息
package cn.com.app.base.context;
import cn.com.app.base.dto.MessageDto;
import cn.com.app.base.dto.MessageSendResultDto;
import cn.com.app.base.utils.HttpUtils;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class AppWxWarnContext {
/**
* 企业微信发送监控信息
*
* @param messageDto
* @param msgKey 企业微信机器人对应key https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=
* @return
*/
public MessageSendResultDto sendMsg(MessageDto messageDto, String msgKey) {
String url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=" + msgKey;
String messgeJsonStr = messageDto.toJsonString();
log.info("----> 单条发送企业微信通知,json:{},url:{},proxyAdress:{}", messgeJsonStr, url, proxyAdress);
String result = HttpUtils.postJsonRequest(url,messgeJsonStr);
if(StringUtils.isNotBlank(result)) {
MessageSendResultDto messageSendResult = JSON.parseObject(result, MessageSendResultDto.class);
if(!messageSendResult.isSuccess()){
log.info("---->单条发送企业微信通知发送失败: {}",JSON.toJSONString(messageSendResult));
}
return messageSendResult;
}
return null;
}
}
2. 发送企业微信消息格式
package cn.com.app.base.service;
import cn.com.app.base.dto.MessageDto;
import cn.com.app.base.dto.MessageSendResultDto;
import java.net.InetAddress;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
public abstract class AbstractWxWarnService<T> {
public final String title = "> **APP-%s 提醒** ";
public final String commentItem = "> **%s:**<font color=\"#000000\">%s</font>";
public final String warningItem = "> **%s:**<font color=\"#FF3300\">%s</font>";
public final String warningItem2 = "> **%s:\n**<font color=\"#FF3300\">%s</font>";
public final String warningItem4 = "> **%s:**<font color=\"red\">%s</font>";
public final String longtext = "> **%s:**\n<font color=\"comment\">%s</font>";
// 日期格式
protected final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//服务器IP
protected String serverIp;
public AbstractWxWarnService() {
// 服务器IP
try {
serverIp = InetAddress.getLocalHost().getHostAddress();
} catch (Exception exception) {
log.error("PmisLog获取服务IP失败");
serverIp = "0.0.0.0";
}
}
public abstract MessageSendResultDto sendWxMessage(T wxMsgDto);
protected abstract MessageDto assemblyWxMessage(T wxMsgDto);
protected String getExceptionStack(Throwable err){
// 异常堆栈
StringBuilder stack = new StringBuilder();
stack.append(err.toString());
stack.append("\n");
// 消息内容长度不能过长,只打印异常栈的第一个和带cn.com.app的异常信息
StackTraceElement root = err.getStackTrace()[0];
stack.append(root.toString());
for (StackTraceElement element : err.getStackTrace()) {
if (element.getClassName().contains("cn.com.app") && !element.equals(root)) {
stack.append("\n");
stack.append(element.toString());
}
}
return stack.toString();
}
}
package cn.com.app.base.service;
import cn.com.app.base.config.WxMsgPropertyConfig;
import cn.com.app.base.context.AppWxWarnContext;
import cn.com.app.base.dto.MarkdownMessageDto;
import cn.com.app.base.dto.MessageDto;
import cn.com.app.base.dto.MessageSendResultDto;
import cn.com.app.base.dto.SystemExceptionMsgDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
@Service
public class SystemExcepWxWarnService extends AbstractWxWarnService<SystemExceptionMsgDto> {
@Autowired
private AppWxWarnContext appWxWarnContext;
@Autowired
private WxMsgPropertyConfig wxMsgPropertyConfig;
@Override
public MessageSendResultDto sendWxMessage(SystemExceptionMsgDto systemExceptionMsgDto) {
MessageDto messageDto = this.assemblyWxMessage(systemExceptionMsgDto);
return appWxWarnContext.sendMsg(messageDto, wxMsgPropertyConfig.getSysExcetionMsgKey());
}
/**
* @Description 获取企业微信预警内容
*/
@Override
protected MessageDto assemblyWxMessage(SystemExceptionMsgDto systemExceptionMsgDto) {
MarkdownMessageDto message = new MarkdownMessageDto();
message.add(String.format(title, "系统预警"));
message.add(String.format(commentItem, "请求参数", systemExceptionMsgDto.getRequestParam()));
message.add(String.format(warningItem, "服务器IP", super.serverIp));
message.add(String.format(commentItem, "请求地址", systemExceptionMsgDto.getRequestUrl()));
message.add(String.format(commentItem, "请求时间", super.dateFormat.format(new Date())));
message.add(String.format(commentItem, "异常信息", systemExceptionMsgDto.getExceptionDesc()));
message.add(String.format(commentItem, "异常栈", super.getExceptionStack(systemExceptionMsgDto.getException())));
return message;
}
}
package cn.com.app.server.support.impl;
import cn.com.app.base.config.WxMsgPropertyConfig;
import cn.com.app.base.context.AppWxWarnContext;
import cn.com.app.base.dto.MarkdownMessageDto;
import cn.com.app.base.dto.MessageDto;
import cn.com.app.base.dto.MessageSendResultDto;
import cn.com.app.base.service.AbstractWxWarnService;
import cn.com.app.server.dto.SignInWarnMsgDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.apache.commons.lang3.StringUtils;
import java.util.Date;
@Service
public class SignInWxWarnService extends AbstractWxWarnService<SignInWarnMsgDto> {
@Autowired
private AppWxWarnContext appWxWarnContext;
@Autowired
private WxMsgPropertyConfig wxMsgPropertyConfig;
@Override
public MessageSendResultDto sendWxMessage(SignInWarnMsgDto signInWarnMsgDto) {
MessageDto messageDto = this.assemblyWxMessage(signInWarnMsgDto);
return appWxWarnContext.sendMsg(messageDto, wxMsgPropertyConfig.getSignInWarnMsgKey());
}
@Override
protected MessageDto assemblyWxMessage(SignInWarnMsgDto signInWarnMsgDto) {
MarkdownMessageDto message = new MarkdownMessageDto();
message.add(String.format(title, "签到预警"));
message.add(String.format(commentItem, "已签到人数", signInWarnMsgDto.getSignedInNum()));
message.add(String.format(warningItem, "未签到人数", signInWarnMsgDto.getNotSignedInNum()));
message.add(String.format(warningItem, "未签到人员姓名", StringUtils.join(signInWarnMsgDto.getNotSignedInEmployeeList(),',')));
message.add(String.format(commentItem, "签到时间", super.dateFormat.format(new Date())));
return message;
}
}
3. 配置
package cn.com.app.base.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Configuration
@Data
public class WxMsgPropertyConfig {
/**
* 签到预警-企业微信消息key
*/
@Value("${app.signIn.warn.msg.key:}")
private String signInWarnMsgKey;
/**
* 系统异常 - 企业微信消息key
*/
@Value("${app.sys.excep.msg.key:}")
private String sysExcetionMsgKey;
}
package cn.com.app.base.dto;
import cn.com.app.base.enums.MessageTypeEnum;
import com.alibaba.fastjson.JSON;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
/**
* 企业微信群机器人消息抽象类
*/
@Data
public abstract class MessageDto {
/**
* 消息类型 :
*
* 文本
* text
* 图片
* image
* MD文本
* markdown
* 图文
* news
* 文件
* file
* 模板卡片
* template_card
**/
private MessageTypeEnum messageType;
/**
* 不用抽象了 直接写输出
* @return
*/
public String toJsonString(){
Map<String, Object> items = new HashMap<String, Object>();
items.put("msgtype", messageType.getValue());
Map<String, Object> content = new HashMap<String, Object>();
content.put("content", getContentJsonString());
items.put(messageType.getValue(),content);
return JSON.toJSONString(items);
}
/**
* 获取内容节点字符串
* @return
*/
abstract String getContentJsonString();
}
package cn.com.app.base.enums;
import cn.com.app.base.constant.emums.IEnum;
import cn.com.app.base.constant.utils.EnumUtil;
public enum MessageTypeEnum implements IEnum {
TEXT("text","文本"),
IMAGE("image","图片"),
MARKDOWN("markdown","MD文本"),
NEWS("news","图文"),
FILE("file","文件"),
TEMPLATE_CARD("template_card","模板卡片")
;
private String value;
private String desc;
MessageTypeEnum(String value, String desc) {
this.value = value;
this.desc = desc;
}
public String getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public void setValue(String value, String desc) {
this.value = value;
this.desc = desc;
}
public String toString() {
return "[" + this.value + "]" + this.desc;
}
public IEnum format(String... args) {
return EnumUtil.newIEnum(this.value, new String[]{EnumUtil.ErrorDescFormat(this.desc, args)});
}
}
package cn.com.app.base.dto;
import cn.com.app.base.enums.MessageTypeEnum;
import java.util.ArrayList;
import java.util.List;
public class MarkdownMessageDto extends MessageDto {
public MarkdownMessageDto(){
super();
this.setMessageType(MessageTypeEnum.MARKDOWN);
}
@Override
String getContentJsonString() {
StringBuffer markdownText = new StringBuffer();
for (String item : items) {
markdownText.append(item + "\n");
}
return markdownText.toString();
}
/**
* 所有markdown文本列表
*/
private List<String> items = new ArrayList<String>();
/**
* 增加 markdown 文本
* @param text
*/
public void add(String text) {
items.add(text);
}
/**
* at用户名
*/
public static String getAtUser(String text){
return "<@" + text + ">";
}
/**
* 加粗字体
*/
public static String getBoldText(String text) {
return "**" + text + "**";
}
/**
* 斜体字体
*/
public static String getItalicText(String text) {
return "*" + text + "*";
}
/**
* 超链接字体
* @param text 文本
* @param href 超链接
*/
public static String getLinkText(String text, String href) {
return "[" + text + "](" + href + ")";
}
/**
* 图片 无效其实是超链接点开查看的
* @param imageUrl
*/
public static String getImageText(String imageUrl) {
return " ";
}
/**
* 标题字体
* @param headerType 1-6号标题
* @param text 标题文本
*/
public static String getHeaderText(int headerType, String text) {
if (headerType < 1 || headerType > 6) {
throw new IllegalArgumentException("headerType should be in [1, 6]");
}
StringBuffer numbers = new StringBuffer();
for (int i = 0; i < headerType; i++) {
numbers.append("#");
}
return numbers + " " + text;
}
/**
* 文本增加引用
* @param text
*/
public static String getReferenceText(String text) {
return "> " + text;
}
/**
* 文本列表 显示前加上序号1、2、3
* 如下:
* 1. order item1
* 2. order item2
* @param orderItem
*/
public static String getOrderListText(List<String> orderItem) {
if (orderItem.isEmpty()) {
return "";
}
StringBuffer sb = new StringBuffer();
for (int i = 1; i <= orderItem.size() - 1; i++) {
sb.append(String.valueOf(i) + ". " + orderItem.get(i - 1) + "\n");
}
sb.append(String.valueOf(orderItem.size()) + ". " + orderItem.get(orderItem.size() - 1));
return sb.toString();
}
/**
* 文本列表 显示前加上 中划线
* 如下:
* - unorder item1
* - unorder item2
* @param unorderItem
*/
public static String getUnorderListText(List<String> unorderItem) {
if (unorderItem.isEmpty()) {
return "";
}
StringBuffer sb = new StringBuffer();
for (int i = 0; i < unorderItem.size() - 1; i++) {
sb.append("- " + unorderItem.get(i) + "\n");
}
sb.append("- " + unorderItem.get(unorderItem.size() - 1));
return sb.toString();
}
}