diff --git a/README.md b/README.md index def2e7e..6c6af8a 100644 --- a/README.md +++ b/README.md @@ -218,6 +218,8 @@ buvid3亦可不填 使用随机生成值 | `TG_PROXY_PORT` | Telegram 代理的端口 | 例子:http代理 则填写 1080 | | `DD_BOT_TOKEN` | 钉钉推送 | 钉钉推送(`DD_BOT_TOKEN`和`DD_BOT_SECRET`两者必需)[官方文档](https://ding-doc.dingtalk.com/doc#/serverapi2/qf2nxq) ,只需`https://oapi.dingtalk.com/robot/send?access_token=XXX` 等于`=`符号后面的XXX即可 | | `DD_BOT_SECRET` | 钉钉推送 | (`DD_BOT_TOKEN`和`DD_BOT_SECRET`两者必需) ,密钥,机器人安全设置页面,加签一栏下面显示的SEC开头的`SECXXXXXXXXXX`等字符 , 注:钉钉机器人安全设置只需勾选`加签`即可,其他选项不要勾选,再不懂看 [这个图](doc/pic/DD_bot.png) | +| `FS_BOT_WEBHOOK` | 飞书机器人 | 飞书机器人 webhook,创建自定义机器人后复制 webhook 地址,[官方文档](https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot) | +| `FS_BOT_SECRET` | 飞书机器人 | 飞书机器人安全设置中的签名密钥(若开启“签名校验”则必填),[官方文档](https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot) | | `IGOT_PUSH_KEY` | iGot推送 | iGot聚合推送,支持多方式推送,确保消息可达。 [参考文档](https://wahao.github.io/Bark-MP-helper ) | | `QQ_SKEY` | 酷推(Cool Push)推送 | 推送所需的Skey,登录后获取Skey [参考文档](https://cp.xuthus.cc/) | | `QQ_MODE` | 酷推(Cool Push)推送 | 推送方式(send或group或者wx,默认send) [参考文档](https://cp.xuthus.cc/) | diff --git a/env.example.js b/env.example.js index 3b97e8f..9532b96 100644 --- a/env.example.js +++ b/env.example.js @@ -109,7 +109,9 @@ module.exports = Object.freeze({ SMTP_PASS: '', SMTP_TO_USER: '', GOTIFY_URL: '', - GOTIFY_APPKEY: '' + GOTIFY_APPKEY: '', + FS_BOT_WEBHOOK: '', + FS_BOT_SECRET: '' }, /** diff --git a/lib/helper/notify.js b/lib/helper/notify.js index d0f13e9..bd268d6 100644 --- a/lib/helper/notify.js +++ b/lib/helper/notify.js @@ -88,6 +88,14 @@ let GOTIFY_URL = ''; // 此处填你想推送的Application的Token(不包含推送时额外添加的前缀 Bearer ) let GOTIFY_APPKEY = ''; +// =======================================飞书机器人通知设置区域=========================================== +// 此处填你飞书机器人的 webhook(详见文档 https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot) +// 注:此处设置github action用户填写到Settings-Secrets里面(Name输入FS_BOT_WEBHOOK) +let FS_BOT_WEBHOOK = ''; +// 签名密钥(如果在飞书机器人安全设置里开启了“签名校验”) +// 注:此处设置github action用户填写到Settings-Secrets里面(Name输入FS_BOT_SECRET) +let FS_BOT_SECRET = ''; + //==========================云端环境变量的判断与接收========================= if (process.env.SCKEY) { SCKEY = process.env.SCKEY; @@ -211,6 +219,14 @@ if (process.env.GOTIFY_URL) { } } +if (process.env.FS_BOT_WEBHOOK) { + FS_BOT_WEBHOOK = process.env.FS_BOT_WEBHOOK; +} + +if (process.env.FS_BOT_SECRET) { + FS_BOT_SECRET = process.env.FS_BOT_SECRET; +} + //==========================云端环境变量的判断与接收========================= async function sendNotify(text, desp, params = {}) { @@ -246,7 +262,9 @@ async function sendNotify(text, desp, params = {}) { //电子邮件 email(text, desp), // Gotify - gotifyNotify(text, desp) + gotifyNotify(text, desp), + // 飞书机器人 + feishuNotify(text, desp) ]); } @@ -885,6 +903,65 @@ function gotifyNotify(text, desp) { }); } +function feishuNotify(text, desp) { + return new Promise(resolve => { + if (FS_BOT_WEBHOOK) { + const payload = { + msg_type: 'text', + content: { + text: `${text}\n\n${desp}` + } + }; + + if (FS_BOT_SECRET) { + const crypto = require('crypto'); + const timestamp = Math.floor(Date.now() / 1000); + const signStr = `${timestamp}\n${FS_BOT_SECRET}`; + const sign = crypto + .createHmac('sha256', FS_BOT_SECRET) + .update(signStr) + .digest('base64'); + payload.timestamp = `${timestamp}`; + payload.sign = sign; + } + + send({ + method: 'POST', + url: FS_BOT_WEBHOOK, + contents: payload, + config: { + retry: false + }, + headers: { + accept: 'application/json, text/plain, */*', + 'content-type': 'application/json', + }, + success: res => { + try { + const data = JSON.parse(res.body); + if (data.code === 0) { + log.info('发送通知', '飞书机器人发送通知消息完成。'); + } else { + log.error('发送通知', `${data.msg || '飞书机器人发送通知异常'}`); + } + } catch (e) { + log.error('发送通知', e); + } finally { + resolve(); + } + }, + failure: err => { + log.error('发送通知', '飞书机器人发送通知消息失败!!' + err); + resolve(); + } + }); + } else { + log.debug('发送通知', '您未提供飞书机器人推送所需的FS_BOT_WEBHOOK,取消飞书机器人推送消息通知'); + resolve(); + } + }); +} + async function qmsg(text, desp) { return new Promise(resolve => { if (QMSG_KEY) {