Files
openclaw/extensions/feishu/src/monitor.ts
2026-03-04 02:35:12 -05:00

96 lines
2.7 KiB
TypeScript

import type { ClawdbotConfig, RuntimeEnv } from "openclaw/plugin-sdk/feishu";
import { listEnabledFeishuAccounts, resolveFeishuAccount } from "./accounts.js";
import {
monitorSingleAccount,
resolveReactionSyntheticEvent,
type FeishuReactionCreatedEvent,
} from "./monitor.account.js";
import { fetchBotOpenIdForMonitor } from "./monitor.startup.js";
import {
clearFeishuWebhookRateLimitStateForTest,
getFeishuWebhookRateLimitStateSizeForTest,
isWebhookRateLimitedForTest,
stopFeishuMonitorState,
} from "./monitor.state.js";
export type MonitorFeishuOpts = {
config?: ClawdbotConfig;
runtime?: RuntimeEnv;
abortSignal?: AbortSignal;
accountId?: string;
};
export {
clearFeishuWebhookRateLimitStateForTest,
getFeishuWebhookRateLimitStateSizeForTest,
isWebhookRateLimitedForTest,
resolveReactionSyntheticEvent,
};
export type { FeishuReactionCreatedEvent };
export async function monitorFeishuProvider(opts: MonitorFeishuOpts = {}): Promise<void> {
const cfg = opts.config;
if (!cfg) {
throw new Error("Config is required for Feishu monitor");
}
const log = opts.runtime?.log ?? console.log;
if (opts.accountId) {
const account = resolveFeishuAccount({ cfg, accountId: opts.accountId });
if (!account.enabled || !account.configured) {
throw new Error(`Feishu account "${opts.accountId}" not configured or disabled`);
}
return monitorSingleAccount({
cfg,
account,
runtime: opts.runtime,
abortSignal: opts.abortSignal,
});
}
const accounts = listEnabledFeishuAccounts(cfg);
if (accounts.length === 0) {
throw new Error("No enabled Feishu accounts configured");
}
log(
`feishu: starting ${accounts.length} account(s): ${accounts.map((a) => a.accountId).join(", ")}`,
);
const monitorPromises: Promise<void>[] = [];
for (const account of accounts) {
if (opts.abortSignal?.aborted) {
log("feishu: abort signal received during startup preflight; stopping startup");
break;
}
// Probe sequentially so large multi-account startups do not burst Feishu's bot-info endpoint.
const botOpenId = await fetchBotOpenIdForMonitor(account, {
runtime: opts.runtime,
abortSignal: opts.abortSignal,
});
if (opts.abortSignal?.aborted) {
log("feishu: abort signal received during startup preflight; stopping startup");
break;
}
monitorPromises.push(
monitorSingleAccount({
cfg,
account,
runtime: opts.runtime,
abortSignal: opts.abortSignal,
botOpenIdSource: { kind: "prefetched", botOpenId },
}),
);
}
await Promise.all(monitorPromises);
}
export function stopFeishuMonitor(accountId?: string): void {
stopFeishuMonitorState(accountId);
}