From b82e1dcd6217b09a7d7e21cd648bb31de320cadf Mon Sep 17 00:00:00 2001 From: xiaojunnuo Date: Fri, 14 Mar 2025 13:16:48 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E6=94=AF=E6=8C=81=E9=A3=9E=E4=B9=A6?= =?UTF-8?q?=E9=80=9A=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/pipeline/src/notification/api.ts | 2 +- .../components/plugins/common/api-test.vue | 3 + .../plugin-notification/feishu/index.ts | 137 ++++++++++++++++++ .../src/plugins/plugin-notification/index.ts | 1 + .../plugin-notification/webhook/index.ts | 3 +- pnpm-lock.yaml | 80 +++++----- 6 files changed, 184 insertions(+), 42 deletions(-) create mode 100644 packages/ui/certd-server/src/plugins/plugin-notification/feishu/index.ts diff --git a/packages/core/pipeline/src/notification/api.ts b/packages/core/pipeline/src/notification/api.ts index fe465e04..c6bd9971 100644 --- a/packages/core/pipeline/src/notification/api.ts +++ b/packages/core/pipeline/src/notification/api.ts @@ -119,7 +119,7 @@ export abstract class BaseNotification implements INotification { } async onTestRequest() { - await this.doSend({ + return await this.doSend({ userId: 0, title: "【Certd】测试通知【*.foo.com】,标题长度测试、测试、测试", content: "测试通知,*.foo.com", diff --git a/packages/ui/certd-client/src/components/plugins/common/api-test.vue b/packages/ui/certd-client/src/components/plugins/common/api-test.vue index 8145abe9..c041a8ea 100644 --- a/packages/ui/certd-client/src/components/plugins/common/api-test.vue +++ b/packages/ui/certd-client/src/components/plugins/common/api-test.vue @@ -60,6 +60,9 @@ const doTest = async () => { } ); message.value = "测试请求成功"; + if (res) { + message.value += `,返回:${JSON.stringify(res)}`; + } } finally { loading.value = false; } diff --git a/packages/ui/certd-server/src/plugins/plugin-notification/feishu/index.ts b/packages/ui/certd-server/src/plugins/plugin-notification/feishu/index.ts new file mode 100644 index 00000000..5f9a7678 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-notification/feishu/index.ts @@ -0,0 +1,137 @@ +import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from "@certd/pipeline"; + +@IsNotification({ + 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 DingTalkNotification extends BaseNotification { + @NotificationInput({ + title: 'webhook地址', + component: { + 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)', + required: true, + }) + webhook = ''; + + @NotificationInput({ + title: '加签密钥', + component: { + placeholder: 'SECxxxxxxxxxxxxxxxxxxxxx', + }, + helper: '必须选择一种安全设置,建议选择加密密钥', + required: false, + }) + secret = ''; + + + @NotificationInput({ + title: '@用户', + component: { + 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)', + required: false, + }) + atUserIds:string[]; + + + @NotificationInput({ + title: '@all', + component: { + placeholder: '非必填', + name: 'a-switch', + vModel:"checked" + }, + helper: '是否@所有人', + required: false, + }) + isAtAll:boolean; + + + 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); + sign.update(Buffer.alloc(0)); + return { timestamp, sign: sign.digest('base64') }; + } + + async send(body: NotificationBody) { + if (!this.webhook) { + throw new Error('webhook地址不能为空'); + } + /** + * + * "msgtype": "text", + * "text": { + * "content": "hello world" + * } + * } + */ + + let webhook = this.webhook; + + + /* + // @ 单个用户 +名字 +// @ 所有人 +所有人 + */ + 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 `${name}` + }).join(""); + } + if(this.isAtAll){ + atText = `所有人` + } + + if (atText){ + atText = `\n· ${atText}` + } + + let sign:any = {} + if(this.secret){ + const signRet = await this.sign(); + sign = { + timestamp: signRet.timestamp, + sign: signRet.sign + } + } + + + const res = await this.http.request({ + url: webhook, + method: 'POST', + data: { + ...sign, + content: { + text: `· ${body.title}\n· ${body.content}\n· 查看详情: ${body.url}${atText}`, + }, + msg_type:"text" + }, + }); + if(res.code>100){ + throw new Error(`发送失败:${res.msg}`); + } + } +} diff --git a/packages/ui/certd-server/src/plugins/plugin-notification/index.ts b/packages/ui/certd-server/src/plugins/plugin-notification/index.ts index d85f071e..db431331 100644 --- a/packages/ui/certd-server/src/plugins/plugin-notification/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-notification/index.ts @@ -9,3 +9,4 @@ 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'; diff --git a/packages/ui/certd-server/src/plugins/plugin-notification/webhook/index.ts b/packages/ui/certd-server/src/plugins/plugin-notification/webhook/index.ts index ffda53e7..02b473ae 100644 --- a/packages/ui/certd-server/src/plugins/plugin-notification/webhook/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-notification/webhook/index.ts @@ -148,7 +148,7 @@ export class WebhookNotification extends BaseNotification { } try { - await this.http.request({ + const res = await this.http.request({ url: url, method: this.method, headers: { @@ -158,6 +158,7 @@ export class WebhookNotification extends BaseNotification { data: data, skipSslVerify: this.skipSslVerify, }); + return res } catch (e) { if (e.response?.data) { throw new Error(e.message + ',' + JSON.stringify(e.response.data)); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9086579f..5e7aba2d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -46,7 +46,7 @@ importers: packages/core/acme-client: dependencies: '@certd/basic': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../basic '@peculiar/x509': specifier: ^1.11.0 @@ -204,10 +204,10 @@ importers: packages/core/pipeline: dependencies: '@certd/basic': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../basic '@certd/plus-core': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../pro/plus-core dayjs: specifier: ^1.11.7 @@ -342,7 +342,7 @@ importers: packages/libs/lib-k8s: dependencies: '@certd/basic': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../core/basic '@kubernetes/client-node': specifier: 0.21.0 @@ -382,16 +382,16 @@ importers: packages/libs/lib-server: dependencies: '@certd/acme-client': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../core/acme-client '@certd/basic': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../core/basic '@certd/pipeline': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../core/pipeline '@certd/plus-core': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../pro/plus-core '@midwayjs/cache': specifier: ~3.14.0 @@ -534,16 +534,16 @@ importers: packages/plugins/plugin-cert: dependencies: '@certd/acme-client': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../core/acme-client '@certd/basic': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../core/basic '@certd/pipeline': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../core/pipeline '@certd/plugin-lib': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../plugin-lib '@google-cloud/publicca': specifier: ^1.3.0 @@ -610,10 +610,10 @@ importers: specifier: ^1.7.10 version: 1.8.0 '@certd/basic': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../core/basic '@certd/pipeline': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../core/pipeline '@kubernetes/client-node': specifier: 0.21.0 @@ -701,19 +701,19 @@ importers: packages/pro/commercial-core: dependencies: '@certd/basic': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../core/basic '@certd/lib-server': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../libs/lib-server '@certd/pipeline': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../core/pipeline '@certd/plugin-plus': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../plugin-plus '@certd/plus-core': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../plus-core '@midwayjs/core': specifier: ~3.20.3 @@ -798,22 +798,22 @@ importers: specifier: ^1.0.2 version: 1.0.2 '@certd/basic': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../core/basic '@certd/lib-k8s': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../libs/lib-k8s '@certd/pipeline': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../core/pipeline '@certd/plugin-cert': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../plugins/plugin-cert '@certd/plugin-lib': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../plugins/plugin-lib '@certd/plus-core': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../plus-core ali-oss: specifier: ^6.21.0 @@ -910,7 +910,7 @@ importers: packages/pro/plus-core: dependencies: '@certd/basic': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../core/basic dayjs: specifier: ^1.11.7 @@ -1182,10 +1182,10 @@ importers: version: 0.1.3(zod@3.24.2) devDependencies: '@certd/lib-iframe': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../libs/lib-iframe '@certd/pipeline': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../core/pipeline '@rollup/plugin-commonjs': specifier: ^25.0.7 @@ -1365,40 +1365,40 @@ importers: specifier: ^3.705.0 version: 3.758.0(aws-crt@1.25.3) '@certd/acme-client': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../core/acme-client '@certd/basic': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../core/basic '@certd/commercial-core': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../pro/commercial-core '@certd/lib-huawei': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../libs/lib-huawei '@certd/lib-k8s': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../libs/lib-k8s '@certd/lib-server': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../libs/lib-server '@certd/midway-flyway-js': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../libs/midway-flyway-js '@certd/pipeline': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../core/pipeline '@certd/plugin-cert': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../plugins/plugin-cert '@certd/plugin-lib': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../plugins/plugin-lib '@certd/plugin-plus': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../pro/plugin-plus '@certd/plus-core': - specifier: ^1.31.2 + specifier: ^1.31.3 version: link:../../pro/plus-core '@corsinvest/cv4pve-api-javascript': specifier: ^8.3.0