"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.monitorWecomProvider = monitorWecomProvider; var _index = require("./config/index.js"); var _monitor = require("./monitor.js"); var _wsAdapter = require("./ws-adapter.js"); var _constants = require("./types/constants.js"); const accountRouteRegistry = new Map(); function logRegisteredRouteSummary( ctx, preferredOrder) { const seen = new Set(); const orderedAccountIds = [ ...preferredOrder.filter((accountId) => accountRouteRegistry.has(accountId)), ...Array.from(accountRouteRegistry.keys()). filter((accountId) => !seen.has(accountId)). sort((a, b) => a.localeCompare(b))]. filter((accountId) => { if (seen.has(accountId)) return false; seen.add(accountId); return true; }); const entries = orderedAccountIds. map((accountId) => { const routes = accountRouteRegistry.get(accountId); if (!routes) return undefined; const botText = routes.botPaths.length > 0 ? routes.botPaths.join(", ") : "未启用"; const agentText = routes.agentPaths.length > 0 ? routes.agentPaths.join(", ") : "未启用"; return `accountId=${accountId}(Bot: ${botText};Agent: ${agentText})`; }). filter((entry) => Boolean(entry)); const summary = entries.length > 0 ? entries.join("; ") : "无"; ctx.log?.info(`[${ctx.account.accountId}] 已注册账号路由汇总:${summary}`); } function resolveExpectedRouteSummaryAccountIds(cfg) { return (0, _index.listWecomAccountIds)(cfg). filter((accountId) => { const conflict = (0, _index.resolveWecomAccountConflict)({ cfg, accountId }); if (conflict) return false; const account = (0, _index.resolveWecomAccount)({ cfg, accountId }); if (!account.enabled || !account.configured) return false; return Boolean(account.bot?.configured || account.agent?.configured); }). sort((a, b) => a.localeCompare(b)); } function waitForAbortSignal(abortSignal) { if (abortSignal.aborted) { return Promise.resolve(); } return new Promise((resolve) => { const onAbort = () => { abortSignal.removeEventListener("abort", onAbort); resolve(); }; abortSignal.addEventListener("abort", onAbort, { once: true }); }); } function uniquePaths(paths) { return Array.from(new Set(paths.map((path) => path.trim()).filter(Boolean))); } function resolveBotRegistrationPaths(params) { if (params.matrixMode) { return uniquePaths([ `${_constants.WEBHOOK_PATHS.BOT_PLUGIN}/${params.accountId}`, `${_constants.WEBHOOK_PATHS.BOT_ALT}/${params.accountId}`, // 兼容老路径:不带 accountId 后缀,签名验证会自动匹配到正确账号 _constants.WEBHOOK_PATHS.BOT_PLUGIN, _constants.WEBHOOK_PATHS.BOT, _constants.WEBHOOK_PATHS.BOT_ALT] ); } return uniquePaths([_constants.WEBHOOK_PATHS.BOT_PLUGIN, _constants.WEBHOOK_PATHS.BOT, _constants.WEBHOOK_PATHS.BOT_ALT]); } function resolveAgentRegistrationPaths(params) { if (params.matrixMode) { return uniquePaths([ `${_constants.WEBHOOK_PATHS.AGENT_PLUGIN}/${params.accountId}`, `${_constants.WEBHOOK_PATHS.AGENT}/${params.accountId}`, // 兼容老路径 _constants.WEBHOOK_PATHS.AGENT_PLUGIN, _constants.WEBHOOK_PATHS.AGENT] ); } return uniquePaths([_constants.WEBHOOK_PATHS.AGENT_PLUGIN, _constants.WEBHOOK_PATHS.AGENT]); } /** * Keeps WeCom webhook targets registered for the account lifecycle. * The promise only settles after gateway abort/reload signals shutdown. */ async function monitorWecomProvider( ctx) { const account = ctx.account; const cfg = ctx.cfg; const expectedRouteSummaryAccountIds = resolveExpectedRouteSummaryAccountIds(cfg); const conflict = (0, _index.resolveWecomAccountConflict)({ cfg, accountId: account.accountId }); if (conflict) { ctx.setStatus({ accountId: account.accountId, running: false, configured: false, lastError: conflict.message }); throw new Error(conflict.message); } const mode = (0, _index.detectMode)(cfg.channels?.wecom); const matrixMode = mode === "matrix"; const bot = account.bot; const agent = account.agent; const botConfigured = Boolean(bot?.configured); const agentConfigured = Boolean(agent?.configured); if (mode === "legacy" && (botConfigured || agentConfigured)) { if (agentConfigured && !botConfigured) { ctx.log?.warn( `[${account.accountId}] 检测到仍在使用单 Agent 兼容模式。建议尽快升级为多账号模式:` + `将 channels.wecom.agent 迁移到 channels.wecom.accounts..agent,` + `并设置 channels.wecom.defaultAccount。` ); } else { ctx.log?.warn( `[${account.accountId}] 检测到仍在使用单账号兼容模式。建议尽快升级为多账号模式:` + `将 channels.wecom.bot/agent 迁移到 channels.wecom.accounts..bot/agent,` + `并设置 channels.wecom.defaultAccount。` ); } } if (!botConfigured && !agentConfigured) { ctx.log?.warn(`[${account.accountId}] wecom not configured; channel is idle`); ctx.setStatus({ accountId: account.accountId, running: false, configured: false }); await waitForAbortSignal(ctx.abortSignal); return; } const unregisters = []; const botPaths = []; const agentPaths = []; try { if (bot && botConfigured) { const connectionMode = bot.connectionMode ?? 'webhook'; if (connectionMode === 'websocket') { // 长链接模式:启动 WSClient unregisters.push( (0, _wsAdapter.startWsClient)({ accountId: account.accountId, botId: bot.botId, secret: bot.secret, account: bot, config: cfg, runtime: ctx.runtime, core: {}, statusSink: (patch) => ctx.setStatus({ accountId: ctx.accountId, ...patch }), welcomeText: bot.config.welcomeText, network: bot.network }) ); botPaths.push(`ws://${account.accountId}`); ctx.log?.info(`[${account.accountId}] wecom bot websocket client started (botId=${bot.botId})`); } else { // Webhook 模式:注册 HTTP 路径(现有逻辑不变) const paths = resolveBotRegistrationPaths({ accountId: account.accountId, matrixMode }); for (const path of paths) { unregisters.push( (0, _monitor.registerWecomWebhookTarget)({ account: bot, config: cfg, runtime: ctx.runtime, core: {}, path, statusSink: (patch) => ctx.setStatus({ accountId: ctx.accountId, ...patch }) }) ); } botPaths.push(...paths); ctx.log?.info(`[${account.accountId}] wecom bot webhook registered at ${paths.join(", ")}`); } } if (agent && agentConfigured) { const paths = resolveAgentRegistrationPaths({ accountId: account.accountId, matrixMode }); for (const path of paths) { unregisters.push( (0, _monitor.registerAgentWebhookTarget)({ agent, config: cfg, runtime: ctx.runtime, path }) ); } agentPaths.push(...paths); ctx.log?.info(`[${account.accountId}] wecom agent webhook registered at ${paths.join(", ")}`); } accountRouteRegistry.set(account.accountId, { botPaths, agentPaths }); const shouldLogSummary = expectedRouteSummaryAccountIds.length <= 1 || expectedRouteSummaryAccountIds.every((accountId) => accountRouteRegistry.has(accountId)); if (shouldLogSummary) { logRegisteredRouteSummary(ctx, expectedRouteSummaryAccountIds); } ctx.setStatus({ accountId: account.accountId, running: true, configured: true, webhookPath: botConfigured ? botPaths[0] ?? _constants.WEBHOOK_PATHS.BOT_PLUGIN : agentPaths[0] ?? _constants.WEBHOOK_PATHS.AGENT_PLUGIN, lastStartAt: Date.now() }); await waitForAbortSignal(ctx.abortSignal); } finally { for (const unregister of unregisters) { unregister(); } accountRouteRegistry.delete(account.accountId); ctx.setStatus({ accountId: account.accountId, running: false, lastStopAt: Date.now() }); } } /* v9-fa87656ec10070e1 */