mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-23 15:11:42 +00:00
fix(feishu): tolerate missing webhook defaults in older plugin-sdk (openclaw#31639) thanks @liuxiaopai-ai
Verified: - pnpm test extensions/feishu/src/monitor.state.defaults.test.ts - pnpm exec vitest run extensions/feishu/src/monitor.state.defaults.test.ts - pnpm exec oxfmt --check extensions/feishu/src/monitor.state.ts extensions/feishu/src/monitor.state.defaults.test.ts CHANGELOG.md - CI note: non-required check "check" failed on unrelated TS errors outside this PR scope. Co-authored-by: liuxiaopai-ai <73659136+liuxiaopai-ai@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
46
extensions/feishu/src/monitor.state.defaults.test.ts
Normal file
46
extensions/feishu/src/monitor.state.defaults.test.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
resolveFeishuWebhookAnomalyDefaultsForTest,
|
||||
resolveFeishuWebhookRateLimitDefaultsForTest,
|
||||
} from "./monitor.state.js";
|
||||
|
||||
describe("feishu monitor state defaults", () => {
|
||||
it("falls back to hard defaults when sdk defaults are missing", () => {
|
||||
expect(resolveFeishuWebhookRateLimitDefaultsForTest(undefined)).toEqual({
|
||||
windowMs: 60_000,
|
||||
maxRequests: 120,
|
||||
maxTrackedKeys: 4_096,
|
||||
});
|
||||
expect(resolveFeishuWebhookAnomalyDefaultsForTest(undefined)).toEqual({
|
||||
maxTrackedKeys: 4_096,
|
||||
ttlMs: 21_600_000,
|
||||
logEvery: 25,
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps valid sdk values and repairs invalid fields", () => {
|
||||
expect(
|
||||
resolveFeishuWebhookRateLimitDefaultsForTest({
|
||||
windowMs: 45_000,
|
||||
maxRequests: 0,
|
||||
maxTrackedKeys: -1,
|
||||
}),
|
||||
).toEqual({
|
||||
windowMs: 45_000,
|
||||
maxRequests: 120,
|
||||
maxTrackedKeys: 4_096,
|
||||
});
|
||||
|
||||
expect(
|
||||
resolveFeishuWebhookAnomalyDefaultsForTest({
|
||||
maxTrackedKeys: 2048,
|
||||
ttlMs: Number.NaN,
|
||||
logEvery: 10,
|
||||
}),
|
||||
).toEqual({
|
||||
maxTrackedKeys: 2048,
|
||||
ttlMs: 21_600_000,
|
||||
logEvery: 10,
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -4,8 +4,8 @@ import {
|
||||
createFixedWindowRateLimiter,
|
||||
createWebhookAnomalyTracker,
|
||||
type RuntimeEnv,
|
||||
WEBHOOK_ANOMALY_COUNTER_DEFAULTS,
|
||||
WEBHOOK_RATE_LIMIT_DEFAULTS,
|
||||
WEBHOOK_ANOMALY_COUNTER_DEFAULTS as WEBHOOK_ANOMALY_COUNTER_DEFAULTS_FROM_SDK,
|
||||
WEBHOOK_RATE_LIMIT_DEFAULTS as WEBHOOK_RATE_LIMIT_DEFAULTS_FROM_SDK,
|
||||
} from "openclaw/plugin-sdk";
|
||||
|
||||
export const wsClients = new Map<string, Lark.WSClient>();
|
||||
@@ -15,16 +15,92 @@ export const botOpenIds = new Map<string, string>();
|
||||
export const FEISHU_WEBHOOK_MAX_BODY_BYTES = 1024 * 1024;
|
||||
export const FEISHU_WEBHOOK_BODY_TIMEOUT_MS = 30_000;
|
||||
|
||||
type WebhookRateLimitDefaults = {
|
||||
windowMs: number;
|
||||
maxRequests: number;
|
||||
maxTrackedKeys: number;
|
||||
};
|
||||
|
||||
type WebhookAnomalyDefaults = {
|
||||
maxTrackedKeys: number;
|
||||
ttlMs: number;
|
||||
logEvery: number;
|
||||
};
|
||||
|
||||
const FEISHU_WEBHOOK_RATE_LIMIT_FALLBACK_DEFAULTS: WebhookRateLimitDefaults = {
|
||||
windowMs: 60_000,
|
||||
maxRequests: 120,
|
||||
maxTrackedKeys: 4_096,
|
||||
};
|
||||
|
||||
const FEISHU_WEBHOOK_ANOMALY_FALLBACK_DEFAULTS: WebhookAnomalyDefaults = {
|
||||
maxTrackedKeys: 4_096,
|
||||
ttlMs: 6 * 60 * 60_000,
|
||||
logEvery: 25,
|
||||
};
|
||||
|
||||
function coercePositiveInt(value: unknown, fallback: number): number {
|
||||
if (typeof value !== "number" || !Number.isFinite(value)) {
|
||||
return fallback;
|
||||
}
|
||||
const normalized = Math.floor(value);
|
||||
return normalized > 0 ? normalized : fallback;
|
||||
}
|
||||
|
||||
export function resolveFeishuWebhookRateLimitDefaultsForTest(
|
||||
defaults: unknown,
|
||||
): WebhookRateLimitDefaults {
|
||||
const resolved = defaults as Partial<WebhookRateLimitDefaults> | null | undefined;
|
||||
return {
|
||||
windowMs: coercePositiveInt(
|
||||
resolved?.windowMs,
|
||||
FEISHU_WEBHOOK_RATE_LIMIT_FALLBACK_DEFAULTS.windowMs,
|
||||
),
|
||||
maxRequests: coercePositiveInt(
|
||||
resolved?.maxRequests,
|
||||
FEISHU_WEBHOOK_RATE_LIMIT_FALLBACK_DEFAULTS.maxRequests,
|
||||
),
|
||||
maxTrackedKeys: coercePositiveInt(
|
||||
resolved?.maxTrackedKeys,
|
||||
FEISHU_WEBHOOK_RATE_LIMIT_FALLBACK_DEFAULTS.maxTrackedKeys,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
export function resolveFeishuWebhookAnomalyDefaultsForTest(
|
||||
defaults: unknown,
|
||||
): WebhookAnomalyDefaults {
|
||||
const resolved = defaults as Partial<WebhookAnomalyDefaults> | null | undefined;
|
||||
return {
|
||||
maxTrackedKeys: coercePositiveInt(
|
||||
resolved?.maxTrackedKeys,
|
||||
FEISHU_WEBHOOK_ANOMALY_FALLBACK_DEFAULTS.maxTrackedKeys,
|
||||
),
|
||||
ttlMs: coercePositiveInt(resolved?.ttlMs, FEISHU_WEBHOOK_ANOMALY_FALLBACK_DEFAULTS.ttlMs),
|
||||
logEvery: coercePositiveInt(
|
||||
resolved?.logEvery,
|
||||
FEISHU_WEBHOOK_ANOMALY_FALLBACK_DEFAULTS.logEvery,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
const feishuWebhookRateLimitDefaults = resolveFeishuWebhookRateLimitDefaultsForTest(
|
||||
WEBHOOK_RATE_LIMIT_DEFAULTS_FROM_SDK,
|
||||
);
|
||||
const feishuWebhookAnomalyDefaults = resolveFeishuWebhookAnomalyDefaultsForTest(
|
||||
WEBHOOK_ANOMALY_COUNTER_DEFAULTS_FROM_SDK,
|
||||
);
|
||||
|
||||
export const feishuWebhookRateLimiter = createFixedWindowRateLimiter({
|
||||
windowMs: WEBHOOK_RATE_LIMIT_DEFAULTS.windowMs,
|
||||
maxRequests: WEBHOOK_RATE_LIMIT_DEFAULTS.maxRequests,
|
||||
maxTrackedKeys: WEBHOOK_RATE_LIMIT_DEFAULTS.maxTrackedKeys,
|
||||
windowMs: feishuWebhookRateLimitDefaults.windowMs,
|
||||
maxRequests: feishuWebhookRateLimitDefaults.maxRequests,
|
||||
maxTrackedKeys: feishuWebhookRateLimitDefaults.maxTrackedKeys,
|
||||
});
|
||||
|
||||
const feishuWebhookAnomalyTracker = createWebhookAnomalyTracker({
|
||||
maxTrackedKeys: WEBHOOK_ANOMALY_COUNTER_DEFAULTS.maxTrackedKeys,
|
||||
ttlMs: WEBHOOK_ANOMALY_COUNTER_DEFAULTS.ttlMs,
|
||||
logEvery: WEBHOOK_ANOMALY_COUNTER_DEFAULTS.logEvery,
|
||||
maxTrackedKeys: feishuWebhookAnomalyDefaults.maxTrackedKeys,
|
||||
ttlMs: feishuWebhookAnomalyDefaults.ttlMs,
|
||||
logEvery: feishuWebhookAnomalyDefaults.logEvery,
|
||||
});
|
||||
|
||||
export function clearFeishuWebhookRateLimitStateForTest(): void {
|
||||
|
||||
Reference in New Issue
Block a user