refactor(消息通知): 优化消息通知配置
This commit is contained in:
parent
f0080cb146
commit
c230af63bd
|
@ -34,6 +34,8 @@ public interface NoticeConstants {
|
|||
String WECHAT_ROBOT = "WECHAT_ROBOT";
|
||||
String LARK = "LARK";
|
||||
String IN_SITE = "IN_SITE";
|
||||
|
||||
String WEBHOOK = "WEBHOOK";
|
||||
}
|
||||
|
||||
interface Event {
|
||||
|
|
|
@ -7,7 +7,6 @@ import io.metersphere.notice.domain.UserDetail;
|
|||
import io.metersphere.notice.sender.AbstractNoticeSender;
|
||||
import io.metersphere.notice.sender.NoticeModel;
|
||||
import io.metersphere.notice.util.LarkClient;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
package io.metersphere.notice.sender.impl;
|
||||
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.notice.domain.MessageDetail;
|
||||
import io.metersphere.notice.domain.Receiver;
|
||||
import io.metersphere.notice.sender.AbstractNoticeSender;
|
||||
import io.metersphere.notice.sender.NoticeModel;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class WebhookNoticeSender extends AbstractNoticeSender {
|
||||
|
||||
|
||||
private void send(MessageDetail messageDetail, NoticeModel noticeModel, String context) {
|
||||
List<Receiver> receivers = noticeModel.getReceivers();
|
||||
CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||
CloseableHttpResponse response = null;
|
||||
if (CollectionUtils.isNotEmpty(receivers)) {
|
||||
List<String> userIds = receivers.stream()
|
||||
.map(Receiver::getUserId)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
LogUtil.info("Webhook收件人: {}", userIds);
|
||||
}
|
||||
|
||||
try {
|
||||
HttpPost httpPost = new HttpPost(messageDetail.getWebhook());
|
||||
// 创建请求内容
|
||||
StringEntity entity = new StringEntity(context, ContentType.APPLICATION_JSON);
|
||||
httpPost.setEntity(entity);
|
||||
// 执行http请求
|
||||
response = httpClient.execute(httpPost);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
} finally {
|
||||
try {
|
||||
if (response != null) {
|
||||
response.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(MessageDetail messageDetail, NoticeModel noticeModel) {
|
||||
String context = super.getContext(messageDetail, noticeModel);
|
||||
send(messageDetail, noticeModel, context);
|
||||
}
|
||||
}
|
|
@ -30,6 +30,8 @@ public class NoticeSendService {
|
|||
private NoticeService noticeService;
|
||||
@Resource
|
||||
private InSiteNoticeSender inSiteNoticeSender;
|
||||
@Resource
|
||||
private WebhookNoticeSender webhookNoticeSender;
|
||||
|
||||
|
||||
private AbstractNoticeSender getNoticeSender(MessageDetail messageDetail) {
|
||||
|
@ -50,6 +52,9 @@ public class NoticeSendService {
|
|||
case NoticeConstants.Type.IN_SITE:
|
||||
noticeSender = inSiteNoticeSender;
|
||||
break;
|
||||
case NoticeConstants.Type.WEBHOOK:
|
||||
noticeSender = webhookNoticeSender;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -68,7 +68,10 @@ export default {
|
|||
],
|
||||
receiveTypeOptions: [
|
||||
{value: 'EMAIL', label: this.$t('organization.message.mail')},
|
||||
{value: 'WEBHOOK', label: 'Webhook'},
|
||||
{value: 'NAIL_ROBOT', label: this.$t('organization.message.nail_robot')},
|
||||
{value: 'WECHAT_ROBOT', label: this.$t('organization.message.enterprise_wechat_robot')},
|
||||
{value: 'LARK', label: this.$t('organization.message.lark')},
|
||||
{value: 'WEBHOOK', label: this.$t('organization.message.webhook')},
|
||||
],
|
||||
variables: [
|
||||
{
|
||||
|
|
|
@ -69,7 +69,10 @@ export default {
|
|||
],
|
||||
receiveTypeOptions: [
|
||||
{value: 'EMAIL', label: this.$t('organization.message.mail')},
|
||||
{value: 'WEBHOOK', label: 'Webhook'},
|
||||
{value: 'NAIL_ROBOT', label: this.$t('organization.message.nail_robot')},
|
||||
{value: 'WECHAT_ROBOT', label: this.$t('organization.message.enterprise_wechat_robot')},
|
||||
{value: 'LARK', label: this.$t('organization.message.lark')},
|
||||
{value: 'WEBHOOK', label: this.$t('organization.message.webhook')},
|
||||
],
|
||||
};
|
||||
},
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
style="width: 100%;"
|
||||
:disabled="!scope.row.isSet" @change="handleEdit(scope.$index, scope.row)">
|
||||
<el-option
|
||||
v-for="item in receiveTypeOptions"
|
||||
v-for="item in (hasLicense() ? receiveTypeOptions: receiveTypeOptions.filter(v => v.value !=='WEBHOOK'))"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
|
@ -53,21 +53,19 @@
|
|||
<template v-slot:header>
|
||||
Webhook
|
||||
<el-tooltip effect="dark" placement="top-start"
|
||||
style="padding-left: 10px;"
|
||||
content="支持企业微信、钉钉、飞书以及自定义Webhook(X-Pack)">
|
||||
style="padding-left: 10px;">
|
||||
<template v-slot:content>
|
||||
支持企业微信、钉钉、飞书以及自定义Webhook(X-Pack)
|
||||
<div>
|
||||
自定义 Webhook 需要配置自定义模版才能发送成功,请自行查询对应的消息模版
|
||||
</div>
|
||||
</template>
|
||||
<i class="el-icon-info pointer"/>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template v-slot:default="scope">
|
||||
<el-input v-model="scope.row.webhook" size="mini"
|
||||
:disabled="!scope.row.isSet||!scope.row.isReadOnly"></el-input>
|
||||
<div v-if="scope.row.type === 'WEBHOOK'" style="font-size: 10px; color: gray; font-style:italic;">
|
||||
<span v-if="scope.row.webhook.indexOf('qyapi.weixin') > -1">企业微信 Webhook</span>
|
||||
<span v-else-if="scope.row.webhook.indexOf('oapi.dingtalk') > -1">钉钉 Webhook</span>
|
||||
<span v-else-if="scope.row.webhook.indexOf('open.feishu.cn') > -1">飞书 Webhook</span>
|
||||
<span v-else-if="scope.row.webhook.startsWith('http') && hasLicense()">自定义 Webhook</span>
|
||||
<span v-else-if="scope.row.webhook">识别失败,如需支持自定义Webhook,请使用X-Pack(企业版)</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.operating')" width="150" prop="result">
|
||||
|
@ -122,6 +120,7 @@
|
|||
|
||||
<script>
|
||||
import MsTipButton from "@/business/components/common/components/MsTipButton";
|
||||
import {hasLicense} from "@/common/js/utils";
|
||||
|
||||
export default {
|
||||
name: "NotificationTable",
|
||||
|
@ -141,6 +140,7 @@ export default {
|
|||
return {}
|
||||
},
|
||||
methods: {
|
||||
hasLicense,
|
||||
rowClass() {
|
||||
return "text-align:center";
|
||||
},
|
||||
|
|
|
@ -68,7 +68,10 @@ export default {
|
|||
],
|
||||
receiveTypeOptions: [
|
||||
{value: 'EMAIL', label: this.$t('organization.message.mail')},
|
||||
{value: 'WEBHOOK', label: 'Webhook'},
|
||||
{value: 'NAIL_ROBOT', label: this.$t('organization.message.nail_robot')},
|
||||
{value: 'WECHAT_ROBOT', label: this.$t('organization.message.enterprise_wechat_robot')},
|
||||
{value: 'LARK', label: this.$t('organization.message.lark')},
|
||||
{value: 'WEBHOOK', label: this.$t('organization.message.webhook')},
|
||||
],
|
||||
};
|
||||
},
|
||||
|
|
|
@ -137,7 +137,10 @@ export default {
|
|||
receiveTypeOptions: [
|
||||
{value: 'IN_SITE', label: this.$t('organization.message.in_site')},
|
||||
{value: 'EMAIL', label: this.$t('organization.message.mail')},
|
||||
{value: 'WEBHOOK', label: 'Webhook'},
|
||||
{value: 'NAIL_ROBOT', label: this.$t('organization.message.nail_robot')},
|
||||
{value: 'WECHAT_ROBOT', label: this.$t('organization.message.enterprise_wechat_robot')},
|
||||
{value: 'LARK', label: this.$t('organization.message.lark')},
|
||||
{value: 'WEBHOOK', label: this.$t('organization.message.webhook')},
|
||||
],
|
||||
result: {}
|
||||
};
|
||||
|
|
|
@ -69,7 +69,10 @@ export default {
|
|||
],
|
||||
receiveTypeOptions: [
|
||||
{value: 'EMAIL', label: this.$t('organization.message.mail')},
|
||||
{value: 'WEBHOOK', label: 'Webhook'},
|
||||
{value: 'NAIL_ROBOT', label: this.$t('organization.message.nail_robot')},
|
||||
{value: 'WECHAT_ROBOT', label: this.$t('organization.message.enterprise_wechat_robot')},
|
||||
{value: 'LARK', label: this.$t('organization.message.lark')},
|
||||
{value: 'WEBHOOK', label: this.$t('organization.message.webhook')},
|
||||
],
|
||||
variables: [
|
||||
{
|
||||
|
|
|
@ -645,6 +645,7 @@ export default {
|
|||
nail_robot: 'Nail robot',
|
||||
enterprise_wechat_robot: 'WeCom robot',
|
||||
lark: "Lark Robot",
|
||||
webhook: 'Webhook',
|
||||
notes: '1. In order to use WeChat Enterprise, Dingding and Feishu notifications, you need to create a custom robot and copy the webhook address;<br/>' +
|
||||
'2. For robots that need security verification, you can choose "custom keyword" verification, and the keyword is "Message Notification";<br/>' +
|
||||
'3. To use the @ feature, the selected recipient must be a user included in the group, the recipient’s phone number is required and should be the phone number used by Dingding.',
|
||||
|
|
|
@ -648,6 +648,7 @@ export default {
|
|||
nail_robot: '钉钉机器人',
|
||||
enterprise_wechat_robot: '企业微信机器人',
|
||||
lark: '飞书机器人',
|
||||
webhook: '自定义 Webhook',
|
||||
notes: '1.企业微信、钉钉及飞书通知需要新建一个自定义机器人,然后复制 webhook 地址在我们平台上;<br/>' +
|
||||
'2.需要安全验证的机器人可以选择 “自定义关键词” 验证,关键词为 “消息通知”;<br/>' +
|
||||
'3.如需在通知中使用@功能,选择的接收人必须是机器人所在群里包含的用户,接收人手机号为必填项且为钉钉企业所使用的手机号',
|
||||
|
|
|
@ -648,6 +648,7 @@ export default {
|
|||
nail_robot: '釘釘機器人',
|
||||
enterprise_wechat_robot: '企業微信機器人',
|
||||
lark: '飛書機器人',
|
||||
webhook: '自定義 Webhook',
|
||||
notes: '1.企業微信、釘釘及飛書通知需要新建一個自定義機器人,然後復制 webhook 地址在我們平台上;<br/>' +
|
||||
'2.需要安全驗證的機器人可以選擇 “自定義關鍵詞” 驗證,關鍵詞為 “消息通知”;<br/>' +
|
||||
'3.如需在通知中使用@功能,選擇的接收人必須是機器人所在群裡包含的用戶,接收人手機號為必填項且為釘釘企業所使用的手機號',
|
||||
|
|
Loading…
Reference in New Issue