From b25614f75c287f7815a662f92d5a7b967890fb3d Mon Sep 17 00:00:00 2001 From: tsingliu <410869548@qq.com> Date: Sat, 7 Feb 2026 16:44:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=BA=E5=99=A8=E4=BA=BA=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=85=B3=E9=94=AE=E8=AF=8D=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 11 ++++++++++- src/index.ts | 29 ++++++++++++++++++++++++++++- src/tools/notify.ts | 19 +++++++++++++++++-- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/.env.example b/.env.example index 2097364..aab9fbf 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,12 @@ OPENAI_API_KEY=sk-your-key-here OPENAI_BASE_URL=https://api.openai.com/v1 -OPENAI_MODEL=gpt-4o \ No newline at end of file +OPENAI_MODEL=gpt-4o + +# Notifications (Optional) +# Configure Webhook URL and Security Keyword for your IM platform +FEISHU_WEBHOOK= +FEISHU_KEYWORD= +DINGTALK_WEBHOOK= +DINGTALK_KEYWORD= +WECOM_WEBHOOK= +WECOM_KEYWORD= \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index e281dd2..303216d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -38,8 +38,11 @@ interface AppConfig { tavilyApiKey?: string; autoConfirm?: boolean; feishuWebhook?: string; + feishuKeyword?: string; dingtalkWebhook?: string; + dingtalkKeyword?: string; wecomWebhook?: string; + wecomKeyword?: string; } function loadJsonConfig(filePath: string): AppConfig { @@ -222,6 +225,12 @@ async function runSetup() { : 'Feishu Webhook (Optional):', mask: '*' }, + { + type: 'input', + name: 'feishuKeyword', + message: 'Feishu Security Keyword (Optional):', + default: currentConfig.feishuKeyword + }, { type: 'password', name: 'dingtalkWebhook', @@ -230,6 +239,12 @@ async function runSetup() { : 'DingTalk Webhook (Optional):', mask: '*' }, + { + type: 'input', + name: 'dingtalkKeyword', + message: 'DingTalk Security Keyword (Optional):', + default: currentConfig.dingtalkKeyword + }, { type: 'password', name: 'wecomWebhook', @@ -237,12 +252,21 @@ async function runSetup() { ? `WeCom Webhook (Leave empty to keep ${maskSecret(currentConfig.wecomWebhook)}):` : 'WeCom Webhook (Optional):', mask: '*' + }, + { + type: 'input', + name: 'wecomKeyword', + message: 'WeCom Security Keyword (Optional):', + default: currentConfig.wecomKeyword } ]); notifyConfig = { feishuWebhook: notifyAnswers.feishuWebhook || currentConfig.feishuWebhook, + feishuKeyword: notifyAnswers.feishuKeyword || currentConfig.feishuKeyword, dingtalkWebhook: notifyAnswers.dingtalkWebhook || currentConfig.dingtalkWebhook, - wecomWebhook: notifyAnswers.wecomWebhook || currentConfig.wecomWebhook + dingtalkKeyword: notifyAnswers.dingtalkKeyword || currentConfig.dingtalkKeyword, + wecomWebhook: notifyAnswers.wecomWebhook || currentConfig.wecomWebhook, + wecomKeyword: notifyAnswers.wecomKeyword || currentConfig.wecomKeyword }; } @@ -302,8 +326,11 @@ async function runChat(queryParts: string[], options: any) { if (process.env.SMTP_PASS) fullConfig.smtpPass = process.env.SMTP_PASS; if (process.env.TAVILY_API_KEY) fullConfig.tavilyApiKey = process.env.TAVILY_API_KEY; if (process.env.FEISHU_WEBHOOK) fullConfig.feishuWebhook = process.env.FEISHU_WEBHOOK; + if (process.env.FEISHU_KEYWORD) fullConfig.feishuKeyword = process.env.FEISHU_KEYWORD; if (process.env.DINGTALK_WEBHOOK) fullConfig.dingtalkWebhook = process.env.DINGTALK_WEBHOOK; + if (process.env.DINGTALK_KEYWORD) fullConfig.dingtalkKeyword = process.env.DINGTALK_KEYWORD; if (process.env.WECOM_WEBHOOK) fullConfig.wecomWebhook = process.env.WECOM_WEBHOOK; + if (process.env.WECOM_KEYWORD) fullConfig.wecomKeyword = process.env.WECOM_KEYWORD; if (!apiKey) { console.log(chalk.yellow("API Key not found.")); diff --git a/src/tools/notify.ts b/src/tools/notify.ts index c159ec7..a137f91 100644 --- a/src/tools/notify.ts +++ b/src/tools/notify.ts @@ -2,7 +2,11 @@ import { ToolModule } from './interface.js'; export const NotifyTool: ToolModule = { name: "Group Bot Notification", - configKeys: ["feishuWebhook", "dingtalkWebhook", "wecomWebhook"], + configKeys: [ + "feishuWebhook", "feishuKeyword", + "dingtalkWebhook", "dingtalkKeyword", + "wecomWebhook", "wecomKeyword" + ], definition: { type: "function", function: { @@ -26,14 +30,23 @@ export const NotifyTool: ToolModule = { } }, handler: async (args: any, config: any) => { - const { platform, content } = args; + let { platform, content } = args; let webhookUrl = ''; let payload = {}; + // Helper to ensure security keyword is present + const ensureKeyword = (envKey: string, configKey: string) => { + const keyword = config[configKey] || process.env[envKey]; + if (keyword && !content.includes(keyword)) { + content = `[${keyword}] ${content}`; + } + }; + // 1. Determine Webhook URL and Payload Format switch (platform) { case 'feishu': webhookUrl = config.feishuWebhook || process.env.FEISHU_WEBHOOK; + ensureKeyword('FEISHU_KEYWORD', 'feishuKeyword'); if (!webhookUrl) return "Error: Feishu Webhook URL is not configured."; payload = { msg_type: "text", @@ -43,6 +56,7 @@ export const NotifyTool: ToolModule = { case 'dingtalk': webhookUrl = config.dingtalkWebhook || process.env.DINGTALK_WEBHOOK; + ensureKeyword('DINGTALK_KEYWORD', 'dingtalkKeyword'); if (!webhookUrl) return "Error: DingTalk Webhook URL is not configured."; payload = { msgtype: "text", @@ -52,6 +66,7 @@ export const NotifyTool: ToolModule = { case 'wecom': webhookUrl = config.wecomWebhook || process.env.WECOM_WEBHOOK; + ensureKeyword('WECOM_KEYWORD', 'wecomKeyword'); if (!webhookUrl) return "Error: WeCom Webhook URL is not configured."; payload = { msgtype: "text",