From 98077d7ce1901b402331d9ea5065bf15bfacd021 Mon Sep 17 00:00:00 2001 From: qwq Date: Fri, 24 Jul 2026 15:58:06 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E4=B8=BA=E9=95=BF=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 20 +++++++++--------- package.json | 1 + src/index.js | 11 +++++++--- src/routes/feishu-event.js | 1 + src/services/feishu-ws.js | 43 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+), 13 deletions(-) create mode 100644 src/services/feishu-ws.js diff --git a/.env.example b/.env.example index 1d35fe6..72bff36 100644 --- a/.env.example +++ b/.env.example @@ -19,25 +19,25 @@ FEISHU_APPROVAL_GROUP_PERM=approval-code-group-perm FEISHU_ALERT_WEBHOOK=https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxx # ===== 群晖 NAS 配置 ===== -SYNOLOGY_HOST=https://192.168.1.100:5001 -SYNOLOGY_USERNAME=admin -SYNOLOGY_PASSWORD=your-nas-password +SYNOLOGY_HOST=https://10.2.3.40:5001 +SYNOLOGY_USERNAME=qwq +SYNOLOGY_PASSWORD=:e7P6ZaxwU9Uv8R # 是否跳过TLS证书验证(自签证书时设为true) SYNOLOGY_SKIP_TLS=true # ===== JumpServer 配置 ===== -JUMPSERVER_HOST=https://jumpserver.yourcompany.com -JUMPSERVER_KEY_ID=your-key-id -JUMPSERVER_KEY_SECRET=your-key-secret +JUMPSERVER_HOST=http://10.2.3.41 +JUMPSERVER_KEY_ID=912c725a-145b-4ee9-8eb8-4dc33913349b +JUMPSERVER_KEY_SECRET=O4XnRa6ustUV7A4sU6KWaH8yAs3TXtxzLcTa # ic1 资产的 asset_id(在JumpServer控制台查看) -JUMPSERVER_ASSET_IC1=asset-id-of-ic1 +JUMPSERVER_ASSET_IC1=c37d2b6d-3c4f-4d24-8792-40f3db2be54e # 系统用户(用于连接ic1的账号) JUMPSERVER_SYSTEM_USER=root # ===== Nextcloud 配置 ===== -NEXTCLOUD_HOST=https://nextcloud.yourcompany.com -NEXTCLOUD_USERNAME=automation -NEXTCLOUD_PASSWORD=your-nextcloud-password +NEXTCLOUD_HOST=http://10.2.3.137:28080 +NEXTCLOUD_USERNAME=qwq +NEXTCLOUD_PASSWORD=03451420 # 共享默认权限(1=读, 15=读写删, 17=读+分享) NEXTCLOUD_SHARE_PERMISSIONS=1 diff --git a/package.json b/package.json index a70cf88..6fea8e6 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "migrate": "node src/db/migrate.js" }, "dependencies": { + "@larksuiteoapi/node-sdk": "^1.28.0", "express": "^4.18.2", "axios": "^1.6.0", "better-sqlite3": "^9.4.3", diff --git a/src/index.js b/src/index.js index c355e9d..b9093f8 100644 --- a/src/index.js +++ b/src/index.js @@ -2,6 +2,8 @@ const app = require('./server'); const config = require('./config'); const logger = require('./utils/logger'); const synology = require('./services/synology'); +const { startWsClient, setEventHandler } = require('./services/feishu-ws'); +const { processEvent } = require('./routes/feishu-event'); async function start() { logger.info('=== 文件传输自动化系统启动 ==='); @@ -15,12 +17,15 @@ async function start() { logger.warn(`群晖 NAS 连接失败(将在首次使用时重试): ${e.message}`); } - // 启动 HTTP 服务 + // 启动飞书 WebSocket 长连接(无需公网IP,主动连出去接收事件) + setEventHandler(processEvent); + startWsClient(); + + // HTTP 服务(管理后台 + 健康检查) app.listen(config.port, () => { - logger.info(`服务已启动: http://0.0.0.0:${config.port}`); logger.info(`管理后台: http://0.0.0.0:${config.port}/admin`); - logger.info(`飞书事件回调: http://0.0.0.0:${config.port}/api/feishu/event`); logger.info(`健康检查: http://0.0.0.0:${config.port}/health`); + logger.info('飞书事件: WebSocket 长连接模式(无需配置回调URL)'); }); } diff --git a/src/routes/feishu-event.js b/src/routes/feishu-event.js index 6fc823c..978f728 100644 --- a/src/routes/feishu-event.js +++ b/src/routes/feishu-event.js @@ -208,3 +208,4 @@ async function processGroupPermission(approvalCode, instanceId) { } module.exports = router; +module.exports.processEvent = processEvent; diff --git a/src/services/feishu-ws.js b/src/services/feishu-ws.js new file mode 100644 index 0000000..78ff7d0 --- /dev/null +++ b/src/services/feishu-ws.js @@ -0,0 +1,43 @@ +const lark = require('@larksuiteoapi/node-sdk'); +const config = require('../config'); +const logger = require('../utils/logger'); + +let eventHandler = null; + +function setEventHandler(handler) { + eventHandler = handler; +} + +/** + * 启动飞书 WebSocket 长连接 + * 无需公网IP,主动连接飞书服务器接收事件 + */ +function startWsClient() { + const wsClient = new lark.WSClient({ + appId: config.feishu.appId, + appSecret: config.feishu.appSecret, + loggerLevel: lark.LoggerLevel.info, + }); + + wsClient.start({ + eventDispatcher: new lark.EventDispatcher({}).register({ + 'approval_instance': async (data) => { + logger.info('[飞书WS] 收到审批事件:', JSON.stringify(data).substring(0, 200)); + if (eventHandler) { + try { + await eventHandler({ + header: { event_type: 'approval_instance' }, + event: data, + }); + } catch (err) { + logger.error(`[飞书WS] 事件处理失败: ${err.message}`); + } + } + }, + }), + }); + + logger.info('[飞书WS] 长连接已启动,等待审批事件...'); +} + +module.exports = { startWsClient, setEventHandler };