feat:2.6.0 企业微信通知
This commit is contained in:
parent
c163986a82
commit
1b5b131a0c
@ -0,0 +1,19 @@
|
|||||||
|
package com.aizuda.easy.retry.common.core.alarm;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 企业微信
|
||||||
|
*
|
||||||
|
* @author lizhongyuan
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class QiYeWechatAttribute {
|
||||||
|
|
||||||
|
private String webhookUrl;
|
||||||
|
|
||||||
|
private List<String> ats;
|
||||||
|
|
||||||
|
}
|
@ -36,7 +36,7 @@ import java.util.Map;
|
|||||||
public class LarkAlarm extends AbstractAlarm<AlarmContext> {
|
public class LarkAlarm extends AbstractAlarm<AlarmContext> {
|
||||||
|
|
||||||
|
|
||||||
public static final String atLabel = "<at id={0}></at>";
|
public static final String AT_LABEL = "<at id={0}></at>";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Integer getAlarmType() {
|
public Integer getAlarmType() {
|
||||||
@ -45,9 +45,7 @@ public class LarkAlarm extends AbstractAlarm<AlarmContext> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean asyncSendMessage(AlarmContext context) {
|
public boolean asyncSendMessage(AlarmContext context) {
|
||||||
threadPoolExecutor.execute(() -> {
|
threadPoolExecutor.execute(() -> syncSendMessage(context));
|
||||||
syncSendMessage(context);
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -69,12 +67,15 @@ public class LarkAlarm extends AbstractAlarm<AlarmContext> {
|
|||||||
HttpRequest request = post.body(JsonUtil.toJsonString(builder), ContentType.JSON.toString());
|
HttpRequest request = post.body(JsonUtil.toJsonString(builder), ContentType.JSON.toString());
|
||||||
HttpResponse execute = request.execute();
|
HttpResponse execute = request.execute();
|
||||||
LogUtils.debug(log, JsonUtil.toJsonString(execute));
|
LogUtils.debug(log, JsonUtil.toJsonString(execute));
|
||||||
|
if (execute.isOk()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
LogUtils.error(log, "发送lark消息失败:{}", execute.body());
|
||||||
|
return false;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("发送lark消息失败", e);
|
log.error("发送lark消息失败", e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List buildElements(String text, List<String> ats) {
|
private List buildElements(String text, List<String> ats) {
|
||||||
@ -123,10 +124,10 @@ public class LarkAlarm extends AbstractAlarm<AlarmContext> {
|
|||||||
|
|
||||||
StringBuilder sb = new StringBuilder(text);
|
StringBuilder sb = new StringBuilder(text);
|
||||||
if (ats.stream().map(String::toLowerCase).anyMatch(SystemConstants.AT_ALL::equals)) {
|
if (ats.stream().map(String::toLowerCase).anyMatch(SystemConstants.AT_ALL::equals)) {
|
||||||
sb.append(MessageFormat.format(atLabel, SystemConstants.AT_ALL));
|
sb.append(MessageFormat.format(AT_LABEL, SystemConstants.AT_ALL));
|
||||||
} else {
|
} else {
|
||||||
ats.stream().filter(StrUtil::isNotBlank)
|
ats.stream().filter(StrUtil::isNotBlank)
|
||||||
.forEach(at -> sb.append(MessageFormat.format(atLabel, at)));
|
.forEach(at -> sb.append(MessageFormat.format(AT_LABEL, at)));
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,91 @@
|
|||||||
|
package com.aizuda.easy.retry.common.core.alarm.strategy;
|
||||||
|
|
||||||
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.http.*;
|
||||||
|
import com.aizuda.easy.retry.common.core.alarm.AlarmContext;
|
||||||
|
import com.aizuda.easy.retry.common.core.alarm.QiYeWechatAttribute;
|
||||||
|
import com.aizuda.easy.retry.common.core.enums.AlarmTypeEnum;
|
||||||
|
import com.aizuda.easy.retry.common.core.log.LogUtils;
|
||||||
|
import com.aizuda.easy.retry.common.core.util.DingDingUtils;
|
||||||
|
import com.aizuda.easy.retry.common.core.util.JsonUtil;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 企业微信通知
|
||||||
|
*
|
||||||
|
* @author lizhongyuan
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class QiYeWechatAlarm extends AbstractAlarm<AlarmContext> {
|
||||||
|
|
||||||
|
public static final String AT_LABEL = "<@{0}>";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getAlarmType() {
|
||||||
|
return AlarmTypeEnum.QI_YE_WECHAT.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean asyncSendMessage(AlarmContext context) {
|
||||||
|
threadPoolExecutor.execute(() -> syncSendMessage(context));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean syncSendMessage(AlarmContext context) {
|
||||||
|
try {
|
||||||
|
QiYeWechatAttribute qiYeWechatAttribute = JsonUtil.parseObject(context.getNotifyAttribute(), QiYeWechatAttribute.class);
|
||||||
|
String webhookUrl = qiYeWechatAttribute.getWebhookUrl();
|
||||||
|
if (StrUtil.isBlank(webhookUrl)) {
|
||||||
|
log.error("请先配置微信机器人 webhookUrl");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Map<String, Object> map = MapUtil.newHashMap();
|
||||||
|
QiYeWechatMessageContent messageContent = new QiYeWechatMessageContent();
|
||||||
|
messageContent.setContent(StrUtil.sub(DingDingUtils.getAtText(qiYeWechatAttribute.getAts(), context.getText(), AT_LABEL), 0, 4096));
|
||||||
|
map.put("msgtype", "markdown");
|
||||||
|
map.put("markdown", messageContent);
|
||||||
|
HttpRequest post = HttpUtil.createPost(webhookUrl);
|
||||||
|
HttpRequest request = post.body(JsonUtil.toJsonString(map), ContentType.JSON.toString());
|
||||||
|
HttpResponse execute = request.execute();
|
||||||
|
LogUtils.debug(log, JsonUtil.toJsonString(execute));
|
||||||
|
if (execute.isOk()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
LogUtils.error(log, "发送企业微信消息失败:{}", execute.body());
|
||||||
|
return false;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("发送企业微信消息失败", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean asyncSendMessage(List<AlarmContext> alarmContexts) {
|
||||||
|
|
||||||
|
for (AlarmContext alarmContext : alarmContexts) {
|
||||||
|
asyncSendMessage(alarmContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Boolean.TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Data
|
||||||
|
private static class QiYeWechatMessageContent {
|
||||||
|
/**
|
||||||
|
* markdown内容,最长不超过4096个字节,必须是utf8编码
|
||||||
|
*/
|
||||||
|
private String content;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -8,13 +8,9 @@ import com.dingtalk.api.DingTalkClient;
|
|||||||
import com.dingtalk.api.request.OapiRobotSendRequest;
|
import com.dingtalk.api.request.OapiRobotSendRequest;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author: www.byteblogs.com
|
* @author: www.byteblogs.com
|
||||||
@ -25,22 +21,6 @@ public class DingDingUtils {
|
|||||||
|
|
||||||
public static final String atLabel = "@{0}";
|
public static final String atLabel = "@{0}";
|
||||||
|
|
||||||
/**
|
|
||||||
* 防止文本过长钉钉限流,目前最大为4000
|
|
||||||
*
|
|
||||||
* @param text
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static String subTextLength(String text) {
|
|
||||||
int length = text.length();
|
|
||||||
|
|
||||||
if (length > 4000) {
|
|
||||||
return text.substring(0, 4000);
|
|
||||||
} else {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 组装OapiRobotSendRequest
|
* 组装OapiRobotSendRequest
|
||||||
*
|
*
|
||||||
@ -53,7 +33,8 @@ public class DingDingUtils {
|
|||||||
request.setMsgtype("markdown");
|
request.setMsgtype("markdown");
|
||||||
OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown();
|
OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown();
|
||||||
markdown.setTitle(title);
|
markdown.setTitle(title);
|
||||||
markdown.setText(subTextLength(getAtText(ats, text)));
|
// 防止文本过长钉钉限流,目前最大为4000
|
||||||
|
markdown.setText(StrUtil.sub(getAtText(ats, text, atLabel), 0, 4000));
|
||||||
request.setMarkdown(markdown);
|
request.setMarkdown(markdown);
|
||||||
|
|
||||||
OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
|
OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
|
||||||
@ -65,7 +46,7 @@ public class DingDingUtils {
|
|||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getAtText(List<String> ats, String text) {
|
public static String getAtText(List<String> ats, String text, String atLabel) {
|
||||||
if (CollectionUtils.isEmpty(ats)) {
|
if (CollectionUtils.isEmpty(ats)) {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
@ -171,6 +171,10 @@ const enums = {
|
|||||||
'name': '邮箱通知',
|
'name': '邮箱通知',
|
||||||
'color': '#1b7ee5'
|
'color': '#1b7ee5'
|
||||||
},
|
},
|
||||||
|
'3': {
|
||||||
|
'name': '企业微信',
|
||||||
|
'color': '#0082EF'
|
||||||
|
},
|
||||||
'4': {
|
'4': {
|
||||||
'name': '飞书',
|
'name': '飞书',
|
||||||
'color': '#087da1'
|
'color': '#087da1'
|
||||||
|
@ -90,6 +90,10 @@ const enums = {
|
|||||||
'name': '邮箱通知',
|
'name': '邮箱通知',
|
||||||
'color': '#1b7ee5'
|
'color': '#1b7ee5'
|
||||||
},
|
},
|
||||||
|
'3': {
|
||||||
|
'name': '企业微信',
|
||||||
|
'color': '#0082EF'
|
||||||
|
},
|
||||||
'4': {
|
'4': {
|
||||||
'name': '飞书',
|
'name': '飞书',
|
||||||
'color': '#087da1'
|
'color': '#087da1'
|
||||||
|
@ -164,7 +164,8 @@
|
|||||||
{rules: [{ required: true, message: '请输入钉钉URL', whitespace: true}]}
|
{rules: [{ required: true, message: '请输入钉钉URL', whitespace: true}]}
|
||||||
]" />
|
]" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item v-if="this.tempNotifyTypeValue === '1'">
|
<a-form-item
|
||||||
|
v-if="this.tempNotifyTypeValue === '1'">
|
||||||
<span slot="label">被@人手机号或钉钉号 </span>
|
<span slot="label">被@人手机号或钉钉号 </span>
|
||||||
<a-input
|
<a-input
|
||||||
placeholder="请输入被@人手机号或钉钉号"
|
placeholder="请输入被@人手机号或钉钉号"
|
||||||
@ -175,6 +176,28 @@
|
|||||||
{rules: [{ required: false, message: '请输入被@人手机号或钉钉号', whitespace: true}]}
|
{rules: [{ required: false, message: '请输入被@人手机号或钉钉号', whitespace: true}]}
|
||||||
]" />
|
]" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
v-if="this.tempNotifyTypeValue === '3'"
|
||||||
|
label="企业微信URL">
|
||||||
|
<a-input
|
||||||
|
placeholder="请输入企业微信URL"
|
||||||
|
v-decorator="[
|
||||||
|
'webhookUrl',
|
||||||
|
{rules: [{ required: true, message: '请输入企业微信URL', whitespace: true}]}
|
||||||
|
]" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
v-if="this.tempNotifyTypeValue === '3'">
|
||||||
|
<span slot="label">被@人企业微信用户id </span>
|
||||||
|
<a-input
|
||||||
|
placeholder="请输入被@人企业微信用户id"
|
||||||
|
type="textarea"
|
||||||
|
v-if="this.tempNotifyTypeValue === '3'"
|
||||||
|
v-decorator="[
|
||||||
|
'ats',
|
||||||
|
{rules: [{ required: false, message: '请输入被@人企业微信用户id', whitespace: true}]}
|
||||||
|
]" />
|
||||||
|
</a-form-item>
|
||||||
<a-form-item
|
<a-form-item
|
||||||
v-if="this.tempNotifyTypeValue === '4'"
|
v-if="this.tempNotifyTypeValue === '4'"
|
||||||
label="飞书URL">
|
label="飞书URL">
|
||||||
@ -493,6 +516,10 @@ export default {
|
|||||||
s =
|
s =
|
||||||
'钉钉Url:' + json['webhookUrl'] + ';' +
|
'钉钉Url:' + json['webhookUrl'] + ';' +
|
||||||
'被@人手机号:' + json['ats'] + ';'
|
'被@人手机号:' + json['ats'] + ';'
|
||||||
|
} else if (this.notifyTypeValue === '3') {
|
||||||
|
s =
|
||||||
|
'企业微信Url:' + json['webhookUrl'] + ';' +
|
||||||
|
'被@人企业微信用户id:' + json['ats'] + ';'
|
||||||
} else if (this.notifyTypeValue === '4') {
|
} else if (this.notifyTypeValue === '4') {
|
||||||
s =
|
s =
|
||||||
'飞书Url:' + json['webhookUrl'] + ';' +
|
'飞书Url:' + json['webhookUrl'] + ';' +
|
||||||
|
@ -165,7 +165,8 @@
|
|||||||
{rules: [{ required: true, message: '请输入钉钉URL', whitespace: true}]}
|
{rules: [{ required: true, message: '请输入钉钉URL', whitespace: true}]}
|
||||||
]" />
|
]" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item v-if="this.tempNotifyTypeValue === '1'">
|
<a-form-item
|
||||||
|
v-if="this.tempNotifyTypeValue === '1'">
|
||||||
<span slot="label">被@人手机号或钉钉号 </span>
|
<span slot="label">被@人手机号或钉钉号 </span>
|
||||||
<a-input
|
<a-input
|
||||||
placeholder="请输入被@人手机号或钉钉号"
|
placeholder="请输入被@人手机号或钉钉号"
|
||||||
@ -176,6 +177,28 @@
|
|||||||
{rules: [{ required: false, message: '请输入被@人手机号或钉钉号', whitespace: true}]}
|
{rules: [{ required: false, message: '请输入被@人手机号或钉钉号', whitespace: true}]}
|
||||||
]" />
|
]" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
v-if="this.tempNotifyTypeValue === '3'"
|
||||||
|
label="企业微信URL">
|
||||||
|
<a-input
|
||||||
|
placeholder="请输入企业微信URL"
|
||||||
|
v-decorator="[
|
||||||
|
'webhookUrl',
|
||||||
|
{rules: [{ required: true, message: '请输入企业微信URL', whitespace: true}]}
|
||||||
|
]" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
v-if="this.tempNotifyTypeValue === '3'">
|
||||||
|
<span slot="label">被@人企业微信用户id </span>
|
||||||
|
<a-input
|
||||||
|
placeholder="请输入被@人企业微信用户id"
|
||||||
|
type="textarea"
|
||||||
|
v-if="this.tempNotifyTypeValue === '3'"
|
||||||
|
v-decorator="[
|
||||||
|
'ats',
|
||||||
|
{rules: [{ required: false, message: '请输入被@人企业微信用户id', whitespace: true}]}
|
||||||
|
]" />
|
||||||
|
</a-form-item>
|
||||||
<a-form-item
|
<a-form-item
|
||||||
v-if="this.tempNotifyTypeValue === '4'"
|
v-if="this.tempNotifyTypeValue === '4'"
|
||||||
label="飞书URL">
|
label="飞书URL">
|
||||||
@ -493,6 +516,10 @@ export default {
|
|||||||
s =
|
s =
|
||||||
'钉钉Url:' + json['webhookUrl'] + ';' +
|
'钉钉Url:' + json['webhookUrl'] + ';' +
|
||||||
'被@人手机号或钉钉号:' + json['ats'] + ';'
|
'被@人手机号或钉钉号:' + json['ats'] + ';'
|
||||||
|
} else if (this.notifyTypeValue === '3') {
|
||||||
|
s =
|
||||||
|
'企业微信Url:' + json['webhookUrl'] + ';' +
|
||||||
|
'被@人企业微信用户id:' + json['ats'] + ';'
|
||||||
} else if (this.notifyTypeValue === '4') {
|
} else if (this.notifyTypeValue === '4') {
|
||||||
s =
|
s =
|
||||||
'飞书Url:' + json['webhookUrl'] + ';' +
|
'飞书Url:' + json['webhookUrl'] + ';' +
|
||||||
|
Loading…
Reference in New Issue
Block a user