mirror of https://github.com/certd/certd
perf: 通知支持vocechat、bark、telegram、discord、slack
parent
cbccd9e3d0
commit
642f57ff6d
|
@ -367,16 +367,16 @@ export class Executor {
|
||||||
const errorMessage = error?.message;
|
const errorMessage = error?.message;
|
||||||
if (when === "start") {
|
if (when === "start") {
|
||||||
subject = `【Certd】开始执行,【${this.pipeline.id}】${this.pipeline.title}`;
|
subject = `【Certd】开始执行,【${this.pipeline.id}】${this.pipeline.title}`;
|
||||||
content = `buildId:${this.runtime.id}\n查看详情:${url}`;
|
content = `buildId:${this.runtime.id}`;
|
||||||
} else if (when === "success") {
|
} else if (when === "success") {
|
||||||
subject = `【Certd】执行成功,【${this.pipeline.id}】${this.pipeline.title}`;
|
subject = `【Certd】执行成功,【${this.pipeline.id}】${this.pipeline.title}`;
|
||||||
content = `buildId:${this.runtime.id}\n查看详情:${url}`;
|
content = `buildId:${this.runtime.id}`;
|
||||||
} else if (when === "turnToSuccess") {
|
} else if (when === "turnToSuccess") {
|
||||||
subject = `【Certd】执行成功(失败转成功),【${this.pipeline.id}】${this.pipeline.title}`;
|
subject = `【Certd】执行成功(失败转成功),【${this.pipeline.id}】${this.pipeline.title}`;
|
||||||
content = `buildId:${this.runtime.id}\n查看详情:${url}`;
|
content = `buildId:${this.runtime.id}`;
|
||||||
} else if (when === "error") {
|
} else if (when === "error") {
|
||||||
subject = `【Certd】执行失败,【${this.pipeline.id}】${this.pipeline.title}`;
|
subject = `【Certd】执行失败,【${this.pipeline.id}】${this.pipeline.title}`;
|
||||||
content = `buildId:${this.runtime.id}\n查看详情:${url}\nerror:${error.message}`;
|
content = `buildId:${this.runtime.id}\nerror:${error.message}`;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,14 +98,14 @@ export abstract class BaseNotification implements INotification {
|
||||||
await this.send({
|
await this.send({
|
||||||
userId: 0,
|
userId: 0,
|
||||||
title: "【Certd】测试通知",
|
title: "【Certd】测试通知",
|
||||||
content: "测试通知\n\n查看详情:http://www.baidu.com",
|
content: "测试通知",
|
||||||
pipeline: {
|
pipeline: {
|
||||||
id: 1,
|
id: 1,
|
||||||
title: "测试流水线",
|
title: "测试流水线",
|
||||||
} as any,
|
} as any,
|
||||||
pipelineId: 1,
|
pipelineId: 1,
|
||||||
historyId: 1,
|
historyId: 1,
|
||||||
url: "http://www.baidu.com",
|
url: "https://certd.docmirror.cn",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,11 +199,13 @@ function openUpgrade() {
|
||||||
const vipTypeDefine = {
|
const vipTypeDefine = {
|
||||||
free: {
|
free: {
|
||||||
title: "基础版",
|
title: "基础版",
|
||||||
|
desc: "免费使用",
|
||||||
type: "free",
|
type: "free",
|
||||||
privilege: ["证书申请功能无限制", "证书流水线数量10条", "常用的主机、cdn等部署插件"]
|
privilege: ["证书申请功能无限制", "证书流水线数量10条", "常用的主机、cdn等部署插件"]
|
||||||
},
|
},
|
||||||
plus: {
|
plus: {
|
||||||
title: "专业版",
|
title: "专业版",
|
||||||
|
desc: "功能增强,适用于个人企业内部使用",
|
||||||
type: "plus",
|
type: "plus",
|
||||||
privilege: ["可加VIP群,需求优先实现", "证书流水线数量无限制", "免配置发邮件功能", "支持宝塔、易盾、群晖、1Panel、cdnfly等部署插件"],
|
privilege: ["可加VIP群,需求优先实现", "证书流水线数量无限制", "免配置发邮件功能", "支持宝塔、易盾、群晖、1Panel、cdnfly等部署插件"],
|
||||||
trial: {
|
trial: {
|
||||||
|
@ -215,6 +217,7 @@ function openUpgrade() {
|
||||||
},
|
},
|
||||||
comm: {
|
comm: {
|
||||||
title: "商业版",
|
title: "商业版",
|
||||||
|
desc: "商业授权,可对外运营",
|
||||||
type: "comm",
|
type: "comm",
|
||||||
privilege: ["拥有专业版所有特权", "允许商用,可修改logo、标题", "数据统计", "插件管理", "多用户无限制", "支持用户支付(敬请期待)"]
|
privilege: ["拥有专业版所有特权", "允许商用,可修改logo、标题", "数据统计", "插件管理", "多用户无限制", "支持用户支付(敬请期待)"]
|
||||||
}
|
}
|
||||||
|
@ -268,6 +271,7 @@ function openUpgrade() {
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</h3>
|
</h3>
|
||||||
|
<div>{item.desc}</div>
|
||||||
<ul>
|
<ul>
|
||||||
{item.privilege.map((p: string) => (
|
{item.privilege.map((p: string) => (
|
||||||
<li>
|
<li>
|
||||||
|
@ -333,7 +337,7 @@ function openUpgrade() {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border: 1px solid #eee;
|
border: 1px solid #eee;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
height: 170px;
|
height: 195px;
|
||||||
//background-color: rgba(250, 237, 167, 0.79);
|
//background-color: rgba(250, 237, 167, 0.79);
|
||||||
&.current {
|
&.current {
|
||||||
border-color: green;
|
border-color: green;
|
||||||
|
|
|
@ -77,6 +77,12 @@ h1, h2, h3, h4, h5, h6 {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
.align-left{
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.align-right{
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
.scroll-y {
|
.scroll-y {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
|
@ -180,8 +180,10 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="task">
|
<div class="task">
|
||||||
<a-button shape="round" @click="notificationEdit(item, ii as number)">
|
<a-button shape="round" @click="notificationEdit(item, ii as number)">
|
||||||
<fs-icon icon="ion:notifications"></fs-icon>
|
<div class="flex-o w-100">
|
||||||
【通知】 {{ item.title || item.type }}
|
<fs-icon icon="ion:notifications"></fs-icon>
|
||||||
|
<span class="ellipsis flex-1 step-title align-left"> 【通知】 {{ item.title || item.type }} </span>
|
||||||
|
</div>
|
||||||
</a-button>
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -198,8 +200,10 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="task">
|
<div class="task">
|
||||||
<a-button shape="round" @click="notificationEdit(item, index)">
|
<a-button shape="round" @click="notificationEdit(item, index)">
|
||||||
<fs-icon icon="ion:notifications"></fs-icon>
|
<div class="flex-o w-100">
|
||||||
【通知】 {{ item.title || item.type }}
|
<fs-icon icon="ion:notifications"></fs-icon>
|
||||||
|
<span class="ellipsis flex-1 step-title align-left"> 【通知】 {{ item.title || item.type }} </span>
|
||||||
|
</div>
|
||||||
</a-button>
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -39,7 +39,7 @@ export class AnPushNotification extends BaseNotification {
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
title: body.title,
|
title: body.title,
|
||||||
content: body.content,
|
content: body.content + '[查看详情](' + body.url + ')',
|
||||||
channel: this.channel,
|
channel: this.channel,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/**
|
||||||
|
* curl -X "POST" "https://api.day.app/your_key" \
|
||||||
|
* -H 'Content-Type: application/json; charset=utf-8' \
|
||||||
|
* -d $'{
|
||||||
|
* "body": "Test Bark Server",
|
||||||
|
* "title": "Test Title",
|
||||||
|
* "badge": 1,
|
||||||
|
* "category": "myNotificationCategory",
|
||||||
|
* "sound": "minuet.caf",
|
||||||
|
* "icon": "https://day.app/assets/images/avatar.jpg",
|
||||||
|
* "group": "test",
|
||||||
|
* "url": "https://mritd.com"
|
||||||
|
* }'
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from '@certd/pipeline';
|
||||||
|
|
||||||
|
@IsNotification({
|
||||||
|
name: 'bark',
|
||||||
|
title: 'Bark 通知',
|
||||||
|
desc: 'Bark 推送通知插件',
|
||||||
|
})
|
||||||
|
export class BarkNotification extends BaseNotification {
|
||||||
|
@NotificationInput({
|
||||||
|
title: '服务地址',
|
||||||
|
component: {
|
||||||
|
placeholder: 'https://api.day.app/your_key',
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
helper: '你的bark服务地址+key',
|
||||||
|
})
|
||||||
|
webhook = '';
|
||||||
|
async send(body: NotificationBody) {
|
||||||
|
if (!this.webhook) {
|
||||||
|
throw new Error('服务器地址不能为空');
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
body: body.content, // 使用传入的内容或默认内容
|
||||||
|
title: body.title, // 使用传入的标题或默认标题
|
||||||
|
};
|
||||||
|
|
||||||
|
await this.http.request({
|
||||||
|
url: `${this.webhook}`,
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json; charset=utf-8',
|
||||||
|
},
|
||||||
|
data: payload,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from '@certd/pipeline';
|
||||||
|
|
||||||
|
@IsNotification({
|
||||||
|
name: 'discord',
|
||||||
|
title: 'Discord 通知',
|
||||||
|
desc: 'Discord 机器人通知',
|
||||||
|
})
|
||||||
|
export class DiscordNotification extends BaseNotification {
|
||||||
|
@NotificationInput({
|
||||||
|
title: 'Webhook URL',
|
||||||
|
component: {
|
||||||
|
placeholder: 'https://discord.com/api/webhooks/xxxxx/xxxx',
|
||||||
|
},
|
||||||
|
helper: '[Discord Webhook 说明](https://discord.com/developers/docs/resources/webhook#execute-webhook)',
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
webhook = '';
|
||||||
|
|
||||||
|
@NotificationInput({
|
||||||
|
title: '提醒指定成员',
|
||||||
|
component: {
|
||||||
|
name: 'a-select',
|
||||||
|
vModel: 'value',
|
||||||
|
mode: 'tags',
|
||||||
|
open: false,
|
||||||
|
},
|
||||||
|
required: false,
|
||||||
|
helper: '填写成员的Id,或者角色Id(&id),或者everyone',
|
||||||
|
})
|
||||||
|
mentionedList!: string[];
|
||||||
|
|
||||||
|
async send(body: NotificationBody) {
|
||||||
|
if (!this.webhook) {
|
||||||
|
throw new Error('Webhook URL 不能为空');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建 Discord 消息体
|
||||||
|
let content = `${body.title}\n${body.content}\n[查看详情](${body.url})`;
|
||||||
|
if (this.mentionedList && this.mentionedList.length > 0) {
|
||||||
|
content += `\n${this.mentionedList.map(item => `<@${item}> `).join('')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const json = {
|
||||||
|
content: content,
|
||||||
|
};
|
||||||
|
|
||||||
|
await this.http.request({
|
||||||
|
url: this.webhook,
|
||||||
|
method: 'POST',
|
||||||
|
data: json,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,7 +23,7 @@ export class EmailNotification extends BaseNotification {
|
||||||
await this.ctx.emailService.send({
|
await this.ctx.emailService.send({
|
||||||
userId: body.userId,
|
userId: body.userId,
|
||||||
subject: body.title,
|
subject: body.title,
|
||||||
content: body.content,
|
content: body.content + '\n[查看详情](' + body.url + ')',
|
||||||
receivers: this.receivers,
|
receivers: this.receivers,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,3 +4,7 @@ export * from './iyuu/index.js';
|
||||||
export * from './webhook/index.js';
|
export * from './webhook/index.js';
|
||||||
export * from './serverchan/index.js';
|
export * from './serverchan/index.js';
|
||||||
export * from './anpush/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';
|
||||||
|
|
|
@ -25,7 +25,7 @@ export class IyuuNotification extends BaseNotification {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: {
|
data: {
|
||||||
text: body.title,
|
text: body.title,
|
||||||
desp: body.content,
|
desp: body.content + '[查看详情](' + body.url + ')',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ export class ServerChanNotification extends BaseNotification {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: {
|
data: {
|
||||||
text: body.title,
|
text: body.title,
|
||||||
desp: body.content,
|
desp: body.content + '[查看详情](' + body.url + ')',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from '@certd/pipeline';
|
||||||
|
|
||||||
|
@IsNotification({
|
||||||
|
name: 'slack',
|
||||||
|
title: 'Slack通知',
|
||||||
|
desc: 'Slack消息推送通知',
|
||||||
|
})
|
||||||
|
export class SlackNotification extends BaseNotification {
|
||||||
|
@NotificationInput({
|
||||||
|
title: 'webhook地址',
|
||||||
|
component: {
|
||||||
|
placeholder: 'https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX',
|
||||||
|
},
|
||||||
|
helper: '[APPS](https://api.slack.com/apps/)->进入APP->incoming-webhooks->Add New Webhook to Workspace',
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
webhook = '';
|
||||||
|
|
||||||
|
async send(body: NotificationBody) {
|
||||||
|
if (!this.webhook) {
|
||||||
|
throw new Error('token不能为空');
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.http.request({
|
||||||
|
url: this.webhook,
|
||||||
|
method: 'POST',
|
||||||
|
data: {
|
||||||
|
text: `${body.title}\n${body.content}\n[查看详情](${body.url})`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from '@certd/pipeline';
|
||||||
|
|
||||||
|
@IsNotification({
|
||||||
|
name: 'telegram',
|
||||||
|
title: 'Telegram通知',
|
||||||
|
desc: 'Telegram Bot推送通知',
|
||||||
|
})
|
||||||
|
export class TelegramNotification extends BaseNotification {
|
||||||
|
@NotificationInput({
|
||||||
|
title: 'Bot Token',
|
||||||
|
component: {
|
||||||
|
placeholder: '123456789:ABCdefGhijklmnopqrstUVWXyz',
|
||||||
|
},
|
||||||
|
helper: '[token获取](https://core.telegram.org/bots/features#botfather)',
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
botToken = '';
|
||||||
|
|
||||||
|
@NotificationInput({
|
||||||
|
title: '聊天ID',
|
||||||
|
component: {
|
||||||
|
placeholder: '聊天ID,例如 -123456789 或 @channelusername',
|
||||||
|
},
|
||||||
|
helper: '聊天的唯一标识符或用户名',
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
chatId = '';
|
||||||
|
|
||||||
|
async send(body: NotificationBody) {
|
||||||
|
if (!this.botToken || !this.chatId) {
|
||||||
|
throw new Error('Bot Token 和聊天ID不能为空');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建消息内容
|
||||||
|
const messageContent = `*${body.title}*\n\n${body.content}\n[查看详情](${body.url})`;
|
||||||
|
|
||||||
|
// Telegram API URL
|
||||||
|
const url = `https://api.telegram.org/bot${this.botToken}/sendMessage`;
|
||||||
|
|
||||||
|
// 发送 HTTP 请求
|
||||||
|
await this.http.request({
|
||||||
|
url: url,
|
||||||
|
method: 'POST',
|
||||||
|
data: {
|
||||||
|
chat_id: this.chatId,
|
||||||
|
text: messageContent,
|
||||||
|
parse_mode: 'MarkdownV2', // 或使用 'HTML' 取决于需要的格式
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from '@certd/pipeline';
|
||||||
|
|
||||||
|
@IsNotification({
|
||||||
|
name: 'vocechat',
|
||||||
|
title: 'VoceChat通知',
|
||||||
|
desc: 'https://voce.chat',
|
||||||
|
})
|
||||||
|
export class VoceChatNotification extends BaseNotification {
|
||||||
|
@NotificationInput({
|
||||||
|
title: '服务地址',
|
||||||
|
component: {
|
||||||
|
placeholder: 'https://replace.your.domain',
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
endpoint = '';
|
||||||
|
|
||||||
|
@NotificationInput({
|
||||||
|
title: 'apiKey',
|
||||||
|
component: {
|
||||||
|
placeholder: '',
|
||||||
|
},
|
||||||
|
helper: '[获取APIKEY](https://doc.voce.chat/bot/bot-and-webhook)',
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
apiKey = '';
|
||||||
|
|
||||||
|
@NotificationInput({
|
||||||
|
title: '目标类型',
|
||||||
|
component: {
|
||||||
|
name: 'a-select',
|
||||||
|
options: [
|
||||||
|
{ value: 'user', label: '用户' },
|
||||||
|
{ value: 'channel', label: '频道' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
helper: '发送消息的目标类型',
|
||||||
|
})
|
||||||
|
targetType = '';
|
||||||
|
|
||||||
|
@NotificationInput({
|
||||||
|
title: '目标ID',
|
||||||
|
component: {
|
||||||
|
placeholder: '发送消息的目标ID',
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
helper: '目标ID可以是用户ID或频道ID',
|
||||||
|
})
|
||||||
|
targetId = '';
|
||||||
|
|
||||||
|
async send(body: NotificationBody) {
|
||||||
|
if (!this.apiKey) {
|
||||||
|
throw new Error('API Key不能为空');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.targetId) {
|
||||||
|
throw new Error('目标ID不能为空');
|
||||||
|
}
|
||||||
|
|
||||||
|
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',
|
||||||
|
headers: {
|
||||||
|
'x-api-key': this.apiKey,
|
||||||
|
'Content-Type': 'text/markdown',
|
||||||
|
},
|
||||||
|
data: `# ${body.title}\n\n${body.content}\n[查看详情](${body.url})`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,11 +44,22 @@ export class WebhookNotification extends BaseNotification {
|
||||||
})
|
})
|
||||||
contentType = '';
|
contentType = '';
|
||||||
|
|
||||||
|
@NotificationInput({
|
||||||
|
title: 'Headers',
|
||||||
|
component: {
|
||||||
|
name: 'a-textarea',
|
||||||
|
rows: 3,
|
||||||
|
},
|
||||||
|
helper: '一行一个,格式为key:value',
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
headers = '';
|
||||||
|
|
||||||
@NotificationInput({
|
@NotificationInput({
|
||||||
title: '消息body模版',
|
title: '消息body模版',
|
||||||
value: `{
|
value: `{
|
||||||
title:"{title}",
|
"text":"{title}",
|
||||||
content:"{content}"
|
"desp":"{content}\\n[查看详情]({url})"
|
||||||
}`,
|
}`,
|
||||||
component: {
|
component: {
|
||||||
name: 'a-textarea',
|
name: 'a-textarea',
|
||||||
|
@ -57,7 +68,7 @@ export class WebhookNotification extends BaseNotification {
|
||||||
col: {
|
col: {
|
||||||
span: 24,
|
span: 24,
|
||||||
},
|
},
|
||||||
helper: `根据实际的webhook接口,构建一个json对象作为参数,支持{title}和{content}两个变量,变量用{}包裹,字符串需要双引号`,
|
helper: `根据实际的webhook接口,构建一个json对象作为参数,支持变量:{title}、{content}、{url},变量用{}包裹,字符串需要双引号`,
|
||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
template = '';
|
template = '';
|
||||||
|
@ -67,15 +78,21 @@ export class WebhookNotification extends BaseNotification {
|
||||||
throw new Error('模版不能为空');
|
throw new Error('模版不能为空');
|
||||||
}
|
}
|
||||||
|
|
||||||
const bodyStr = this.template.replaceAll('{title}', body.title).replaceAll('{content}', body.content);
|
const bodyStr = this.template.replaceAll('{title}', body.title).replaceAll('{content}', body.content).replaceAll('{url}', body.url);
|
||||||
|
|
||||||
const data = JSON.parse(bodyStr);
|
const data = JSON.parse(bodyStr);
|
||||||
|
|
||||||
|
const headers: any = {};
|
||||||
|
this.headers.split('\n').forEach(item => {
|
||||||
|
const [key, value] = item.trim().split(':');
|
||||||
|
headers[key] = value;
|
||||||
|
});
|
||||||
await this.http.request({
|
await this.http.request({
|
||||||
url: this.webhook,
|
url: this.webhook,
|
||||||
method: this.method,
|
method: this.method,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': `${this.contentType}; charset=UTF-8`,
|
'Content-Type': `${this.contentType}; charset=UTF-8`,
|
||||||
|
...headers,
|
||||||
},
|
},
|
||||||
data: data,
|
data: data,
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue