mirror of
https://github.com/certd/certd.git
synced 2026-07-14 17:53:28 +08:00
chore: format
This commit is contained in:
@@ -1,52 +1,52 @@
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from '@certd/pipeline';
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from "@certd/pipeline";
|
||||
|
||||
@IsNotification({
|
||||
name: 'anpush',
|
||||
title: 'AnPush',
|
||||
desc: 'https://anpush.com',
|
||||
name: "anpush",
|
||||
title: "AnPush",
|
||||
desc: "https://anpush.com",
|
||||
needPlus: true,
|
||||
})
|
||||
export class AnPushNotification extends BaseNotification {
|
||||
@NotificationInput({
|
||||
title: 'API密钥',
|
||||
title: "API密钥",
|
||||
component: {
|
||||
placeholder: '',
|
||||
placeholder: "",
|
||||
},
|
||||
helper: '[获取API密钥](https://anpush.com/push/tool) ',
|
||||
helper: "[获取API密钥](https://anpush.com/push/tool) ",
|
||||
required: true,
|
||||
})
|
||||
token = '';
|
||||
token = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '通道ID',
|
||||
title: "通道ID",
|
||||
component: {
|
||||
placeholder: '',
|
||||
placeholder: "",
|
||||
},
|
||||
helper: '[获取通道ID](https://anpush.com/push/setting)创建通道,复制通道id,填入此处',
|
||||
helper: "[获取通道ID](https://anpush.com/push/setting)创建通道,复制通道id,填入此处",
|
||||
required: true,
|
||||
})
|
||||
channel = '';
|
||||
channel = "";
|
||||
|
||||
async send(body: NotificationBody) {
|
||||
if (!this.token) {
|
||||
throw new Error('token不能为空');
|
||||
throw new Error("token不能为空");
|
||||
}
|
||||
const config = {
|
||||
url: `https://api.anpush.com/push/${this.token}`,
|
||||
method: 'POST',
|
||||
method: "POST",
|
||||
timeout: 0,
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
data: {
|
||||
title: body.title,
|
||||
content: body.content + '\n\n[查看详情](' + body.url + ')',
|
||||
content: body.content + "\n\n[查看详情](" + body.url + ")",
|
||||
channel: this.channel,
|
||||
},
|
||||
};
|
||||
const res = await this.http.request(config);
|
||||
if (res.code != 200) {
|
||||
throw new Error('发送失败:' + res.msg);
|
||||
throw new Error("发送失败:" + res.msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,31 +13,31 @@
|
||||
* }'
|
||||
*/
|
||||
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from '@certd/pipeline';
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from "@certd/pipeline";
|
||||
|
||||
@IsNotification({
|
||||
name: 'bark',
|
||||
title: 'Bark 通知',
|
||||
desc: 'Bark 推送通知插件',
|
||||
name: "bark",
|
||||
title: "Bark 通知",
|
||||
desc: "Bark 推送通知插件",
|
||||
needPlus: true,
|
||||
})
|
||||
export class BarkNotification extends BaseNotification {
|
||||
@NotificationInput({
|
||||
title: '服务地址',
|
||||
title: "服务地址",
|
||||
component: {
|
||||
placeholder: 'https://api.day.app/your_key',
|
||||
placeholder: "https://api.day.app/your_key",
|
||||
},
|
||||
required: true,
|
||||
helper: '你的bark服务地址+key',
|
||||
helper: "你的bark服务地址+key",
|
||||
})
|
||||
webhook = '';
|
||||
webhook = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '忽略证书校验',
|
||||
title: "忽略证书校验",
|
||||
value: false,
|
||||
component: {
|
||||
name: 'a-switch',
|
||||
vModel: 'checked',
|
||||
name: "a-switch",
|
||||
vModel: "checked",
|
||||
},
|
||||
required: false,
|
||||
})
|
||||
@@ -45,7 +45,7 @@ export class BarkNotification extends BaseNotification {
|
||||
|
||||
async send(body: NotificationBody) {
|
||||
if (!this.webhook) {
|
||||
throw new Error('服务器地址不能为空');
|
||||
throw new Error("服务器地址不能为空");
|
||||
}
|
||||
|
||||
const payload = {
|
||||
@@ -55,9 +55,9 @@ export class BarkNotification extends BaseNotification {
|
||||
|
||||
await this.http.request({
|
||||
url: `${this.webhook}`,
|
||||
method: 'POST',
|
||||
method: "POST",
|
||||
headers: {
|
||||
'Content-Type': 'application/json; charset=utf-8',
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
},
|
||||
data: payload,
|
||||
skipSslVerify: this.skipSslVerify,
|
||||
|
||||
@@ -1,79 +1,76 @@
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from "@certd/pipeline";
|
||||
|
||||
@IsNotification({
|
||||
name: 'dingtalk',
|
||||
title: '钉钉通知',
|
||||
desc: '钉钉群聊通知',
|
||||
name: "dingtalk",
|
||||
title: "钉钉通知",
|
||||
desc: "钉钉群聊通知",
|
||||
needPlus: true,
|
||||
})
|
||||
// https://open.dingtalk.com/document/orgapp/the-creation-and-installation-of-the-application-robot-in-the?spm=ding_open_doc.document.0.0.242d1563cDgZz3
|
||||
export class DingTalkNotification extends BaseNotification {
|
||||
@NotificationInput({
|
||||
title: 'webhook地址',
|
||||
title: "webhook地址",
|
||||
component: {
|
||||
placeholder: 'https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxxxxxx',
|
||||
placeholder: "https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxxxxxx",
|
||||
},
|
||||
helper: '钉钉APP->群聊->设置->机器人->添加机器人->自定义->[创建机器人->复制webhook地址](https://open.dingtalk.com/document/robots/custom-robot-access)',
|
||||
helper: "钉钉APP->群聊->设置->机器人->添加机器人->自定义->[创建机器人->复制webhook地址](https://open.dingtalk.com/document/robots/custom-robot-access)",
|
||||
required: true,
|
||||
})
|
||||
webhook = '';
|
||||
webhook = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '加签密钥',
|
||||
title: "加签密钥",
|
||||
component: {
|
||||
placeholder: 'SECxxxxxxxxxxxxxxxxxxxxx',
|
||||
placeholder: "SECxxxxxxxxxxxxxxxxxxxxx",
|
||||
},
|
||||
helper: '必须选择一种安全设置,请选择加密密钥',
|
||||
helper: "必须选择一种安全设置,请选择加密密钥",
|
||||
required: false,
|
||||
})
|
||||
secret = '';
|
||||
|
||||
secret = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '@用户ID',
|
||||
title: "@用户ID",
|
||||
component: {
|
||||
placeholder: '非必填,填写完一个按回车',
|
||||
name: 'a-select',
|
||||
vModel: 'value',
|
||||
mode: 'tags',
|
||||
placeholder: "非必填,填写完一个按回车",
|
||||
name: "a-select",
|
||||
vModel: "value",
|
||||
mode: "tags",
|
||||
multiple: true,
|
||||
open: false,
|
||||
},
|
||||
helper: '填写要@的用户ID',
|
||||
helper: "填写要@的用户ID",
|
||||
required: false,
|
||||
})
|
||||
atUserIds:string[];
|
||||
atUserIds: string[];
|
||||
|
||||
@NotificationInput({
|
||||
title: '@用户手机号',
|
||||
title: "@用户手机号",
|
||||
component: {
|
||||
placeholder: '非必填,填写一个按回车',
|
||||
name: 'a-select',
|
||||
vModel: 'value',
|
||||
mode: 'tags',
|
||||
placeholder: "非必填,填写一个按回车",
|
||||
name: "a-select",
|
||||
vModel: "value",
|
||||
mode: "tags",
|
||||
multiple: true,
|
||||
open: false,
|
||||
},
|
||||
helper: '填写要@的用户的手机号',
|
||||
helper: "填写要@的用户的手机号",
|
||||
required: false,
|
||||
})
|
||||
atMobiles:string[];
|
||||
|
||||
atMobiles: string[];
|
||||
|
||||
@NotificationInput({
|
||||
title: '@all',
|
||||
title: "@all",
|
||||
component: {
|
||||
placeholder: '非必填',
|
||||
name: 'a-switch',
|
||||
vModel:"checked"
|
||||
placeholder: "非必填",
|
||||
name: "a-switch",
|
||||
vModel: "checked",
|
||||
},
|
||||
helper: '是否@所有人',
|
||||
helper: "是否@所有人",
|
||||
required: false,
|
||||
})
|
||||
isAtAll:boolean;
|
||||
isAtAll: boolean;
|
||||
|
||||
|
||||
async sign(){
|
||||
async sign() {
|
||||
const timestamp = Date.now();
|
||||
const secret = this.secret;
|
||||
const stringToSign = `${timestamp}\n${secret}`;
|
||||
@@ -83,21 +80,20 @@ export class DingTalkNotification extends BaseNotification {
|
||||
* hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
|
||||
* sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
|
||||
*/
|
||||
const crypto = await import('crypto');
|
||||
const hmac = crypto.createHmac('sha256', secret);
|
||||
const crypto = await import("crypto");
|
||||
const hmac = crypto.createHmac("sha256", secret);
|
||||
hmac.update(stringToSign);
|
||||
const sign = encodeURIComponent(Buffer.from(hmac.digest()).toString('base64'));
|
||||
const sign = encodeURIComponent(Buffer.from(hmac.digest()).toString("base64"));
|
||||
|
||||
return {
|
||||
timestamp,
|
||||
sign,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
async send(body: NotificationBody) {
|
||||
if (!this.webhook) {
|
||||
throw new Error('webhook地址不能为空');
|
||||
throw new Error("webhook地址不能为空");
|
||||
}
|
||||
/**
|
||||
*
|
||||
@@ -109,36 +105,36 @@ export class DingTalkNotification extends BaseNotification {
|
||||
*/
|
||||
|
||||
let webhook = this.webhook;
|
||||
if(this.secret){
|
||||
if (this.secret) {
|
||||
const signRet = await this.sign();
|
||||
webhook = `${webhook}×tamp=${signRet.timestamp}&sign=${signRet.sign}`;
|
||||
}
|
||||
|
||||
const at :any= {}
|
||||
if(this.atUserIds && this.atUserIds.length>0){
|
||||
at.atUserIds = this.atUserIds;
|
||||
const at: any = {};
|
||||
if (this.atUserIds && this.atUserIds.length > 0) {
|
||||
at.atUserIds = this.atUserIds;
|
||||
}
|
||||
if(this.atMobiles && this.atMobiles.length>0){
|
||||
at.atMobiles = this.atMobiles;
|
||||
if (this.atMobiles && this.atMobiles.length > 0) {
|
||||
at.atMobiles = this.atMobiles;
|
||||
}
|
||||
if(this.isAtAll){
|
||||
at.isAtAll = true;
|
||||
if (this.isAtAll) {
|
||||
at.isAtAll = true;
|
||||
}
|
||||
|
||||
const color = body.errorMessage?'red':'green';
|
||||
const color = body.errorMessage ? "red" : "green";
|
||||
const res = await this.http.request({
|
||||
url: webhook,
|
||||
method: 'POST',
|
||||
method: "POST",
|
||||
data: {
|
||||
at: at,
|
||||
markdown: {
|
||||
title: body.title,
|
||||
text: `<font color='${color}'>${body.title}</font>\n\n\n ${body.content}\n\n\n[查看详情](${body.url})`,
|
||||
},
|
||||
msgtype:"markdown"
|
||||
msgtype: "markdown",
|
||||
},
|
||||
});
|
||||
if(res.errcode>100){
|
||||
if (res.errcode > 100) {
|
||||
throw new Error(`发送失败:${res.errmsg}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,51 +1,51 @@
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from '@certd/pipeline';
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from "@certd/pipeline";
|
||||
|
||||
@IsNotification({
|
||||
name: 'discord',
|
||||
title: 'Discord 通知',
|
||||
desc: 'Discord 机器人通知',
|
||||
name: "discord",
|
||||
title: "Discord 通知",
|
||||
desc: "Discord 机器人通知",
|
||||
needPlus: true,
|
||||
})
|
||||
export class DiscordNotification extends BaseNotification {
|
||||
@NotificationInput({
|
||||
title: 'Webhook URL',
|
||||
title: "Webhook URL",
|
||||
component: {
|
||||
placeholder: 'https://discord.com/api/webhooks/xxxxx/xxxx',
|
||||
placeholder: "https://discord.com/api/webhooks/xxxxx/xxxx",
|
||||
},
|
||||
helper: '[Discord Webhook 说明](https://discord.com/developers/docs/resources/webhook#execute-webhook)',
|
||||
helper: "[Discord Webhook 说明](https://discord.com/developers/docs/resources/webhook#execute-webhook)",
|
||||
required: true,
|
||||
})
|
||||
webhook = '';
|
||||
webhook = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '提醒指定成员',
|
||||
title: "提醒指定成员",
|
||||
component: {
|
||||
name: 'a-select',
|
||||
vModel: 'value',
|
||||
mode: 'tags',
|
||||
name: "a-select",
|
||||
vModel: "value",
|
||||
mode: "tags",
|
||||
open: false,
|
||||
},
|
||||
required: false,
|
||||
helper: '填写成员的Id,或者角色Id(&id),或者everyone',
|
||||
helper: "填写成员的Id,或者角色Id(&id),或者everyone",
|
||||
})
|
||||
mentionedList!: string[];
|
||||
|
||||
@NotificationInput({
|
||||
title: '代理',
|
||||
title: "代理",
|
||||
component: {
|
||||
placeholder: 'http://xxxxx:xx',
|
||||
placeholder: "http://xxxxx:xx",
|
||||
},
|
||||
helper: '使用https_proxy',
|
||||
helper: "使用https_proxy",
|
||||
required: false,
|
||||
})
|
||||
httpsProxy = '';
|
||||
httpsProxy = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '忽略证书校验',
|
||||
title: "忽略证书校验",
|
||||
value: false,
|
||||
component: {
|
||||
name: 'a-switch',
|
||||
vModel: 'checked',
|
||||
name: "a-switch",
|
||||
vModel: "checked",
|
||||
},
|
||||
required: false,
|
||||
})
|
||||
@@ -53,13 +53,13 @@ export class DiscordNotification extends BaseNotification {
|
||||
|
||||
async send(body: NotificationBody) {
|
||||
if (!this.webhook) {
|
||||
throw new Error('Webhook URL 不能为空');
|
||||
throw new Error("Webhook URL 不能为空");
|
||||
}
|
||||
|
||||
// 创建 Discord 消息体
|
||||
let content = `${body.title}\n${body.content}\n\n[查看详情](${body.url})`;
|
||||
if (this.mentionedList && this.mentionedList.length > 0) {
|
||||
content += `\n${this.mentionedList.map(item => `<@${item}> `).join('')}`;
|
||||
content += `\n${this.mentionedList.map(item => `<@${item}> `).join("")}`;
|
||||
}
|
||||
|
||||
const json = {
|
||||
@@ -68,7 +68,7 @@ export class DiscordNotification extends BaseNotification {
|
||||
|
||||
await this.http.request({
|
||||
url: this.webhook,
|
||||
method: 'POST',
|
||||
method: "POST",
|
||||
data: json,
|
||||
httpProxy: this.httpsProxy,
|
||||
skipSslVerify: this.skipSslVerify,
|
||||
|
||||
@@ -1,41 +1,40 @@
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from '@certd/pipeline';
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from "@certd/pipeline";
|
||||
|
||||
@IsNotification({
|
||||
name: 'email',
|
||||
title: '电子邮件',
|
||||
desc: '电子邮件通知',
|
||||
name: "email",
|
||||
title: "电子邮件",
|
||||
desc: "电子邮件通知",
|
||||
order: -100,
|
||||
})
|
||||
export class EmailNotification extends BaseNotification {
|
||||
@NotificationInput({
|
||||
title: '收件人邮箱',
|
||||
title: "收件人邮箱",
|
||||
component: {
|
||||
name: 'email-selector',
|
||||
vModel: 'value',
|
||||
mode: 'tags',
|
||||
name: "email-selector",
|
||||
vModel: "value",
|
||||
mode: "tags",
|
||||
// open: false,
|
||||
},
|
||||
required: true,
|
||||
helper: '可以填写多个,填写一个按回车键再填写下一个\n需要先[配置邮件服务器](#/sys/settings/email)',
|
||||
helper: "可以填写多个,填写一个按回车键再填写下一个\n需要先[配置邮件服务器](#/sys/settings/email)",
|
||||
})
|
||||
receivers!: string[];
|
||||
|
||||
async send(body: NotificationBody) {
|
||||
|
||||
const templateData = {
|
||||
...body,
|
||||
}
|
||||
const emailSend:any = {
|
||||
};
|
||||
const emailSend: any = {
|
||||
receivers: this.receivers,
|
||||
}
|
||||
};
|
||||
if (body.attachments && body.attachments.length > 0) {
|
||||
emailSend.attachments = body.attachments;
|
||||
}
|
||||
await this.ctx.emailService.sendByTemplate({
|
||||
type: body.notificationType,
|
||||
data: templateData,
|
||||
...emailSend
|
||||
})
|
||||
...emailSend,
|
||||
});
|
||||
|
||||
// await this.ctx.emailService.send({
|
||||
// subject: body.title,
|
||||
|
||||
@@ -1,76 +1,73 @@
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from "@certd/pipeline";
|
||||
|
||||
@IsNotification({
|
||||
name: 'feishu',
|
||||
title: '飞书通知',
|
||||
desc: '飞书群聊webhook通知',
|
||||
name: "feishu",
|
||||
title: "飞书通知",
|
||||
desc: "飞书群聊webhook通知",
|
||||
needPlus: true,
|
||||
})
|
||||
// https://open.dingtalk.com/document/orgapp/the-creation-and-installation-of-the-application-robot-in-the?spm=ding_open_doc.document.0.0.242d1563cDgZz3
|
||||
export class FeishuNotification extends BaseNotification {
|
||||
@NotificationInput({
|
||||
title: 'webhook地址',
|
||||
title: "webhook地址",
|
||||
component: {
|
||||
placeholder: 'https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxxxxxxxxxx',
|
||||
placeholder: "https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxxxxxxxxxx",
|
||||
},
|
||||
helper: '飞书APP->群聊->设置->机器人->添加机器人->自定义webhook->[创建机器人->复制webhook地址](https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot?lang=zh-CN)',
|
||||
helper: "飞书APP->群聊->设置->机器人->添加机器人->自定义webhook->[创建机器人->复制webhook地址](https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot?lang=zh-CN)",
|
||||
required: true,
|
||||
})
|
||||
webhook = '';
|
||||
webhook = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '加签密钥',
|
||||
title: "加签密钥",
|
||||
component: {
|
||||
placeholder: 'SECxxxxxxxxxxxxxxxxxxxxx',
|
||||
placeholder: "SECxxxxxxxxxxxxxxxxxxxxx",
|
||||
},
|
||||
helper: '必须选择一种安全设置,建议选择加密密钥',
|
||||
helper: "必须选择一种安全设置,建议选择加密密钥",
|
||||
required: false,
|
||||
})
|
||||
secret = '';
|
||||
|
||||
secret = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '@用户',
|
||||
title: "@用户",
|
||||
component: {
|
||||
placeholder: '非必填,支持多个,填写完一个按回车',
|
||||
name: 'a-select',
|
||||
vModel: 'value',
|
||||
mode: 'tags',
|
||||
placeholder: "非必填,支持多个,填写完一个按回车",
|
||||
name: "a-select",
|
||||
vModel: "value",
|
||||
mode: "tags",
|
||||
multiple: true,
|
||||
open: false,
|
||||
},
|
||||
helper: '填写要@的用户ID:【ou_xxxxxxxxx】\n用户ID获取方法,[查看OpenId获取方法](https://open.feishu.cn/document/home/user-identity-introduction/open-id)',
|
||||
helper: "填写要@的用户ID:【ou_xxxxxxxxx】\n用户ID获取方法,[查看OpenId获取方法](https://open.feishu.cn/document/home/user-identity-introduction/open-id)",
|
||||
required: false,
|
||||
})
|
||||
atUserIds:string[];
|
||||
|
||||
atUserIds: string[];
|
||||
|
||||
@NotificationInput({
|
||||
title: '@all',
|
||||
title: "@all",
|
||||
component: {
|
||||
placeholder: '非必填',
|
||||
name: 'a-switch',
|
||||
vModel:"checked"
|
||||
placeholder: "非必填",
|
||||
name: "a-switch",
|
||||
vModel: "checked",
|
||||
},
|
||||
helper: '是否@所有人',
|
||||
helper: "是否@所有人",
|
||||
required: false,
|
||||
})
|
||||
isAtAll:boolean;
|
||||
isAtAll: boolean;
|
||||
|
||||
|
||||
async sign(){
|
||||
const crypto = await import('crypto');
|
||||
async sign() {
|
||||
const crypto = await import("crypto");
|
||||
const secret = this.secret;
|
||||
const timestamp = Math.floor(Date.now() / 1000);
|
||||
const str = Buffer.from(`${timestamp}\n${secret}`, 'utf8');
|
||||
const sign = crypto.createHmac('SHA256', str);
|
||||
const str = Buffer.from(`${timestamp}\n${secret}`, "utf8");
|
||||
const sign = crypto.createHmac("SHA256", str);
|
||||
sign.update(Buffer.alloc(0));
|
||||
return { timestamp, sign: sign.digest('base64') };
|
||||
return { timestamp, sign: sign.digest("base64") };
|
||||
}
|
||||
|
||||
async send(body: NotificationBody) {
|
||||
if (!this.webhook) {
|
||||
throw new Error('webhook地址不能为空');
|
||||
throw new Error("webhook地址不能为空");
|
||||
}
|
||||
/**
|
||||
*
|
||||
@@ -81,8 +78,7 @@ export class FeishuNotification extends BaseNotification {
|
||||
* }
|
||||
*/
|
||||
|
||||
let webhook = this.webhook;
|
||||
|
||||
const webhook = this.webhook;
|
||||
|
||||
/*
|
||||
// @ 单个用户
|
||||
@@ -90,109 +86,109 @@ export class FeishuNotification extends BaseNotification {
|
||||
// @ 所有人
|
||||
<at user_id="all">所有人</at>
|
||||
*/
|
||||
let atText = ""
|
||||
if(this.atUserIds && this.atUserIds.length>0){
|
||||
atText = this.atUserIds.map((id:string)=>{
|
||||
const nameIndex = id.indexOf(".");
|
||||
let name = id
|
||||
if(nameIndex>0){
|
||||
name = id.substring(nameIndex+1)
|
||||
}
|
||||
return `<at id=${id}>${name}</at>`
|
||||
}).join("");
|
||||
let atText = "";
|
||||
if (this.atUserIds && this.atUserIds.length > 0) {
|
||||
atText = this.atUserIds
|
||||
.map((id: string) => {
|
||||
const nameIndex = id.indexOf(".");
|
||||
let name = id;
|
||||
if (nameIndex > 0) {
|
||||
name = id.substring(nameIndex + 1);
|
||||
}
|
||||
return `<at id=${id}>${name}</at>`;
|
||||
})
|
||||
.join("");
|
||||
}
|
||||
if(this.isAtAll){
|
||||
atText = `<at id=all>所有人</at>`
|
||||
if (this.isAtAll) {
|
||||
atText = `<at id=all>所有人</at>`;
|
||||
}
|
||||
|
||||
if (atText){
|
||||
atText = `\n${atText}`
|
||||
if (atText) {
|
||||
atText = `\n${atText}`;
|
||||
}
|
||||
|
||||
let sign:any = {}
|
||||
if(this.secret){
|
||||
let sign: any = {};
|
||||
if (this.secret) {
|
||||
const signRet = await this.sign();
|
||||
sign = {
|
||||
timestamp: signRet.timestamp,
|
||||
sign: signRet.sign
|
||||
}
|
||||
sign: signRet.sign,
|
||||
};
|
||||
}
|
||||
|
||||
const cardBody = {
|
||||
"msg_type": "interactive",
|
||||
"card": {
|
||||
"schema": "2.0",
|
||||
"config": {
|
||||
"update_multi": true,
|
||||
"style": {
|
||||
"text_size": {
|
||||
"normal_v2": {
|
||||
"default": "normal",
|
||||
"pc": "normal",
|
||||
"mobile": "heading"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": {
|
||||
"tag": "plain_text",
|
||||
"content": body.title
|
||||
msg_type: "interactive",
|
||||
card: {
|
||||
schema: "2.0",
|
||||
config: {
|
||||
update_multi: true,
|
||||
style: {
|
||||
text_size: {
|
||||
normal_v2: {
|
||||
default: "normal",
|
||||
pc: "normal",
|
||||
mobile: "heading",
|
||||
},
|
||||
},
|
||||
},
|
||||
"subtitle": {
|
||||
"tag": "plain_text",
|
||||
"content": ""
|
||||
},
|
||||
"template": body.errorMessage?"red":"green",
|
||||
"padding": "12px 12px 12px 12px"
|
||||
},
|
||||
"body": {
|
||||
"direction": "vertical",
|
||||
"padding": "12px 12px 12px 12px",
|
||||
"elements": [
|
||||
header: {
|
||||
title: {
|
||||
tag: "plain_text",
|
||||
content: body.title,
|
||||
},
|
||||
subtitle: {
|
||||
tag: "plain_text",
|
||||
content: "",
|
||||
},
|
||||
template: body.errorMessage ? "red" : "green",
|
||||
padding: "12px 12px 12px 12px",
|
||||
},
|
||||
body: {
|
||||
direction: "vertical",
|
||||
padding: "12px 12px 12px 12px",
|
||||
elements: [
|
||||
{
|
||||
"tag": "markdown",
|
||||
"content": body.content+atText,
|
||||
"text_align": "left",
|
||||
"text_size": "normal_v2",
|
||||
"margin": "0px 0px 0px 0px"
|
||||
tag: "markdown",
|
||||
content: body.content + atText,
|
||||
text_align: "left",
|
||||
text_size: "normal_v2",
|
||||
margin: "0px 0px 0px 0px",
|
||||
},
|
||||
{
|
||||
"tag": "button",
|
||||
"text": {
|
||||
"tag": "plain_text",
|
||||
"content": "查看详情"
|
||||
tag: "button",
|
||||
text: {
|
||||
tag: "plain_text",
|
||||
content: "查看详情",
|
||||
},
|
||||
"type": "default",
|
||||
"width": "default",
|
||||
"size": "medium",
|
||||
"behaviors": [
|
||||
type: "default",
|
||||
width: "default",
|
||||
size: "medium",
|
||||
behaviors: [
|
||||
{
|
||||
"type": "open_url",
|
||||
"default_url": body.url,
|
||||
"pc_url": "",
|
||||
"ios_url": "",
|
||||
"android_url": ""
|
||||
}
|
||||
type: "open_url",
|
||||
default_url: body.url,
|
||||
pc_url: "",
|
||||
ios_url: "",
|
||||
android_url: "",
|
||||
},
|
||||
],
|
||||
"margin": "0px 0px 0px 0px"
|
||||
}
|
||||
]
|
||||
margin: "0px 0px 0px 0px",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
};
|
||||
|
||||
const res = await this.http.request({
|
||||
url: webhook,
|
||||
method: 'POST',
|
||||
method: "POST",
|
||||
data: {
|
||||
...sign,
|
||||
...cardBody
|
||||
...cardBody,
|
||||
},
|
||||
});
|
||||
if(res.code>100){
|
||||
if (res.code > 100) {
|
||||
throw new Error(`发送失败:${res.msg}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
export * from './qywx/index.js';
|
||||
export * from './email/index.js';
|
||||
export * from './iyuu/index.js';
|
||||
export * from './webhook/index.js';
|
||||
export * from './serverchan/index.js';
|
||||
export * from './serverchan3/index.js';
|
||||
export * from './anpush/index.js';
|
||||
export * from './telegram/index.js';
|
||||
export * from './discord/index.js';
|
||||
export * from './slack/index.js';
|
||||
export * from './bark/index.js';
|
||||
export * from './feishu/index.js';
|
||||
export * from './dingtalk/index.js';
|
||||
export * from './vocechat/index.js';
|
||||
export * from './onebot/index.js';
|
||||
export * from './meow/index.js';
|
||||
export * from "./qywx/index.js";
|
||||
export * from "./email/index.js";
|
||||
export * from "./iyuu/index.js";
|
||||
export * from "./webhook/index.js";
|
||||
export * from "./serverchan/index.js";
|
||||
export * from "./serverchan3/index.js";
|
||||
export * from "./anpush/index.js";
|
||||
export * from "./telegram/index.js";
|
||||
export * from "./discord/index.js";
|
||||
export * from "./slack/index.js";
|
||||
export * from "./bark/index.js";
|
||||
export * from "./feishu/index.js";
|
||||
export * from "./dingtalk/index.js";
|
||||
export * from "./vocechat/index.js";
|
||||
export * from "./onebot/index.js";
|
||||
export * from "./meow/index.js";
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from '@certd/pipeline';
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from "@certd/pipeline";
|
||||
|
||||
@IsNotification({
|
||||
name: 'iyuu',
|
||||
title: '爱语飞飞微信通知(iyuu)',
|
||||
desc: 'https://iyuu.cn/',
|
||||
name: "iyuu",
|
||||
title: "爱语飞飞微信通知(iyuu)",
|
||||
desc: "https://iyuu.cn/",
|
||||
needPlus: true,
|
||||
})
|
||||
export class IyuuNotification extends BaseNotification {
|
||||
@NotificationInput({
|
||||
title: 'Token令牌',
|
||||
title: "Token令牌",
|
||||
component: {
|
||||
placeholder: '',
|
||||
placeholder: "",
|
||||
},
|
||||
helper: 'https://iyuu.cn/ 微信扫码获取',
|
||||
helper: "https://iyuu.cn/ 微信扫码获取",
|
||||
required: true,
|
||||
})
|
||||
token = '';
|
||||
token = "";
|
||||
|
||||
async send(body: NotificationBody) {
|
||||
if (!this.token) {
|
||||
throw new Error('token不能为空');
|
||||
throw new Error("token不能为空");
|
||||
}
|
||||
const res = await this.http.request({
|
||||
url: `https://iyuu.cn/${this.token}.send`,
|
||||
method: 'POST',
|
||||
method: "POST",
|
||||
data: {
|
||||
text: body.title,
|
||||
desp: body.content + '\n\n[查看详情](' + body.url + ')',
|
||||
desp: body.content + "\n\n[查看详情](" + body.url + ")",
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from '@certd/pipeline';
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from "@certd/pipeline";
|
||||
|
||||
/**
|
||||
* POST请求
|
||||
@@ -38,43 +38,42 @@ Content-Type: application/json
|
||||
}
|
||||
*/
|
||||
@IsNotification({
|
||||
name: 'meow',
|
||||
title: 'MeoW通知',
|
||||
desc: 'https://api.chuckfang.com/',
|
||||
name: "meow",
|
||||
title: "MeoW通知",
|
||||
desc: "https://api.chuckfang.com/",
|
||||
needPlus: false,
|
||||
})
|
||||
export class MeowNotification extends BaseNotification {
|
||||
|
||||
@NotificationInput({
|
||||
title: 'MeoW接口地址',
|
||||
title: "MeoW接口地址",
|
||||
component: {
|
||||
placeholder: 'https://api.xxxxxx.com',
|
||||
placeholder: "https://api.xxxxxx.com",
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
endpoint = '';
|
||||
endpoint = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '昵称',
|
||||
title: "昵称",
|
||||
component: {
|
||||
placeholder: '',
|
||||
placeholder: "",
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
nickName = '';
|
||||
nickName = "";
|
||||
|
||||
async send(body: NotificationBody) {
|
||||
if (!this.nickName) {
|
||||
throw new Error('昵称不能为空');
|
||||
throw new Error("昵称不能为空");
|
||||
}
|
||||
let endpoint = this.endpoint;
|
||||
if (!endpoint.endsWith('/')) {
|
||||
endpoint += '/';
|
||||
if (!endpoint.endsWith("/")) {
|
||||
endpoint += "/";
|
||||
}
|
||||
const url = `${endpoint}${this.nickName}/`;
|
||||
const res = await this.http.request({
|
||||
url: url,
|
||||
method: 'POST',
|
||||
method: "POST",
|
||||
data: {
|
||||
text: body.title,
|
||||
msg: body.content,
|
||||
|
||||
@@ -1,135 +1,131 @@
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from "@certd/pipeline";
|
||||
import axios from "axios";
|
||||
|
||||
/**
|
||||
* 文档: https://github.com/botuniverse/onebot-11
|
||||
* 教程: https://ayakasuki.com/
|
||||
*/
|
||||
|
||||
@IsNotification({
|
||||
name: 'onebot',
|
||||
title: 'OneBot V11 通知',
|
||||
desc: '通过动态拼接URL发送 OneBot V11 协议消息',
|
||||
needPlus: false,
|
||||
})
|
||||
export class OneBotNotification extends BaseNotification {
|
||||
// 基础服务地址(不含路径)
|
||||
@NotificationInput({
|
||||
title: '服务地址',
|
||||
component: {
|
||||
placeholder: 'http://xxxx.xxxx.xxxx',
|
||||
},
|
||||
helper: 'OneBot 服务的基础地址(不包含action路径)',
|
||||
required: true,
|
||||
rules: [
|
||||
{
|
||||
type: 'url',
|
||||
message: '请输入有效的HTTP/HTTPS地址'
|
||||
}
|
||||
]
|
||||
})
|
||||
baseUrl = '';
|
||||
|
||||
// 目标类型选择
|
||||
@NotificationInput({
|
||||
title: '目标类型',
|
||||
component: {
|
||||
name: 'a-select',
|
||||
options: [
|
||||
{ value: 'group', label: '群聊' },
|
||||
{ value: 'private', label: '私聊' },
|
||||
],
|
||||
},
|
||||
required: true,
|
||||
helper: '选择消息发送的目标类型',
|
||||
})
|
||||
targetType = 'group';
|
||||
|
||||
// 目标ID配置
|
||||
@NotificationInput({
|
||||
title: '目标ID',
|
||||
component: {
|
||||
name: 'a-input-number',
|
||||
placeholder: '123456789',
|
||||
},
|
||||
helper: '群聊ID或用户ID(纯数字)',
|
||||
required: true,
|
||||
})
|
||||
targetId = '';
|
||||
|
||||
// 鉴权密钥(非必填)
|
||||
@NotificationInput({
|
||||
title: '鉴权密钥',
|
||||
component: {
|
||||
placeholder: 'xxxxxxxxxx',
|
||||
},
|
||||
helper: '(选填)访问API的授权令牌(无token时留空)',
|
||||
required: false, // 关键修改点
|
||||
})
|
||||
accessToken = '';
|
||||
|
||||
// 构建完整请求URL(支持无token场景)
|
||||
private buildFullUrl(): string {
|
||||
const action = this.targetType === 'group'
|
||||
? 'send_group_msg'
|
||||
: 'send_private_msg';
|
||||
|
||||
let url = `${this.baseUrl}/${action}`;
|
||||
|
||||
// 动态添加access_token参数(仅当存在时)
|
||||
if (this.accessToken) {
|
||||
url += `?access_token=${encodeURIComponent(this.accessToken)}`;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
// 构建消息内容
|
||||
private buildMessage(body: NotificationBody): string {
|
||||
return body.title
|
||||
? `${body.title}\n${body.content}`
|
||||
: body.content;
|
||||
}
|
||||
|
||||
// 构建请求体(动态字段)
|
||||
private buildRequestBody(body: NotificationBody): object {
|
||||
return {
|
||||
[this.targetType === 'group' ? 'group_id' : 'user_id']: Number(this.targetId),
|
||||
message: this.buildMessage(body),
|
||||
auto_escape: false
|
||||
};
|
||||
}
|
||||
|
||||
// 发送通知主逻辑
|
||||
async send(body: NotificationBody) {
|
||||
const fullUrl = this.buildFullUrl();
|
||||
const requestBody = this.buildRequestBody(body);
|
||||
|
||||
try {
|
||||
console.debug("[ONEBOT] 最终请求URL:", fullUrl);
|
||||
console.debug("[ONEBOT] 请求体:", JSON.stringify(requestBody));
|
||||
console.debug("[ONEBOT] 使用Token:", !!this.accessToken); // 明确token使用状态
|
||||
|
||||
const response = await axios.post(fullUrl, requestBody, {
|
||||
timeout: 5000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'User-Agent': 'Certd-Notification/1.0'
|
||||
}
|
||||
});
|
||||
|
||||
// 响应验证(保持不变)
|
||||
if (response.data?.retcode !== 0) {
|
||||
throw new Error(`[${response.data.retcode}] ${response.data.message}`);
|
||||
}
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error('[ONEBOT] 请求失败:', {
|
||||
url: fullUrl,
|
||||
tokenUsed: !!this.accessToken, // 记录token使用状态
|
||||
error: error.response?.data || error.message
|
||||
});
|
||||
throw new Error(`OneBot通知发送失败: ${error.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from "@certd/pipeline";
|
||||
import axios from "axios";
|
||||
|
||||
/**
|
||||
* 文档: https://github.com/botuniverse/onebot-11
|
||||
* 教程: https://ayakasuki.com/
|
||||
*/
|
||||
|
||||
@IsNotification({
|
||||
name: "onebot",
|
||||
title: "OneBot V11 通知",
|
||||
desc: "通过动态拼接URL发送 OneBot V11 协议消息",
|
||||
needPlus: false,
|
||||
})
|
||||
export class OneBotNotification extends BaseNotification {
|
||||
// 基础服务地址(不含路径)
|
||||
@NotificationInput({
|
||||
title: "服务地址",
|
||||
component: {
|
||||
placeholder: "http://xxxx.xxxx.xxxx",
|
||||
},
|
||||
helper: "OneBot 服务的基础地址(不包含action路径)",
|
||||
required: true,
|
||||
rules: [
|
||||
{
|
||||
type: "url",
|
||||
message: "请输入有效的HTTP/HTTPS地址",
|
||||
},
|
||||
],
|
||||
})
|
||||
baseUrl = "";
|
||||
|
||||
// 目标类型选择
|
||||
@NotificationInput({
|
||||
title: "目标类型",
|
||||
component: {
|
||||
name: "a-select",
|
||||
options: [
|
||||
{ value: "group", label: "群聊" },
|
||||
{ value: "private", label: "私聊" },
|
||||
],
|
||||
},
|
||||
required: true,
|
||||
helper: "选择消息发送的目标类型",
|
||||
})
|
||||
targetType = "group";
|
||||
|
||||
// 目标ID配置
|
||||
@NotificationInput({
|
||||
title: "目标ID",
|
||||
component: {
|
||||
name: "a-input-number",
|
||||
placeholder: "123456789",
|
||||
},
|
||||
helper: "群聊ID或用户ID(纯数字)",
|
||||
required: true,
|
||||
})
|
||||
targetId = "";
|
||||
|
||||
// 鉴权密钥(非必填)
|
||||
@NotificationInput({
|
||||
title: "鉴权密钥",
|
||||
component: {
|
||||
placeholder: "xxxxxxxxxx",
|
||||
},
|
||||
helper: "(选填)访问API的授权令牌(无token时留空)",
|
||||
required: false, // 关键修改点
|
||||
})
|
||||
accessToken = "";
|
||||
|
||||
// 构建完整请求URL(支持无token场景)
|
||||
private buildFullUrl(): string {
|
||||
const action = this.targetType === "group" ? "send_group_msg" : "send_private_msg";
|
||||
|
||||
let url = `${this.baseUrl}/${action}`;
|
||||
|
||||
// 动态添加access_token参数(仅当存在时)
|
||||
if (this.accessToken) {
|
||||
url += `?access_token=${encodeURIComponent(this.accessToken)}`;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
// 构建消息内容
|
||||
private buildMessage(body: NotificationBody): string {
|
||||
return body.title ? `${body.title}\n${body.content}` : body.content;
|
||||
}
|
||||
|
||||
// 构建请求体(动态字段)
|
||||
private buildRequestBody(body: NotificationBody): object {
|
||||
return {
|
||||
[this.targetType === "group" ? "group_id" : "user_id"]: Number(this.targetId),
|
||||
message: this.buildMessage(body),
|
||||
auto_escape: false,
|
||||
};
|
||||
}
|
||||
|
||||
// 发送通知主逻辑
|
||||
async send(body: NotificationBody) {
|
||||
const fullUrl = this.buildFullUrl();
|
||||
const requestBody = this.buildRequestBody(body);
|
||||
|
||||
try {
|
||||
console.debug("[ONEBOT] 最终请求URL:", fullUrl);
|
||||
console.debug("[ONEBOT] 请求体:", JSON.stringify(requestBody));
|
||||
console.debug("[ONEBOT] 使用Token:", !!this.accessToken); // 明确token使用状态
|
||||
|
||||
const response = await axios.post(fullUrl, requestBody, {
|
||||
timeout: 5000,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": "Certd-Notification/1.0",
|
||||
},
|
||||
});
|
||||
|
||||
// 响应验证(保持不变)
|
||||
if (response.data?.retcode !== 0) {
|
||||
throw new Error(`[${response.data.retcode}] ${response.data.message}`);
|
||||
}
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error("[ONEBOT] 请求失败:", {
|
||||
url: fullUrl,
|
||||
tokenUsed: !!this.accessToken, // 记录token使用状态
|
||||
error: error.response?.data || error.message,
|
||||
});
|
||||
throw new Error(`OneBot通知发送失败: ${error.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,58 +1,58 @@
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from '@certd/pipeline';
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from "@certd/pipeline";
|
||||
|
||||
@IsNotification({
|
||||
name: 'qywx',
|
||||
title: '企业微信通知',
|
||||
desc: '企业微信群聊机器人通知',
|
||||
name: "qywx",
|
||||
title: "企业微信通知",
|
||||
desc: "企业微信群聊机器人通知",
|
||||
needPlus: true,
|
||||
})
|
||||
export class QywxNotification extends BaseNotification {
|
||||
@NotificationInput({
|
||||
title: 'webhook地址',
|
||||
title: "webhook地址",
|
||||
component: {
|
||||
placeholder: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxx',
|
||||
placeholder: "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxx",
|
||||
},
|
||||
helper: '[企微群聊机器人配置说明](https://developer.work.weixin.qq.com/document/path/91770)',
|
||||
helper: "[企微群聊机器人配置说明](https://developer.work.weixin.qq.com/document/path/91770)",
|
||||
required: true,
|
||||
})
|
||||
webhook = '';
|
||||
webhook = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '提醒指定成员',
|
||||
title: "提醒指定成员",
|
||||
component: {
|
||||
name: 'a-select',
|
||||
vModel: 'value',
|
||||
mode: 'tags',
|
||||
name: "a-select",
|
||||
vModel: "value",
|
||||
mode: "tags",
|
||||
open: false,
|
||||
},
|
||||
required: false,
|
||||
helper: '填写成员名字,@all 为提醒所有人',
|
||||
helper: "填写成员名字,@all 为提醒所有人",
|
||||
})
|
||||
mentionedList!: string[];
|
||||
|
||||
@NotificationInput({
|
||||
title: '提醒指定手机号成员',
|
||||
title: "提醒指定手机号成员",
|
||||
component: {
|
||||
name: 'a-select',
|
||||
vModel: 'value',
|
||||
mode: 'tags',
|
||||
name: "a-select",
|
||||
vModel: "value",
|
||||
mode: "tags",
|
||||
open: false,
|
||||
},
|
||||
required: false,
|
||||
helper: '填写成员手机号,@all 为提醒所有人',
|
||||
helper: "填写成员手机号,@all 为提醒所有人",
|
||||
})
|
||||
mentionedMobileList!: string[];
|
||||
|
||||
async send(body: NotificationBody) {
|
||||
if (!this.webhook) {
|
||||
throw new Error('webhook地址不能为空');
|
||||
throw new Error("webhook地址不能为空");
|
||||
}
|
||||
|
||||
await this.http.request({
|
||||
url: this.webhook,
|
||||
method: 'POST',
|
||||
method: "POST",
|
||||
data: {
|
||||
msgtype: 'text',
|
||||
msgtype: "text",
|
||||
text: {
|
||||
content: `${body.title}\n${body.content}\n查看详情: ${body.url}`,
|
||||
mentioned_list: this.mentionedList,
|
||||
@@ -61,7 +61,6 @@ export class QywxNotification extends BaseNotification {
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
//Markdown 模式不支持@
|
||||
|
||||
// const color = body.errorMessage?'red':'green';
|
||||
|
||||
@@ -1,55 +1,55 @@
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from '@certd/pipeline';
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from "@certd/pipeline";
|
||||
|
||||
@IsNotification({
|
||||
name: 'serverchan',
|
||||
title: 'Server酱ᵀ',
|
||||
desc: 'https://sct.ftqq.com/',
|
||||
name: "serverchan",
|
||||
title: "Server酱ᵀ",
|
||||
desc: "https://sct.ftqq.com/",
|
||||
needPlus: true,
|
||||
})
|
||||
export class ServerChanNotification extends BaseNotification {
|
||||
@NotificationInput({
|
||||
title: '服务地址',
|
||||
value: 'https://sctapi.ftqq.com',
|
||||
title: "服务地址",
|
||||
value: "https://sctapi.ftqq.com",
|
||||
required: true,
|
||||
})
|
||||
endpoint = 'https://sctapi.ftqq.com';
|
||||
endpoint = "https://sctapi.ftqq.com";
|
||||
|
||||
@NotificationInput({
|
||||
title: 'SendKey',
|
||||
title: "SendKey",
|
||||
component: {
|
||||
placeholder: 'https://sctapi.ftqq.com/<SENDKEY>.send',
|
||||
placeholder: "https://sctapi.ftqq.com/<SENDKEY>.send",
|
||||
},
|
||||
helper: 'https://sct.ftqq.com/ 微信扫码获取',
|
||||
helper: "https://sct.ftqq.com/ 微信扫码获取",
|
||||
required: true,
|
||||
})
|
||||
sendKey = '';
|
||||
sendKey = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '消息通道号',
|
||||
title: "消息通道号",
|
||||
component: {
|
||||
placeholder: '9|66',
|
||||
placeholder: "9|66",
|
||||
},
|
||||
helper: '可以不填,最多两个通道,[通道配置说明](https://sct.ftqq.com/sendkey)',
|
||||
helper: "可以不填,最多两个通道,[通道配置说明](https://sct.ftqq.com/sendkey)",
|
||||
required: false,
|
||||
})
|
||||
channel: string;
|
||||
|
||||
@NotificationInput({
|
||||
title: '是否隐藏IP',
|
||||
title: "是否隐藏IP",
|
||||
component: {
|
||||
name: 'a-switch',
|
||||
vModel: 'checked',
|
||||
name: "a-switch",
|
||||
vModel: "checked",
|
||||
},
|
||||
required: false,
|
||||
})
|
||||
noip: boolean;
|
||||
|
||||
@NotificationInput({
|
||||
title: '忽略证书校验',
|
||||
title: "忽略证书校验",
|
||||
value: false,
|
||||
component: {
|
||||
name: 'a-switch',
|
||||
vModel: 'checked',
|
||||
name: "a-switch",
|
||||
vModel: "checked",
|
||||
},
|
||||
required: false,
|
||||
})
|
||||
@@ -57,14 +57,14 @@ export class ServerChanNotification extends BaseNotification {
|
||||
|
||||
async send(body: NotificationBody) {
|
||||
if (!this.sendKey) {
|
||||
throw new Error('sendKey不能为空');
|
||||
throw new Error("sendKey不能为空");
|
||||
}
|
||||
await this.http.request({
|
||||
url: `${this.endpoint}/${this.sendKey}.send`,
|
||||
method: 'POST',
|
||||
method: "POST",
|
||||
data: {
|
||||
text: body.title,
|
||||
desp: body.content + '\n\n[查看详情](' + body.url + ')',
|
||||
desp: body.content + "\n\n[查看详情](" + body.url + ")",
|
||||
},
|
||||
skipSslVerify: this.skipSslVerify,
|
||||
});
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from '@certd/pipeline';
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from "@certd/pipeline";
|
||||
|
||||
@IsNotification({
|
||||
name: 'serverchan3',
|
||||
title: 'Server酱³',
|
||||
desc: 'https://doc.sc3.ft07.com/serverchan3',
|
||||
name: "serverchan3",
|
||||
title: "Server酱³",
|
||||
desc: "https://doc.sc3.ft07.com/serverchan3",
|
||||
needPlus: true,
|
||||
})
|
||||
export class ServerChan3Notification extends BaseNotification {
|
||||
@NotificationInput({
|
||||
title: 'ApiURL',
|
||||
title: "ApiURL",
|
||||
component: {
|
||||
placeholder: 'https://uid.push.ft07.com/send/sendKey.send',
|
||||
placeholder: "https://uid.push.ft07.com/send/sendKey.send",
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
apiURL = '';
|
||||
apiURL = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '标签Tags',
|
||||
title: "标签Tags",
|
||||
component: {
|
||||
name: 'a-select',
|
||||
vModel: 'value',
|
||||
mode: 'tags',
|
||||
name: "a-select",
|
||||
vModel: "value",
|
||||
mode: "tags",
|
||||
open: false,
|
||||
},
|
||||
helper: '支持多个,回车后填写下一个',
|
||||
helper: "支持多个,回车后填写下一个",
|
||||
required: false,
|
||||
})
|
||||
tags: string[];
|
||||
|
||||
@NotificationInput({
|
||||
title: 'short',
|
||||
title: "short",
|
||||
required: false,
|
||||
})
|
||||
short: string;
|
||||
|
||||
@NotificationInput({
|
||||
title: '忽略证书校验',
|
||||
title: "忽略证书校验",
|
||||
value: false,
|
||||
component: {
|
||||
name: 'a-switch',
|
||||
vModel: 'checked',
|
||||
name: "a-switch",
|
||||
vModel: "checked",
|
||||
},
|
||||
required: false,
|
||||
})
|
||||
@@ -48,15 +48,15 @@ export class ServerChan3Notification extends BaseNotification {
|
||||
|
||||
async send(body: NotificationBody) {
|
||||
if (!this.apiURL) {
|
||||
throw new Error('sendKey不能为空');
|
||||
throw new Error("sendKey不能为空");
|
||||
}
|
||||
await this.http.request({
|
||||
url: `${this.apiURL}`,
|
||||
method: 'POST',
|
||||
method: "POST",
|
||||
data: {
|
||||
text: body.title,
|
||||
desp: body.content + '\n\n[查看详情](' + body.url + ')',
|
||||
tags: this.tags?.join('|') || undefined,
|
||||
desp: body.content + "\n\n[查看详情](" + body.url + ")",
|
||||
tags: this.tags?.join("|") || undefined,
|
||||
short: this.short,
|
||||
},
|
||||
skipSslVerify: this.skipSslVerify,
|
||||
|
||||
@@ -1,38 +1,38 @@
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from '@certd/pipeline';
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from "@certd/pipeline";
|
||||
|
||||
@IsNotification({
|
||||
name: 'slack',
|
||||
title: 'Slack通知',
|
||||
desc: 'Slack消息推送通知',
|
||||
name: "slack",
|
||||
title: "Slack通知",
|
||||
desc: "Slack消息推送通知",
|
||||
needPlus: true,
|
||||
})
|
||||
export class SlackNotification extends BaseNotification {
|
||||
@NotificationInput({
|
||||
title: 'webhook地址',
|
||||
title: "webhook地址",
|
||||
component: {
|
||||
placeholder: 'https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX',
|
||||
placeholder: "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
},
|
||||
helper: '[APPS](https://api.slack.com/apps/)->进入APP->incoming-webhooks->Add New Webhook to Workspace',
|
||||
helper: "[APPS](https://api.slack.com/apps/)->进入APP->incoming-webhooks->Add New Webhook to Workspace",
|
||||
required: true,
|
||||
})
|
||||
webhook = '';
|
||||
webhook = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '代理',
|
||||
title: "代理",
|
||||
component: {
|
||||
placeholder: 'http://xxxxx:xx',
|
||||
placeholder: "http://xxxxx:xx",
|
||||
},
|
||||
helper: '使用https_proxy',
|
||||
helper: "使用https_proxy",
|
||||
required: false,
|
||||
})
|
||||
httpsProxy = '';
|
||||
httpsProxy = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '忽略证书校验',
|
||||
title: "忽略证书校验",
|
||||
value: false,
|
||||
component: {
|
||||
name: 'a-switch',
|
||||
vModel: 'checked',
|
||||
name: "a-switch",
|
||||
vModel: "checked",
|
||||
},
|
||||
required: false,
|
||||
})
|
||||
@@ -40,12 +40,12 @@ export class SlackNotification extends BaseNotification {
|
||||
|
||||
async send(body: NotificationBody) {
|
||||
if (!this.webhook) {
|
||||
throw new Error('token不能为空');
|
||||
throw new Error("token不能为空");
|
||||
}
|
||||
|
||||
await this.http.request({
|
||||
url: this.webhook,
|
||||
method: 'POST',
|
||||
method: "POST",
|
||||
data: {
|
||||
text: `${body.title}\n${body.content}\n\n[查看详情](${body.url})`,
|
||||
},
|
||||
|
||||
@@ -1,58 +1,58 @@
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from '@certd/pipeline';
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from "@certd/pipeline";
|
||||
|
||||
@IsNotification({
|
||||
name: 'telegram',
|
||||
title: 'Telegram通知',
|
||||
desc: 'Telegram Bot推送通知',
|
||||
name: "telegram",
|
||||
title: "Telegram通知",
|
||||
desc: "Telegram Bot推送通知",
|
||||
needPlus: true,
|
||||
})
|
||||
export class TelegramNotification extends BaseNotification {
|
||||
@NotificationInput({
|
||||
title: 'URL',
|
||||
value: 'https://api.telegram.org',
|
||||
title: "URL",
|
||||
value: "https://api.telegram.org",
|
||||
component: {
|
||||
placeholder: 'https://api.telegram.org',
|
||||
placeholder: "https://api.telegram.org",
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
endpoint = 'https://api.telegram.org';
|
||||
endpoint = "https://api.telegram.org";
|
||||
|
||||
@NotificationInput({
|
||||
title: 'Bot Token',
|
||||
title: "Bot Token",
|
||||
component: {
|
||||
placeholder: '123456789:ABCdefGhijklmnopqrstUVWXyz',
|
||||
placeholder: "123456789:ABCdefGhijklmnopqrstUVWXyz",
|
||||
},
|
||||
helper: '[token获取](https://core.telegram.org/bots/features#botfather)',
|
||||
helper: "[token获取](https://core.telegram.org/bots/features#botfather)",
|
||||
required: true,
|
||||
})
|
||||
botToken = '';
|
||||
botToken = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '聊天ID',
|
||||
title: "聊天ID",
|
||||
component: {
|
||||
placeholder: '聊天ID,例如 123456789 或 @channelusername',
|
||||
placeholder: "聊天ID,例如 123456789 或 @channelusername",
|
||||
},
|
||||
helper: '用户ID(纯数字)或频道名称(@xxxx)',
|
||||
helper: "用户ID(纯数字)或频道名称(@xxxx)",
|
||||
required: true,
|
||||
})
|
||||
chatId = '';
|
||||
chatId = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '代理',
|
||||
title: "代理",
|
||||
component: {
|
||||
placeholder: 'http://xxxxx:xx',
|
||||
placeholder: "http://xxxxx:xx",
|
||||
},
|
||||
helper: '使用https_proxy',
|
||||
helper: "使用https_proxy",
|
||||
required: false,
|
||||
})
|
||||
httpsProxy = '';
|
||||
httpsProxy = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '忽略证书校验',
|
||||
title: "忽略证书校验",
|
||||
value: false,
|
||||
component: {
|
||||
name: 'a-switch',
|
||||
vModel: 'checked',
|
||||
name: "a-switch",
|
||||
vModel: "checked",
|
||||
},
|
||||
required: false,
|
||||
})
|
||||
@@ -60,13 +60,13 @@ export class TelegramNotification extends BaseNotification {
|
||||
|
||||
replaceText(text: string) {
|
||||
// .*()<> 等都需要用\\进行替换
|
||||
return text.replace(/[_*[\]()~`>#\+\-=|{}.!]/g, '\\$&');
|
||||
return text.replace(/[_*[\]()~`>#\+\-=|{}.!]/g, "\\$&");
|
||||
// .replace(/([\\_*`|!.[\](){}>+#=~-])/gm, '\\$1')
|
||||
// return text.replace(/[\\.*()<>]/g, '\\$&');
|
||||
}
|
||||
async send(body: NotificationBody) {
|
||||
if (!this.botToken || !this.chatId) {
|
||||
throw new Error('Bot Token 和聊天ID不能为空');
|
||||
throw new Error("Bot Token 和聊天ID不能为空");
|
||||
}
|
||||
|
||||
// 构建消息内容
|
||||
@@ -78,11 +78,11 @@ export class TelegramNotification extends BaseNotification {
|
||||
// 发送 HTTP 请求
|
||||
await this.http.request({
|
||||
url: url,
|
||||
method: 'POST',
|
||||
method: "POST",
|
||||
data: {
|
||||
chat_id: this.chatId,
|
||||
text: messageContent,
|
||||
parse_mode: 'MarkdownV2', // 或使用 'HTML' 取决于需要的格式
|
||||
parse_mode: "MarkdownV2", // 或使用 'HTML' 取决于需要的格式
|
||||
},
|
||||
httpProxy: this.httpsProxy,
|
||||
skipSslVerify: this.skipSslVerify,
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from '@certd/pipeline';
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from "@certd/pipeline";
|
||||
|
||||
@IsNotification({
|
||||
name: 'vocechat',
|
||||
title: 'VoceChat通知',
|
||||
desc: 'https://voce.chat',
|
||||
name: "vocechat",
|
||||
title: "VoceChat通知",
|
||||
desc: "https://voce.chat",
|
||||
needPlus: true,
|
||||
})
|
||||
export class VoceChatNotification extends BaseNotification {
|
||||
@NotificationInput({
|
||||
title: '服务地址',
|
||||
title: "服务地址",
|
||||
component: {
|
||||
placeholder: 'https://replace.your.domain',
|
||||
placeholder: "https://replace.your.domain",
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
endpoint = '';
|
||||
endpoint = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: 'apiKey',
|
||||
title: "apiKey",
|
||||
component: {
|
||||
placeholder: '',
|
||||
placeholder: "",
|
||||
},
|
||||
helper: '[获取APIKEY](https://doc.voce.chat/bot/bot-and-webhook)',
|
||||
helper: "[获取APIKEY](https://doc.voce.chat/bot/bot-and-webhook)",
|
||||
required: true,
|
||||
})
|
||||
apiKey = '';
|
||||
apiKey = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '目标类型',
|
||||
title: "目标类型",
|
||||
component: {
|
||||
name: 'a-select',
|
||||
name: "a-select",
|
||||
options: [
|
||||
{ value: 'user', label: '用户' },
|
||||
{ value: 'channel', label: '频道' },
|
||||
{ value: "user", label: "用户" },
|
||||
{ value: "channel", label: "频道" },
|
||||
],
|
||||
},
|
||||
required: true,
|
||||
helper: '发送消息的目标类型',
|
||||
helper: "发送消息的目标类型",
|
||||
})
|
||||
targetType = '';
|
||||
targetType = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '目标ID',
|
||||
title: "目标ID",
|
||||
component: {
|
||||
placeholder: '发送消息的目标ID',
|
||||
placeholder: "发送消息的目标ID",
|
||||
},
|
||||
required: true,
|
||||
helper: '目标ID可以是用户ID或频道ID',
|
||||
helper: "目标ID可以是用户ID或频道ID",
|
||||
})
|
||||
targetId = '';
|
||||
targetId = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '忽略证书校验',
|
||||
title: "忽略证书校验",
|
||||
value: false,
|
||||
component: {
|
||||
name: 'a-switch',
|
||||
vModel: 'checked',
|
||||
name: "a-switch",
|
||||
vModel: "checked",
|
||||
},
|
||||
required: false,
|
||||
})
|
||||
@@ -63,21 +63,21 @@ export class VoceChatNotification extends BaseNotification {
|
||||
|
||||
async send(body: NotificationBody) {
|
||||
if (!this.apiKey) {
|
||||
throw new Error('API Key不能为空');
|
||||
throw new Error("API Key不能为空");
|
||||
}
|
||||
|
||||
if (!this.targetId) {
|
||||
throw new Error('目标ID不能为空');
|
||||
throw new Error("目标ID不能为空");
|
||||
}
|
||||
|
||||
const url = this.targetType === 'user' ? '/api/bot/send_to_user/' : '/api/bot/send_to_group/';
|
||||
const url = this.targetType === "user" ? "/api/bot/send_to_user/" : "/api/bot/send_to_group/";
|
||||
await this.http.request({
|
||||
url: url + this.targetId, // 这是示例API URL,请根据实际API文档调整
|
||||
baseURL: this.endpoint,
|
||||
method: 'POST',
|
||||
method: "POST",
|
||||
headers: {
|
||||
'x-api-key': this.apiKey,
|
||||
'Content-Type': 'text/markdown',
|
||||
"x-api-key": this.apiKey,
|
||||
"Content-Type": "text/markdown",
|
||||
},
|
||||
data: `# ${body.title}\n\n${body.content}\n\n[查看详情](${body.url})`,
|
||||
skipSslVerify: this.skipSslVerify,
|
||||
|
||||
@@ -1,79 +1,79 @@
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from '@certd/pipeline';
|
||||
import qs from 'qs';
|
||||
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from "@certd/pipeline";
|
||||
import qs from "qs";
|
||||
|
||||
@IsNotification({
|
||||
name: 'webhook',
|
||||
title: '自定义webhook',
|
||||
desc: '根据模版自定义http请求',
|
||||
name: "webhook",
|
||||
title: "自定义webhook",
|
||||
desc: "根据模版自定义http请求",
|
||||
order: -100,
|
||||
})
|
||||
export class WebhookNotification extends BaseNotification {
|
||||
@NotificationInput({
|
||||
title: 'webhook地址',
|
||||
title: "webhook地址",
|
||||
component: {
|
||||
placeholder: 'https://xxxxx.com/xxxx',
|
||||
placeholder: "https://xxxxx.com/xxxx",
|
||||
},
|
||||
col: {
|
||||
span: 24,
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
webhook = '';
|
||||
webhook = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '请求方式',
|
||||
value: 'POST',
|
||||
title: "请求方式",
|
||||
value: "POST",
|
||||
component: {
|
||||
name: 'a-select',
|
||||
placeholder: 'post/put/get',
|
||||
name: "a-select",
|
||||
placeholder: "post/put/get",
|
||||
options: [
|
||||
{ value: 'POST', label: 'POST' },
|
||||
{ value: 'PUT', label: 'PUT' },
|
||||
{ value: 'GET', label: 'GET' },
|
||||
{ value: "POST", label: "POST" },
|
||||
{ value: "PUT", label: "PUT" },
|
||||
{ value: "GET", label: "GET" },
|
||||
],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
method = '';
|
||||
method = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: 'ContentType',
|
||||
value: 'application/json',
|
||||
title: "ContentType",
|
||||
value: "application/json",
|
||||
component: {
|
||||
name: 'a-auto-complete',
|
||||
name: "a-auto-complete",
|
||||
options: [
|
||||
{ value: 'application/json', label: 'application/json' },
|
||||
{ value: 'application/x-www-form-urlencoded', label: 'application/x-www-form-urlencoded' },
|
||||
{ value: "application/json", label: "application/json" },
|
||||
{ value: "application/x-www-form-urlencoded", label: "application/x-www-form-urlencoded" },
|
||||
],
|
||||
},
|
||||
helper: '也可以自定义填写',
|
||||
helper: "也可以自定义填写",
|
||||
required: true,
|
||||
})
|
||||
contentType = '';
|
||||
contentType = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: 'Headers',
|
||||
title: "Headers",
|
||||
component: {
|
||||
name: 'a-textarea',
|
||||
vModel: 'value',
|
||||
name: "a-textarea",
|
||||
vModel: "value",
|
||||
rows: 2,
|
||||
},
|
||||
col: {
|
||||
span: 24,
|
||||
},
|
||||
helper: '一行一个,格式为key=value',
|
||||
helper: "一行一个,格式为key=value",
|
||||
required: false,
|
||||
})
|
||||
headers = '';
|
||||
headers = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '消息body模版',
|
||||
title: "消息body模版",
|
||||
value: `{
|
||||
"title":"{title}",
|
||||
"content":"{content}\\n[查看详情]({url})"
|
||||
}`,
|
||||
component: {
|
||||
name: 'a-textarea',
|
||||
name: "a-textarea",
|
||||
rows: 4,
|
||||
},
|
||||
col: {
|
||||
@@ -82,14 +82,14 @@ export class WebhookNotification extends BaseNotification {
|
||||
helper: `根据对应的webhook接口文档,构建一个json对象作为参数(默认值只是一个示例,一般不是正确的参数)\n支持变量:{title}、{content}、{url},变量用{}包裹\n字符串需要双引号,使用\\n换行\n如果是get方式,将作为query参数拼接到url上`,
|
||||
required: true,
|
||||
})
|
||||
template = '';
|
||||
template = "";
|
||||
|
||||
@NotificationInput({
|
||||
title: '忽略证书校验',
|
||||
title: "忽略证书校验",
|
||||
value: false,
|
||||
component: {
|
||||
name: 'a-switch',
|
||||
vModel: 'checked',
|
||||
name: "a-switch",
|
||||
vModel: "checked",
|
||||
},
|
||||
required: false,
|
||||
})
|
||||
@@ -102,17 +102,16 @@ export class WebhookNotification extends BaseNotification {
|
||||
let value = urlEncode ? encodeURIComponent(body[key]) : body[key];
|
||||
value = value.replaceAll(`\n`, "\\n");
|
||||
bodyStr = bodyStr.replaceAll(`{${key}}`, value);
|
||||
|
||||
}
|
||||
return bodyStr;
|
||||
}
|
||||
|
||||
async send(body: NotificationBody) {
|
||||
if (!this.template) {
|
||||
throw new Error('模版不能为空');
|
||||
throw new Error("模版不能为空");
|
||||
}
|
||||
if (!this.webhook) {
|
||||
throw new Error('webhook不能为空');
|
||||
throw new Error("webhook不能为空");
|
||||
}
|
||||
|
||||
const replaceBody = {
|
||||
@@ -124,9 +123,9 @@ export class WebhookNotification extends BaseNotification {
|
||||
let data = JSON.parse(bodyStr);
|
||||
|
||||
let url = this.webhook;
|
||||
if (this.method.toLowerCase() === 'get') {
|
||||
if (this.method.toLowerCase() === "get") {
|
||||
const query = qs.stringify(data);
|
||||
if (url.includes('?')) {
|
||||
if (url.includes("?")) {
|
||||
url = `${url}&${query}`;
|
||||
} else {
|
||||
url = `${url}?${query}`;
|
||||
@@ -136,12 +135,12 @@ export class WebhookNotification extends BaseNotification {
|
||||
|
||||
const headers: any = {};
|
||||
if (this.headers && this.headers.trim()) {
|
||||
this.headers.split('\n').forEach(item => {
|
||||
this.headers.split("\n").forEach(item => {
|
||||
item = item.trim();
|
||||
if (item) {
|
||||
const eqIndex = item.indexOf('=');
|
||||
const eqIndex = item.indexOf("=");
|
||||
if (eqIndex <= 0) {
|
||||
this.logger.warn('header格式错误,请使用=号分割', item);
|
||||
this.logger.warn("header格式错误,请使用=号分割", item);
|
||||
return;
|
||||
}
|
||||
const key = item.substring(0, eqIndex);
|
||||
@@ -155,16 +154,16 @@ export class WebhookNotification extends BaseNotification {
|
||||
url: url,
|
||||
method: this.method,
|
||||
headers: {
|
||||
'Content-Type': `${this.contentType}; charset=UTF-8`,
|
||||
"Content-Type": `${this.contentType}; charset=UTF-8`,
|
||||
...headers,
|
||||
},
|
||||
data: data,
|
||||
skipSslVerify: this.skipSslVerify,
|
||||
});
|
||||
return res
|
||||
return res;
|
||||
} catch (e) {
|
||||
if (e.response?.data) {
|
||||
throw new Error(e.message + ',' + JSON.stringify(e.response.data));
|
||||
throw new Error(e.message + "," + JSON.stringify(e.response.data));
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user