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}`); } } }