diff --git a/extensions/feishu/src/monitor.ts b/extensions/feishu/src/monitor.ts index ce782cb615c..e71a4316b4c 100644 --- a/extensions/feishu/src/monitor.ts +++ b/extensions/feishu/src/monitor.ts @@ -335,6 +335,7 @@ type MonitorAccountParams = { runtime?: RuntimeEnv; abortSignal?: AbortSignal; botOpenId?: string; + botOpenIdPrefetched?: boolean; }; /** @@ -346,7 +347,7 @@ async function monitorSingleAccount(params: MonitorAccountParams): Promise const log = runtime?.log ?? console.log; // Fetch bot open_id - const botOpenId = params.botOpenId ?? (await fetchBotOpenId(account)); + const botOpenId = params.botOpenIdPrefetched ? params.botOpenId : await fetchBotOpenId(account); botOpenIds.set(accountId, botOpenId ?? ""); log(`feishu[${accountId}]: bot open_id resolved: ${botOpenId ?? "unknown"}`); @@ -558,6 +559,7 @@ export async function monitorFeishuProvider(opts: MonitorFeishuOpts = {}): Promi runtime: opts.runtime, abortSignal: opts.abortSignal, botOpenId, + botOpenIdPrefetched: true, }), ); } diff --git a/extensions/feishu/src/monitor.webhook-security.test.ts b/extensions/feishu/src/monitor.webhook-security.test.ts index 53bb7c739d4..586cc465e93 100644 --- a/extensions/feishu/src/monitor.webhook-security.test.ts +++ b/extensions/feishu/src/monitor.webhook-security.test.ts @@ -263,4 +263,40 @@ describe("Feishu webhook security hardening", () => { await monitorPromise; } }); + + it("does not refetch bot info after a failed sequential preflight", async () => { + const started: string[] = []; + let releaseBetaProbe!: () => void; + const betaProbeReleased = new Promise((resolve) => { + releaseBetaProbe = () => resolve(); + }); + + probeFeishuMock.mockImplementation(async (account: { accountId: string }) => { + started.push(account.accountId); + if (account.accountId === "alpha") { + return { ok: false }; + } + await betaProbeReleased; + return { ok: true, botOpenId: `bot_${account.accountId}` }; + }); + + const abortController = new AbortController(); + const monitorPromise = monitorFeishuProvider({ + config: buildMultiAccountWebsocketConfig(["alpha", "beta"]), + abortSignal: abortController.signal, + }); + + try { + await Promise.resolve(); + await Promise.resolve(); + await Promise.resolve(); + + expect(started).toEqual(["alpha", "beta"]); + expect(started.filter((accountId) => accountId === "alpha")).toHaveLength(1); + } finally { + releaseBetaProbe(); + abortController.abort(); + await monitorPromise; + } + }); });