mirror of
https://github.com/openclaw/openclaw.git
synced 2026-02-19 18:39:20 -05:00
Discord: fix bare guild ID misrouted as channel ID in parser
The channel allowlist parser matches bare numeric strings as channel IDs before checking for guild IDs, causing guild snowflakes to hit Discord's /channels/ endpoint (404). Prefix guild-only entries with 'guild:' so the parser routes them to the correct guild resolution path. Fixes both the monitor provider and onboarding wizard call sites. Adds regression tests.
This commit is contained in:
@@ -52,4 +52,62 @@ describe("resolveDiscordChannelAllowlist", () => {
|
||||
expect(res[0]?.guildId).toBe("g1");
|
||||
expect(res[0]?.channelId).toBe("123");
|
||||
});
|
||||
|
||||
it("resolves guild: prefixed id as guild (not channel)", async () => {
|
||||
const fetcher = async (url: string) => {
|
||||
if (url.endsWith("/users/@me/guilds")) {
|
||||
return jsonResponse([{ id: "111222333444555666", name: "Guild One" }]);
|
||||
}
|
||||
// Should never be called — if it is, the ID was misrouted as a channel
|
||||
if (url.includes("/channels/")) {
|
||||
throw new Error("guild id was incorrectly routed to /channels/");
|
||||
}
|
||||
return new Response("not found", { status: 404 });
|
||||
};
|
||||
|
||||
const res = await resolveDiscordChannelAllowlist({
|
||||
token: "test",
|
||||
entries: ["guild:111222333444555666"],
|
||||
fetcher,
|
||||
});
|
||||
|
||||
expect(res[0]?.resolved).toBe(true);
|
||||
expect(res[0]?.guildId).toBe("111222333444555666");
|
||||
expect(res[0]?.channelId).toBeUndefined();
|
||||
});
|
||||
|
||||
it("bare numeric guild id is misrouted as channel id (regression)", async () => {
|
||||
// Demonstrates why provider.ts must prefix guild-only entries with "guild:"
|
||||
// In reality, Discord returns 404 when a guild ID is sent to /channels/<guildId>,
|
||||
// which causes fetchDiscord to throw and the entire resolver to crash.
|
||||
const fetcher = async (url: string) => {
|
||||
if (url.endsWith("/users/@me/guilds")) {
|
||||
return jsonResponse([{ id: "999", name: "My Server" }]);
|
||||
}
|
||||
// Guild ID hitting /channels/ returns 404 — just like real Discord
|
||||
if (url.includes("/channels/")) {
|
||||
return new Response(JSON.stringify({ message: "Unknown Channel" }), { status: 404 });
|
||||
}
|
||||
return new Response("not found", { status: 404 });
|
||||
};
|
||||
|
||||
// Without the guild: prefix, a bare numeric string hits /channels/999 → 404 → throws
|
||||
await expect(
|
||||
resolveDiscordChannelAllowlist({
|
||||
token: "test",
|
||||
entries: ["999"],
|
||||
fetcher,
|
||||
}),
|
||||
).rejects.toThrow(/404/);
|
||||
|
||||
// With the guild: prefix, it correctly resolves as a guild (never hits /channels/)
|
||||
const res2 = await resolveDiscordChannelAllowlist({
|
||||
token: "test",
|
||||
entries: ["guild:999"],
|
||||
fetcher,
|
||||
});
|
||||
expect(res2[0]?.resolved).toBe(true);
|
||||
expect(res2[0]?.guildId).toBe("999");
|
||||
expect(res2[0]?.channelId).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user