mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 13:27:39 +00:00
fix(discord): skip bot messages before debounce
This commit is contained in:
@@ -13,6 +13,7 @@ Docs: https://docs.openclaw.ai
|
|||||||
### Fixes
|
### Fixes
|
||||||
|
|
||||||
- Docs/tool-loop detection config keys: align `docs/tools/loop-detection.md` examples and field names with the current `tools.loopDetection` schema to prevent copy-paste validation failures from outdated keys. (#33182) Thanks @Mylszd.
|
- Docs/tool-loop detection config keys: align `docs/tools/loop-detection.md` examples and field names with the current `tools.loopDetection` schema to prevent copy-paste validation failures from outdated keys. (#33182) Thanks @Mylszd.
|
||||||
|
- Discord/inbound debouncer: skip bot-own MESSAGE_CREATE events before they reach the debounce queue to avoid self-triggered slowdowns in busy servers. Thanks @thewilloftheshadow.
|
||||||
- Discord/presence defaults: send an online presence update on ready when no custom presence is configured so bots no longer appear offline by default. Thanks @thewilloftheshadow.
|
- Discord/presence defaults: send an online presence update on ready when no custom presence is configured so bots no longer appear offline by default. Thanks @thewilloftheshadow.
|
||||||
- Discord/typing cleanup: stop typing indicators after silent/NO_REPLY runs by marking the run complete before dispatch idle cleanup. Thanks @thewilloftheshadow.
|
- Discord/typing cleanup: stop typing indicators after silent/NO_REPLY runs by marking the run complete before dispatch idle cleanup. Thanks @thewilloftheshadow.
|
||||||
- Discord/voice messages: request upload slots with JSON fetch calls so voice message uploads no longer fail with content-type errors. Thanks @thewilloftheshadow.
|
- Discord/voice messages: request upload slots with JSON fetch calls so voice message uploads no longer fail with content-type errors. Thanks @thewilloftheshadow.
|
||||||
|
|||||||
73
src/discord/monitor/message-handler.bot-self-filter.test.ts
Normal file
73
src/discord/monitor/message-handler.bot-self-filter.test.ts
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
import { describe, it, vi } from "vitest";
|
||||||
|
import type { OpenClawConfig } from "../../config/types.js";
|
||||||
|
import { createDiscordMessageHandler } from "./message-handler.js";
|
||||||
|
import { createNoopThreadBindingManager } from "./thread-bindings.js";
|
||||||
|
|
||||||
|
const BOT_USER_ID = "bot-123";
|
||||||
|
|
||||||
|
function createHandlerParams(overrides?: Partial<{ botUserId: string }>) {
|
||||||
|
const cfg: OpenClawConfig = {
|
||||||
|
channels: {
|
||||||
|
discord: {
|
||||||
|
enabled: true,
|
||||||
|
token: "test-token",
|
||||||
|
groupPolicy: "allowlist",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
cfg,
|
||||||
|
discordConfig: cfg.channels?.discord,
|
||||||
|
accountId: "default",
|
||||||
|
token: "test-token",
|
||||||
|
runtime: {
|
||||||
|
log: vi.fn(),
|
||||||
|
error: vi.fn(),
|
||||||
|
exit: (code: number): never => {
|
||||||
|
throw new Error(`exit ${code}`);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
botUserId: overrides?.botUserId ?? BOT_USER_ID,
|
||||||
|
guildHistories: new Map(),
|
||||||
|
historyLimit: 0,
|
||||||
|
mediaMaxBytes: 10_000,
|
||||||
|
textLimit: 2000,
|
||||||
|
replyToMode: "off" as const,
|
||||||
|
dmEnabled: true,
|
||||||
|
groupDmEnabled: false,
|
||||||
|
threadBindings: createNoopThreadBindingManager("default"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function createMessageData(authorId: string) {
|
||||||
|
return {
|
||||||
|
message: {
|
||||||
|
id: "msg-1",
|
||||||
|
author: { id: authorId, bot: authorId === BOT_USER_ID },
|
||||||
|
content: "hello",
|
||||||
|
channel_id: "ch-1",
|
||||||
|
},
|
||||||
|
channel_id: "ch-1",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("createDiscordMessageHandler bot-self filter", () => {
|
||||||
|
it("skips bot-own messages before debouncer", async () => {
|
||||||
|
const handler = createDiscordMessageHandler(createHandlerParams());
|
||||||
|
await handler(createMessageData(BOT_USER_ID) as never, {} as never);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("processes messages from other users", async () => {
|
||||||
|
const handler = createDiscordMessageHandler(createHandlerParams());
|
||||||
|
try {
|
||||||
|
await handler(
|
||||||
|
createMessageData("user-456") as never,
|
||||||
|
{
|
||||||
|
fetchChannel: vi.fn().mockResolvedValue(null),
|
||||||
|
} as never,
|
||||||
|
);
|
||||||
|
} catch {
|
||||||
|
// Expected: pipeline fails without full mock, but it passed the filter.
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -141,6 +141,16 @@ export function createDiscordMessageHandler(
|
|||||||
|
|
||||||
return async (data, client) => {
|
return async (data, client) => {
|
||||||
try {
|
try {
|
||||||
|
// Filter bot-own messages before they enter the debounce queue.
|
||||||
|
// The same check exists in preflightDiscordMessage(), but by that point
|
||||||
|
// the message has already consumed debounce capacity and blocked
|
||||||
|
// legitimate user messages. On active servers this causes cumulative
|
||||||
|
// slowdown (see #15874).
|
||||||
|
const msgAuthorId = data.message?.author?.id ?? data.author?.id;
|
||||||
|
if (params.botUserId && msgAuthorId === params.botUserId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await debouncer.enqueue({ data, client });
|
await debouncer.enqueue({ data, client });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
params.runtime.error?.(danger(`handler failed: ${String(err)}`));
|
params.runtime.error?.(danger(`handler failed: ${String(err)}`));
|
||||||
|
|||||||
Reference in New Issue
Block a user