diff --git a/back/data/notify.ts b/back/data/notify.ts index bf4031d3..b0899500 100644 --- a/back/data/notify.ts +++ b/back/data/notify.ts @@ -142,6 +142,7 @@ export class WebhookNotification extends NotificationBaseInfo { export class LarkNotification extends NotificationBaseInfo { public larkKey = ''; + public larkSecret = ''; } export class NtfyNotification extends NotificationBaseInfo { diff --git a/back/services/notify.ts b/back/services/notify.ts index 4f4e2ebb..934a86ed 100644 --- a/back/services/notify.ts +++ b/back/services/notify.ts @@ -550,19 +550,31 @@ export default class NotificationService { } private async lark() { - let { larkKey } = this.params; + let { larkKey, larkSecret } = this.params; if (!larkKey.startsWith('http')) { larkKey = `https://open.feishu.cn/open-apis/bot/v2/hook/${larkKey}`; } + const body: Record = { + msg_type: 'text', + content: { text: `${this.title}\n\n${this.content}` }, + }; + + // Add signature if secret is provided + if (larkSecret) { + const timestamp = Math.floor(Date.now() / 1000).toString(); + const stringToSign = `${timestamp}\n${larkSecret}`; + const hmac = crypto.createHmac('sha256', stringToSign); + const sign = hmac.digest('base64'); + body.timestamp = timestamp; + body.sign = sign; + } + try { const res = await httpClient.post(larkKey, { ...this.gotOption, - json: { - msg_type: 'text', - content: { text: `${this.title}\n\n${this.content}` }, - }, + json: body, headers: { 'Content-Type': 'application/json' }, }); if (res.StatusCode === 0 || res.code === 0) { diff --git a/sample/notify.js b/sample/notify.js index 8dfe8851..fd68bea0 100644 --- a/sample/notify.js +++ b/sample/notify.js @@ -52,6 +52,7 @@ const push_config = { DD_BOT_TOKEN: '', // 钉钉机器人的 DD_BOT_TOKEN FSKEY: '', // 飞书机器人的 FSKEY + FSSECRET: '', // 飞书机器人的 FSSECRET,对应安全设置里的签名校验密钥 // 推送到个人QQ:http://127.0.0.1/send_private_msg // 群:http://127.0.0.1/send_group_msg @@ -989,11 +990,24 @@ function aibotkNotify(text, desp) { function fsBotNotify(text, desp) { return new Promise((resolve) => { - const { FSKEY } = push_config; + const { FSKEY, FSSECRET } = push_config; if (FSKEY) { + const body = { msg_type: 'text', content: { text: `${text}\n\n${desp}` } }; + + // Add signature if secret is provided + if (FSSECRET) { + const crypto = require('crypto'); + const timestamp = Math.floor(Date.now() / 1000).toString(); + const stringToSign = `${timestamp}\n${FSSECRET}`; + const hmac = crypto.createHmac('sha256', stringToSign); + const sign = hmac.digest('base64'); + body.timestamp = timestamp; + body.sign = sign; + } + const options = { url: `https://open.feishu.cn/open-apis/bot/v2/hook/${FSKEY}`, - json: { msg_type: 'text', content: { text: `${text}\n\n${desp}` } }, + json: body, headers: { 'Content-Type': 'application/json', }, diff --git a/sample/notify.py b/sample/notify.py index 032bb97e..410ab7ae 100644 --- a/sample/notify.py +++ b/sample/notify.py @@ -49,6 +49,7 @@ push_config = { 'DD_BOT_TOKEN': '', # 钉钉机器人的 DD_BOT_TOKEN 'FSKEY': '', # 飞书机器人的 FSKEY + 'FSSECRET': '', # 飞书机器人的 FSSECRET,对应安全设置里的签名校验密钥 'GOBOT_URL': '', # go-cqhttp # 推送到个人QQ:http://127.0.0.1/send_private_msg @@ -233,6 +234,18 @@ def feishu_bot(title: str, content: str) -> None: url = f'https://open.feishu.cn/open-apis/bot/v2/hook/{push_config.get("FSKEY")}' data = {"msg_type": "text", "content": {"text": f"{title}\n\n{content}"}} + + # Add signature if secret is provided + if push_config.get("FSSECRET"): + timestamp = str(int(time.time())) + string_to_sign = f'{timestamp}\n{push_config.get("FSSECRET")}' + hmac_code = hmac.new( + string_to_sign.encode("utf-8"), digestmod=hashlib.sha256 + ).digest() + sign = base64.b64encode(hmac_code).decode("utf-8") + data["timestamp"] = timestamp + data["sign"] = sign + response = requests.post(url, data=json.dumps(data)).json() if response.get("StatusCode") == 0 or response.get("code") == 0: diff --git a/src/utils/config.ts b/src/utils/config.ts index 49eab36b..b529a7d0 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -395,6 +395,12 @@ export default { ), required: true, }, + { + label: 'larkSecret', + tip: intl.get( + '飞书群组机器人加签密钥,安全设置中开启签名校验后获得', + ), + }, ], email: [ {