mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-10 01:23:29 +00:00
refactor(discord): dedupe preflight test builders
This commit is contained in:
@@ -27,6 +27,13 @@ type DiscordConfig = NonNullable<
|
|||||||
type DiscordMessageEvent = import("./listeners.js").DiscordMessageEvent;
|
type DiscordMessageEvent = import("./listeners.js").DiscordMessageEvent;
|
||||||
type DiscordClient = import("@buape/carbon").Client;
|
type DiscordClient = import("@buape/carbon").Client;
|
||||||
|
|
||||||
|
const DEFAULT_CFG = {
|
||||||
|
session: {
|
||||||
|
mainKey: "main",
|
||||||
|
scope: "per-sender",
|
||||||
|
},
|
||||||
|
} as import("../../config/config.js").OpenClawConfig;
|
||||||
|
|
||||||
function createThreadBinding(
|
function createThreadBinding(
|
||||||
overrides?: Partial<
|
overrides?: Partial<
|
||||||
import("../../infra/outbound/session-binding-service.js").SessionBindingRecord
|
import("../../infra/outbound/session-binding-service.js").SessionBindingRecord
|
||||||
@@ -82,6 +89,85 @@ function createPreflightArgs(params: {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createGuildTextClient(channelId: string): DiscordClient {
|
||||||
|
return {
|
||||||
|
fetchChannel: async (id: string) => {
|
||||||
|
if (id === channelId) {
|
||||||
|
return {
|
||||||
|
id: channelId,
|
||||||
|
type: ChannelType.GuildText,
|
||||||
|
name: "general",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
} as unknown as DiscordClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createThreadClient(params: { threadId: string; parentId: string }): DiscordClient {
|
||||||
|
return {
|
||||||
|
fetchChannel: async (channelId: string) => {
|
||||||
|
if (channelId === params.threadId) {
|
||||||
|
return {
|
||||||
|
id: params.threadId,
|
||||||
|
type: ChannelType.PublicThread,
|
||||||
|
name: "focus",
|
||||||
|
parentId: params.parentId,
|
||||||
|
ownerId: "owner-1",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (channelId === params.parentId) {
|
||||||
|
return {
|
||||||
|
id: params.parentId,
|
||||||
|
type: ChannelType.GuildText,
|
||||||
|
name: "general",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
} as unknown as DiscordClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createGuildEvent(params: {
|
||||||
|
channelId: string;
|
||||||
|
guildId: string;
|
||||||
|
author: import("@buape/carbon").Message["author"];
|
||||||
|
message: import("@buape/carbon").Message;
|
||||||
|
}): DiscordMessageEvent {
|
||||||
|
return {
|
||||||
|
channel_id: params.channelId,
|
||||||
|
guild_id: params.guildId,
|
||||||
|
guild: {
|
||||||
|
id: params.guildId,
|
||||||
|
name: "Guild One",
|
||||||
|
},
|
||||||
|
author: params.author,
|
||||||
|
message: params.message,
|
||||||
|
} as unknown as DiscordMessageEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createMessage(params: {
|
||||||
|
id: string;
|
||||||
|
channelId: string;
|
||||||
|
content: string;
|
||||||
|
author: import("@buape/carbon").Message["author"];
|
||||||
|
mentionedUsers?: Array<{ id: string }>;
|
||||||
|
mentionedEveryone?: boolean;
|
||||||
|
attachments?: import("@buape/carbon").Message["attachments"];
|
||||||
|
}): import("@buape/carbon").Message {
|
||||||
|
return {
|
||||||
|
id: params.id,
|
||||||
|
content: params.content,
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
channelId: params.channelId,
|
||||||
|
attachments: params.attachments ?? [],
|
||||||
|
mentionedUsers: params.mentionedUsers ?? [],
|
||||||
|
mentionedRoles: [],
|
||||||
|
mentionedEveryone: params.mentionedEveryone ?? false,
|
||||||
|
author: params.author,
|
||||||
|
} as unknown as import("@buape/carbon").Message;
|
||||||
|
}
|
||||||
|
|
||||||
describe("resolvePreflightMentionRequirement", () => {
|
describe("resolvePreflightMentionRequirement", () => {
|
||||||
it("requires mention when config requires mention and thread is not bound", () => {
|
it("requires mention when config requires mention and thread is not bound", () => {
|
||||||
expect(
|
expect(
|
||||||
@@ -124,81 +210,36 @@ describe("preflightDiscordMessage", () => {
|
|||||||
});
|
});
|
||||||
const threadId = "thread-system-1";
|
const threadId = "thread-system-1";
|
||||||
const parentId = "channel-parent-1";
|
const parentId = "channel-parent-1";
|
||||||
const client = {
|
const client = createThreadClient({ threadId, parentId });
|
||||||
fetchChannel: async (channelId: string) => {
|
const message = createMessage({
|
||||||
if (channelId === threadId) {
|
|
||||||
return {
|
|
||||||
id: threadId,
|
|
||||||
type: ChannelType.PublicThread,
|
|
||||||
name: "focus",
|
|
||||||
parentId,
|
|
||||||
ownerId: "owner-1",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (channelId === parentId) {
|
|
||||||
return {
|
|
||||||
id: parentId,
|
|
||||||
type: ChannelType.GuildText,
|
|
||||||
name: "general",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
} as unknown as import("@buape/carbon").Client;
|
|
||||||
const message = {
|
|
||||||
id: "m-system-1",
|
id: "m-system-1",
|
||||||
|
channelId: threadId,
|
||||||
content:
|
content:
|
||||||
"⚙️ codex-acp session active (auto-unfocus in 24h). Messages here go directly to this session.",
|
"⚙️ codex-acp session active (auto-unfocus in 24h). Messages here go directly to this session.",
|
||||||
timestamp: new Date().toISOString(),
|
|
||||||
channelId: threadId,
|
|
||||||
attachments: [],
|
|
||||||
mentionedUsers: [],
|
|
||||||
mentionedRoles: [],
|
|
||||||
mentionedEveryone: false,
|
|
||||||
author: {
|
author: {
|
||||||
id: "relay-bot-1",
|
id: "relay-bot-1",
|
||||||
bot: true,
|
bot: true,
|
||||||
username: "OpenClaw",
|
username: "OpenClaw",
|
||||||
},
|
},
|
||||||
} as unknown as import("@buape/carbon").Message;
|
});
|
||||||
|
|
||||||
const result = await preflightDiscordMessage({
|
const result = await preflightDiscordMessage({
|
||||||
cfg: {
|
...createPreflightArgs({
|
||||||
session: {
|
cfg: DEFAULT_CFG,
|
||||||
mainKey: "main",
|
discordConfig: {
|
||||||
scope: "per-sender",
|
allowBots: true,
|
||||||
},
|
} as DiscordConfig,
|
||||||
} as import("../../config/config.js").OpenClawConfig,
|
data: createGuildEvent({
|
||||||
discordConfig: {
|
channelId: threadId,
|
||||||
allowBots: true,
|
guildId: "guild-1",
|
||||||
} as NonNullable<import("../../config/config.js").OpenClawConfig["channels"]>["discord"],
|
author: message.author,
|
||||||
accountId: "default",
|
message,
|
||||||
token: "token",
|
}),
|
||||||
runtime: {} as import("../../runtime.js").RuntimeEnv,
|
client,
|
||||||
botUserId: "openclaw-bot",
|
}),
|
||||||
guildHistories: new Map(),
|
|
||||||
historyLimit: 0,
|
|
||||||
mediaMaxBytes: 1_000_000,
|
|
||||||
textLimit: 2_000,
|
|
||||||
replyToMode: "all",
|
|
||||||
dmEnabled: true,
|
|
||||||
groupDmEnabled: true,
|
|
||||||
ackReactionScope: "direct",
|
|
||||||
groupPolicy: "open",
|
|
||||||
threadBindings: {
|
threadBindings: {
|
||||||
getByThreadId: (id: string) => (id === threadId ? threadBinding : undefined),
|
getByThreadId: (id: string) => (id === threadId ? threadBinding : undefined),
|
||||||
} as import("./thread-bindings.js").ThreadBindingManager,
|
} as import("./thread-bindings.js").ThreadBindingManager,
|
||||||
data: {
|
|
||||||
channel_id: threadId,
|
|
||||||
guild_id: "guild-1",
|
|
||||||
guild: {
|
|
||||||
id: "guild-1",
|
|
||||||
name: "Guild One",
|
|
||||||
},
|
|
||||||
author: message.author,
|
|
||||||
message,
|
|
||||||
} as unknown as import("./listeners.js").DiscordMessageEvent,
|
|
||||||
client,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result).toBeNull();
|
expect(result).toBeNull();
|
||||||
@@ -211,42 +252,17 @@ describe("preflightDiscordMessage", () => {
|
|||||||
});
|
});
|
||||||
const threadId = "thread-bot-regular-1";
|
const threadId = "thread-bot-regular-1";
|
||||||
const parentId = "channel-parent-regular-1";
|
const parentId = "channel-parent-regular-1";
|
||||||
const client = {
|
const client = createThreadClient({ threadId, parentId });
|
||||||
fetchChannel: async (channelId: string) => {
|
const message = createMessage({
|
||||||
if (channelId === threadId) {
|
|
||||||
return {
|
|
||||||
id: threadId,
|
|
||||||
type: ChannelType.PublicThread,
|
|
||||||
name: "focus",
|
|
||||||
parentId,
|
|
||||||
ownerId: "owner-1",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (channelId === parentId) {
|
|
||||||
return {
|
|
||||||
id: parentId,
|
|
||||||
type: ChannelType.GuildText,
|
|
||||||
name: "general",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
} as unknown as import("@buape/carbon").Client;
|
|
||||||
const message = {
|
|
||||||
id: "m-bot-regular-1",
|
id: "m-bot-regular-1",
|
||||||
content: "here is tool output chunk",
|
|
||||||
timestamp: new Date().toISOString(),
|
|
||||||
channelId: threadId,
|
channelId: threadId,
|
||||||
attachments: [],
|
content: "here is tool output chunk",
|
||||||
mentionedUsers: [],
|
|
||||||
mentionedRoles: [],
|
|
||||||
mentionedEveryone: false,
|
|
||||||
author: {
|
author: {
|
||||||
id: "relay-bot-1",
|
id: "relay-bot-1",
|
||||||
bot: true,
|
bot: true,
|
||||||
username: "Relay",
|
username: "Relay",
|
||||||
},
|
},
|
||||||
} as unknown as import("@buape/carbon").Message;
|
});
|
||||||
|
|
||||||
registerSessionBindingAdapter({
|
registerSessionBindingAdapter({
|
||||||
channel: "discord",
|
channel: "discord",
|
||||||
@@ -256,42 +272,22 @@ describe("preflightDiscordMessage", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const result = await preflightDiscordMessage({
|
const result = await preflightDiscordMessage({
|
||||||
cfg: {
|
...createPreflightArgs({
|
||||||
session: {
|
cfg: DEFAULT_CFG,
|
||||||
mainKey: "main",
|
discordConfig: {
|
||||||
scope: "per-sender",
|
allowBots: true,
|
||||||
},
|
} as DiscordConfig,
|
||||||
} as import("../../config/config.js").OpenClawConfig,
|
data: createGuildEvent({
|
||||||
discordConfig: {
|
channelId: threadId,
|
||||||
allowBots: true,
|
guildId: "guild-1",
|
||||||
} as NonNullable<import("../../config/config.js").OpenClawConfig["channels"]>["discord"],
|
author: message.author,
|
||||||
accountId: "default",
|
message,
|
||||||
token: "token",
|
}),
|
||||||
runtime: {} as import("../../runtime.js").RuntimeEnv,
|
client,
|
||||||
botUserId: "openclaw-bot",
|
}),
|
||||||
guildHistories: new Map(),
|
|
||||||
historyLimit: 0,
|
|
||||||
mediaMaxBytes: 1_000_000,
|
|
||||||
textLimit: 2_000,
|
|
||||||
replyToMode: "all",
|
|
||||||
dmEnabled: true,
|
|
||||||
groupDmEnabled: true,
|
|
||||||
ackReactionScope: "direct",
|
|
||||||
groupPolicy: "open",
|
|
||||||
threadBindings: {
|
threadBindings: {
|
||||||
getByThreadId: (id: string) => (id === threadId ? threadBinding : undefined),
|
getByThreadId: (id: string) => (id === threadId ? threadBinding : undefined),
|
||||||
} as import("./thread-bindings.js").ThreadBindingManager,
|
} as import("./thread-bindings.js").ThreadBindingManager,
|
||||||
data: {
|
|
||||||
channel_id: threadId,
|
|
||||||
guild_id: "guild-1",
|
|
||||||
guild: {
|
|
||||||
id: "guild-1",
|
|
||||||
name: "Guild One",
|
|
||||||
},
|
|
||||||
author: message.author,
|
|
||||||
message,
|
|
||||||
} as unknown as import("./listeners.js").DiscordMessageEvent,
|
|
||||||
client,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result).not.toBeNull();
|
expect(result).not.toBeNull();
|
||||||
@@ -302,42 +298,17 @@ describe("preflightDiscordMessage", () => {
|
|||||||
const threadBinding = createThreadBinding();
|
const threadBinding = createThreadBinding();
|
||||||
const threadId = "thread-bot-focus";
|
const threadId = "thread-bot-focus";
|
||||||
const parentId = "channel-parent-focus";
|
const parentId = "channel-parent-focus";
|
||||||
const client = {
|
const client = createThreadClient({ threadId, parentId });
|
||||||
fetchChannel: async (channelId: string) => {
|
const message = createMessage({
|
||||||
if (channelId === threadId) {
|
|
||||||
return {
|
|
||||||
id: threadId,
|
|
||||||
type: ChannelType.PublicThread,
|
|
||||||
name: "focus",
|
|
||||||
parentId,
|
|
||||||
ownerId: "owner-1",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (channelId === parentId) {
|
|
||||||
return {
|
|
||||||
id: parentId,
|
|
||||||
type: ChannelType.GuildText,
|
|
||||||
name: "general",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
} as unknown as import("@buape/carbon").Client;
|
|
||||||
const message = {
|
|
||||||
id: "m-bot-1",
|
id: "m-bot-1",
|
||||||
content: "relay message without mention",
|
|
||||||
timestamp: new Date().toISOString(),
|
|
||||||
channelId: threadId,
|
channelId: threadId,
|
||||||
attachments: [],
|
content: "relay message without mention",
|
||||||
mentionedUsers: [],
|
|
||||||
mentionedRoles: [],
|
|
||||||
mentionedEveryone: false,
|
|
||||||
author: {
|
author: {
|
||||||
id: "relay-bot-1",
|
id: "relay-bot-1",
|
||||||
bot: true,
|
bot: true,
|
||||||
username: "Relay",
|
username: "Relay",
|
||||||
},
|
},
|
||||||
} as unknown as import("@buape/carbon").Message;
|
});
|
||||||
|
|
||||||
registerSessionBindingAdapter({
|
registerSessionBindingAdapter({
|
||||||
channel: "discord",
|
channel: "discord",
|
||||||
@@ -349,24 +320,17 @@ describe("preflightDiscordMessage", () => {
|
|||||||
const result = await preflightDiscordMessage(
|
const result = await preflightDiscordMessage(
|
||||||
createPreflightArgs({
|
createPreflightArgs({
|
||||||
cfg: {
|
cfg: {
|
||||||
session: {
|
...DEFAULT_CFG,
|
||||||
mainKey: "main",
|
|
||||||
scope: "per-sender",
|
|
||||||
},
|
|
||||||
} as import("../../config/config.js").OpenClawConfig,
|
} as import("../../config/config.js").OpenClawConfig,
|
||||||
discordConfig: {
|
discordConfig: {
|
||||||
allowBots: true,
|
allowBots: true,
|
||||||
} as DiscordConfig,
|
} as DiscordConfig,
|
||||||
data: {
|
data: createGuildEvent({
|
||||||
channel_id: threadId,
|
channelId: threadId,
|
||||||
guild_id: "guild-1",
|
guildId: "guild-1",
|
||||||
guild: {
|
|
||||||
id: "guild-1",
|
|
||||||
name: "Guild One",
|
|
||||||
},
|
|
||||||
author: message.author,
|
author: message.author,
|
||||||
message,
|
message,
|
||||||
} as unknown as DiscordMessageEvent,
|
}),
|
||||||
client,
|
client,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -379,69 +343,32 @@ describe("preflightDiscordMessage", () => {
|
|||||||
it("drops bot messages without mention when allowBots=mentions", async () => {
|
it("drops bot messages without mention when allowBots=mentions", async () => {
|
||||||
const channelId = "channel-bot-mentions-off";
|
const channelId = "channel-bot-mentions-off";
|
||||||
const guildId = "guild-bot-mentions-off";
|
const guildId = "guild-bot-mentions-off";
|
||||||
const client = {
|
const client = createGuildTextClient(channelId);
|
||||||
fetchChannel: async (id: string) => {
|
const message = createMessage({
|
||||||
if (id === channelId) {
|
|
||||||
return {
|
|
||||||
id: channelId,
|
|
||||||
type: ChannelType.GuildText,
|
|
||||||
name: "general",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
} as unknown as import("@buape/carbon").Client;
|
|
||||||
const message = {
|
|
||||||
id: "m-bot-mentions-off",
|
id: "m-bot-mentions-off",
|
||||||
content: "relay chatter",
|
|
||||||
timestamp: new Date().toISOString(),
|
|
||||||
channelId,
|
channelId,
|
||||||
attachments: [],
|
content: "relay chatter",
|
||||||
mentionedUsers: [],
|
|
||||||
mentionedRoles: [],
|
|
||||||
mentionedEveryone: false,
|
|
||||||
author: {
|
author: {
|
||||||
id: "relay-bot-1",
|
id: "relay-bot-1",
|
||||||
bot: true,
|
bot: true,
|
||||||
username: "Relay",
|
username: "Relay",
|
||||||
},
|
},
|
||||||
} as unknown as import("@buape/carbon").Message;
|
});
|
||||||
|
|
||||||
const result = await preflightDiscordMessage({
|
const result = await preflightDiscordMessage({
|
||||||
cfg: {
|
...createPreflightArgs({
|
||||||
session: {
|
cfg: DEFAULT_CFG,
|
||||||
mainKey: "main",
|
discordConfig: {
|
||||||
scope: "per-sender",
|
allowBots: "mentions",
|
||||||
},
|
} as DiscordConfig,
|
||||||
} as import("../../config/config.js").OpenClawConfig,
|
data: createGuildEvent({
|
||||||
discordConfig: {
|
channelId,
|
||||||
allowBots: "mentions",
|
guildId,
|
||||||
} as NonNullable<import("../../config/config.js").OpenClawConfig["channels"]>["discord"],
|
author: message.author,
|
||||||
accountId: "default",
|
message,
|
||||||
token: "token",
|
}),
|
||||||
runtime: {} as import("../../runtime.js").RuntimeEnv,
|
client,
|
||||||
botUserId: "openclaw-bot",
|
}),
|
||||||
guildHistories: new Map(),
|
|
||||||
historyLimit: 0,
|
|
||||||
mediaMaxBytes: 1_000_000,
|
|
||||||
textLimit: 2_000,
|
|
||||||
replyToMode: "all",
|
|
||||||
dmEnabled: true,
|
|
||||||
groupDmEnabled: true,
|
|
||||||
ackReactionScope: "direct",
|
|
||||||
groupPolicy: "open",
|
|
||||||
threadBindings: createNoopThreadBindingManager("default"),
|
|
||||||
data: {
|
|
||||||
channel_id: channelId,
|
|
||||||
guild_id: guildId,
|
|
||||||
guild: {
|
|
||||||
id: guildId,
|
|
||||||
name: "Guild One",
|
|
||||||
},
|
|
||||||
author: message.author,
|
|
||||||
message,
|
|
||||||
} as unknown as import("./listeners.js").DiscordMessageEvent,
|
|
||||||
client,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result).toBeNull();
|
expect(result).toBeNull();
|
||||||
@@ -450,69 +377,33 @@ describe("preflightDiscordMessage", () => {
|
|||||||
it("allows bot messages with explicit mention when allowBots=mentions", async () => {
|
it("allows bot messages with explicit mention when allowBots=mentions", async () => {
|
||||||
const channelId = "channel-bot-mentions-on";
|
const channelId = "channel-bot-mentions-on";
|
||||||
const guildId = "guild-bot-mentions-on";
|
const guildId = "guild-bot-mentions-on";
|
||||||
const client = {
|
const client = createGuildTextClient(channelId);
|
||||||
fetchChannel: async (id: string) => {
|
const message = createMessage({
|
||||||
if (id === channelId) {
|
|
||||||
return {
|
|
||||||
id: channelId,
|
|
||||||
type: ChannelType.GuildText,
|
|
||||||
name: "general",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
} as unknown as import("@buape/carbon").Client;
|
|
||||||
const message = {
|
|
||||||
id: "m-bot-mentions-on",
|
id: "m-bot-mentions-on",
|
||||||
content: "hi <@openclaw-bot>",
|
|
||||||
timestamp: new Date().toISOString(),
|
|
||||||
channelId,
|
channelId,
|
||||||
attachments: [],
|
content: "hi <@openclaw-bot>",
|
||||||
mentionedUsers: [{ id: "openclaw-bot" }],
|
mentionedUsers: [{ id: "openclaw-bot" }],
|
||||||
mentionedRoles: [],
|
|
||||||
mentionedEveryone: false,
|
|
||||||
author: {
|
author: {
|
||||||
id: "relay-bot-1",
|
id: "relay-bot-1",
|
||||||
bot: true,
|
bot: true,
|
||||||
username: "Relay",
|
username: "Relay",
|
||||||
},
|
},
|
||||||
} as unknown as import("@buape/carbon").Message;
|
});
|
||||||
|
|
||||||
const result = await preflightDiscordMessage({
|
const result = await preflightDiscordMessage({
|
||||||
cfg: {
|
...createPreflightArgs({
|
||||||
session: {
|
cfg: DEFAULT_CFG,
|
||||||
mainKey: "main",
|
discordConfig: {
|
||||||
scope: "per-sender",
|
allowBots: "mentions",
|
||||||
},
|
} as DiscordConfig,
|
||||||
} as import("../../config/config.js").OpenClawConfig,
|
data: createGuildEvent({
|
||||||
discordConfig: {
|
channelId,
|
||||||
allowBots: "mentions",
|
guildId,
|
||||||
} as NonNullable<import("../../config/config.js").OpenClawConfig["channels"]>["discord"],
|
author: message.author,
|
||||||
accountId: "default",
|
message,
|
||||||
token: "token",
|
}),
|
||||||
runtime: {} as import("../../runtime.js").RuntimeEnv,
|
client,
|
||||||
botUserId: "openclaw-bot",
|
}),
|
||||||
guildHistories: new Map(),
|
|
||||||
historyLimit: 0,
|
|
||||||
mediaMaxBytes: 1_000_000,
|
|
||||||
textLimit: 2_000,
|
|
||||||
replyToMode: "all",
|
|
||||||
dmEnabled: true,
|
|
||||||
groupDmEnabled: true,
|
|
||||||
ackReactionScope: "direct",
|
|
||||||
groupPolicy: "open",
|
|
||||||
threadBindings: createNoopThreadBindingManager("default"),
|
|
||||||
data: {
|
|
||||||
channel_id: channelId,
|
|
||||||
guild_id: guildId,
|
|
||||||
guild: {
|
|
||||||
id: guildId,
|
|
||||||
name: "Guild One",
|
|
||||||
},
|
|
||||||
author: message.author,
|
|
||||||
message,
|
|
||||||
} as unknown as import("./listeners.js").DiscordMessageEvent,
|
|
||||||
client,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result).not.toBeNull();
|
expect(result).not.toBeNull();
|
||||||
@@ -521,75 +412,37 @@ describe("preflightDiscordMessage", () => {
|
|||||||
it("drops guild messages that mention another user when ignoreOtherMentions=true", async () => {
|
it("drops guild messages that mention another user when ignoreOtherMentions=true", async () => {
|
||||||
const channelId = "channel-other-mention-1";
|
const channelId = "channel-other-mention-1";
|
||||||
const guildId = "guild-other-mention-1";
|
const guildId = "guild-other-mention-1";
|
||||||
const client = {
|
const client = createGuildTextClient(channelId);
|
||||||
fetchChannel: async (id: string) => {
|
const message = createMessage({
|
||||||
if (id === channelId) {
|
|
||||||
return {
|
|
||||||
id: channelId,
|
|
||||||
type: ChannelType.GuildText,
|
|
||||||
name: "general",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
} as unknown as import("@buape/carbon").Client;
|
|
||||||
const message = {
|
|
||||||
id: "m-other-mention-1",
|
id: "m-other-mention-1",
|
||||||
content: "hello <@999>",
|
|
||||||
timestamp: new Date().toISOString(),
|
|
||||||
channelId,
|
channelId,
|
||||||
attachments: [],
|
content: "hello <@999>",
|
||||||
mentionedUsers: [{ id: "999" }],
|
mentionedUsers: [{ id: "999" }],
|
||||||
mentionedRoles: [],
|
|
||||||
mentionedEveryone: false,
|
|
||||||
author: {
|
author: {
|
||||||
id: "user-1",
|
id: "user-1",
|
||||||
bot: false,
|
bot: false,
|
||||||
username: "Alice",
|
username: "Alice",
|
||||||
},
|
},
|
||||||
} as unknown as import("@buape/carbon").Message;
|
});
|
||||||
|
|
||||||
const result = await preflightDiscordMessage({
|
const result = await preflightDiscordMessage({
|
||||||
cfg: {
|
...createPreflightArgs({
|
||||||
session: {
|
cfg: DEFAULT_CFG,
|
||||||
mainKey: "main",
|
discordConfig: {} as DiscordConfig,
|
||||||
scope: "per-sender",
|
data: createGuildEvent({
|
||||||
},
|
channelId,
|
||||||
} as import("../../config/config.js").OpenClawConfig,
|
guildId,
|
||||||
discordConfig: {} as NonNullable<
|
author: message.author,
|
||||||
import("../../config/config.js").OpenClawConfig["channels"]
|
message,
|
||||||
>["discord"],
|
}),
|
||||||
accountId: "default",
|
client,
|
||||||
token: "token",
|
}),
|
||||||
runtime: {} as import("../../runtime.js").RuntimeEnv,
|
|
||||||
botUserId: "openclaw-bot",
|
|
||||||
guildHistories: new Map(),
|
|
||||||
historyLimit: 0,
|
|
||||||
mediaMaxBytes: 1_000_000,
|
|
||||||
textLimit: 2_000,
|
|
||||||
replyToMode: "all",
|
|
||||||
dmEnabled: true,
|
|
||||||
groupDmEnabled: true,
|
|
||||||
ackReactionScope: "direct",
|
|
||||||
groupPolicy: "open",
|
|
||||||
threadBindings: createNoopThreadBindingManager("default"),
|
|
||||||
guildEntries: {
|
guildEntries: {
|
||||||
[guildId]: {
|
[guildId]: {
|
||||||
requireMention: false,
|
requireMention: false,
|
||||||
ignoreOtherMentions: true,
|
ignoreOtherMentions: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data: {
|
|
||||||
channel_id: channelId,
|
|
||||||
guild_id: guildId,
|
|
||||||
guild: {
|
|
||||||
id: guildId,
|
|
||||||
name: "Guild One",
|
|
||||||
},
|
|
||||||
author: message.author,
|
|
||||||
message,
|
|
||||||
} as unknown as import("./listeners.js").DiscordMessageEvent,
|
|
||||||
client,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result).toBeNull();
|
expect(result).toBeNull();
|
||||||
@@ -598,75 +451,37 @@ describe("preflightDiscordMessage", () => {
|
|||||||
it("does not drop @everyone messages when ignoreOtherMentions=true", async () => {
|
it("does not drop @everyone messages when ignoreOtherMentions=true", async () => {
|
||||||
const channelId = "channel-other-mention-everyone";
|
const channelId = "channel-other-mention-everyone";
|
||||||
const guildId = "guild-other-mention-everyone";
|
const guildId = "guild-other-mention-everyone";
|
||||||
const client = {
|
const client = createGuildTextClient(channelId);
|
||||||
fetchChannel: async (id: string) => {
|
const message = createMessage({
|
||||||
if (id === channelId) {
|
|
||||||
return {
|
|
||||||
id: channelId,
|
|
||||||
type: ChannelType.GuildText,
|
|
||||||
name: "general",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
} as unknown as import("@buape/carbon").Client;
|
|
||||||
const message = {
|
|
||||||
id: "m-other-mention-everyone",
|
id: "m-other-mention-everyone",
|
||||||
content: "@everyone heads up",
|
|
||||||
timestamp: new Date().toISOString(),
|
|
||||||
channelId,
|
channelId,
|
||||||
attachments: [],
|
content: "@everyone heads up",
|
||||||
mentionedUsers: [],
|
|
||||||
mentionedRoles: [],
|
|
||||||
mentionedEveryone: true,
|
mentionedEveryone: true,
|
||||||
author: {
|
author: {
|
||||||
id: "user-1",
|
id: "user-1",
|
||||||
bot: false,
|
bot: false,
|
||||||
username: "Alice",
|
username: "Alice",
|
||||||
},
|
},
|
||||||
} as unknown as import("@buape/carbon").Message;
|
});
|
||||||
|
|
||||||
const result = await preflightDiscordMessage({
|
const result = await preflightDiscordMessage({
|
||||||
cfg: {
|
...createPreflightArgs({
|
||||||
session: {
|
cfg: DEFAULT_CFG,
|
||||||
mainKey: "main",
|
discordConfig: {} as DiscordConfig,
|
||||||
scope: "per-sender",
|
data: createGuildEvent({
|
||||||
},
|
channelId,
|
||||||
} as import("../../config/config.js").OpenClawConfig,
|
guildId,
|
||||||
discordConfig: {} as NonNullable<
|
author: message.author,
|
||||||
import("../../config/config.js").OpenClawConfig["channels"]
|
message,
|
||||||
>["discord"],
|
}),
|
||||||
accountId: "default",
|
client,
|
||||||
token: "token",
|
}),
|
||||||
runtime: {} as import("../../runtime.js").RuntimeEnv,
|
|
||||||
botUserId: "openclaw-bot",
|
|
||||||
guildHistories: new Map(),
|
|
||||||
historyLimit: 0,
|
|
||||||
mediaMaxBytes: 1_000_000,
|
|
||||||
textLimit: 2_000,
|
|
||||||
replyToMode: "all",
|
|
||||||
dmEnabled: true,
|
|
||||||
groupDmEnabled: true,
|
|
||||||
ackReactionScope: "direct",
|
|
||||||
groupPolicy: "open",
|
|
||||||
threadBindings: createNoopThreadBindingManager("default"),
|
|
||||||
guildEntries: {
|
guildEntries: {
|
||||||
[guildId]: {
|
[guildId]: {
|
||||||
requireMention: false,
|
requireMention: false,
|
||||||
ignoreOtherMentions: true,
|
ignoreOtherMentions: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data: {
|
|
||||||
channel_id: channelId,
|
|
||||||
guild_id: guildId,
|
|
||||||
guild: {
|
|
||||||
id: guildId,
|
|
||||||
name: "Guild One",
|
|
||||||
},
|
|
||||||
author: message.author,
|
|
||||||
message,
|
|
||||||
} as unknown as import("./listeners.js").DiscordMessageEvent,
|
|
||||||
client,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result).not.toBeNull();
|
expect(result).not.toBeNull();
|
||||||
@@ -676,74 +491,38 @@ describe("preflightDiscordMessage", () => {
|
|||||||
it("ignores bot-sent @everyone mentions for detection", async () => {
|
it("ignores bot-sent @everyone mentions for detection", async () => {
|
||||||
const channelId = "channel-everyone-1";
|
const channelId = "channel-everyone-1";
|
||||||
const guildId = "guild-everyone-1";
|
const guildId = "guild-everyone-1";
|
||||||
const client = {
|
const client = createGuildTextClient(channelId);
|
||||||
fetchChannel: async (id: string) => {
|
const message = createMessage({
|
||||||
if (id === channelId) {
|
|
||||||
return {
|
|
||||||
id: channelId,
|
|
||||||
type: ChannelType.GuildText,
|
|
||||||
name: "general",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
} as unknown as import("@buape/carbon").Client;
|
|
||||||
const message = {
|
|
||||||
id: "m-everyone-1",
|
id: "m-everyone-1",
|
||||||
content: "@everyone heads up",
|
|
||||||
timestamp: new Date().toISOString(),
|
|
||||||
channelId,
|
channelId,
|
||||||
attachments: [],
|
content: "@everyone heads up",
|
||||||
mentionedUsers: [],
|
|
||||||
mentionedRoles: [],
|
|
||||||
mentionedEveryone: true,
|
mentionedEveryone: true,
|
||||||
author: {
|
author: {
|
||||||
id: "relay-bot-1",
|
id: "relay-bot-1",
|
||||||
bot: true,
|
bot: true,
|
||||||
username: "Relay",
|
username: "Relay",
|
||||||
},
|
},
|
||||||
} as unknown as import("@buape/carbon").Message;
|
});
|
||||||
|
|
||||||
const result = await preflightDiscordMessage({
|
const result = await preflightDiscordMessage({
|
||||||
cfg: {
|
...createPreflightArgs({
|
||||||
session: {
|
cfg: DEFAULT_CFG,
|
||||||
mainKey: "main",
|
discordConfig: {
|
||||||
scope: "per-sender",
|
allowBots: true,
|
||||||
},
|
} as DiscordConfig,
|
||||||
} as import("../../config/config.js").OpenClawConfig,
|
data: createGuildEvent({
|
||||||
discordConfig: {
|
channelId,
|
||||||
allowBots: true,
|
guildId,
|
||||||
} as NonNullable<import("../../config/config.js").OpenClawConfig["channels"]>["discord"],
|
author: message.author,
|
||||||
accountId: "default",
|
message,
|
||||||
token: "token",
|
}),
|
||||||
runtime: {} as import("../../runtime.js").RuntimeEnv,
|
client,
|
||||||
botUserId: "openclaw-bot",
|
}),
|
||||||
guildHistories: new Map(),
|
|
||||||
historyLimit: 0,
|
|
||||||
mediaMaxBytes: 1_000_000,
|
|
||||||
textLimit: 2_000,
|
|
||||||
replyToMode: "all",
|
|
||||||
dmEnabled: true,
|
|
||||||
groupDmEnabled: true,
|
|
||||||
ackReactionScope: "direct",
|
|
||||||
groupPolicy: "open",
|
|
||||||
threadBindings: createNoopThreadBindingManager("default"),
|
|
||||||
guildEntries: {
|
guildEntries: {
|
||||||
[guildId]: {
|
[guildId]: {
|
||||||
requireMention: false,
|
requireMention: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data: {
|
|
||||||
channel_id: channelId,
|
|
||||||
guild_id: guildId,
|
|
||||||
guild: {
|
|
||||||
id: guildId,
|
|
||||||
name: "Guild One",
|
|
||||||
},
|
|
||||||
author: message.author,
|
|
||||||
message,
|
|
||||||
} as unknown as import("./listeners.js").DiscordMessageEvent,
|
|
||||||
client,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result).not.toBeNull();
|
expect(result).not.toBeNull();
|
||||||
@@ -754,24 +533,12 @@ describe("preflightDiscordMessage", () => {
|
|||||||
transcribeFirstAudioMock.mockResolvedValue("hey openclaw");
|
transcribeFirstAudioMock.mockResolvedValue("hey openclaw");
|
||||||
|
|
||||||
const channelId = "channel-audio-1";
|
const channelId = "channel-audio-1";
|
||||||
const client = {
|
const client = createGuildTextClient(channelId);
|
||||||
fetchChannel: async (id: string) => {
|
|
||||||
if (id === channelId) {
|
|
||||||
return {
|
|
||||||
id: channelId,
|
|
||||||
type: ChannelType.GuildText,
|
|
||||||
name: "general",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
} as unknown as import("@buape/carbon").Client;
|
|
||||||
|
|
||||||
const message = {
|
const message = createMessage({
|
||||||
id: "m-audio-1",
|
id: "m-audio-1",
|
||||||
content: "",
|
|
||||||
timestamp: new Date().toISOString(),
|
|
||||||
channelId,
|
channelId,
|
||||||
|
content: "",
|
||||||
attachments: [
|
attachments: [
|
||||||
{
|
{
|
||||||
id: "att-1",
|
id: "att-1",
|
||||||
@@ -780,23 +547,17 @@ describe("preflightDiscordMessage", () => {
|
|||||||
filename: "voice.ogg",
|
filename: "voice.ogg",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
mentionedUsers: [],
|
|
||||||
mentionedRoles: [],
|
|
||||||
mentionedEveryone: false,
|
|
||||||
author: {
|
author: {
|
||||||
id: "user-1",
|
id: "user-1",
|
||||||
bot: false,
|
bot: false,
|
||||||
username: "Alice",
|
username: "Alice",
|
||||||
},
|
},
|
||||||
} as unknown as import("@buape/carbon").Message;
|
});
|
||||||
|
|
||||||
const result = await preflightDiscordMessage(
|
const result = await preflightDiscordMessage(
|
||||||
createPreflightArgs({
|
createPreflightArgs({
|
||||||
cfg: {
|
cfg: {
|
||||||
session: {
|
...DEFAULT_CFG,
|
||||||
mainKey: "main",
|
|
||||||
scope: "per-sender",
|
|
||||||
},
|
|
||||||
messages: {
|
messages: {
|
||||||
groupChat: {
|
groupChat: {
|
||||||
mentionPatterns: ["openclaw"],
|
mentionPatterns: ["openclaw"],
|
||||||
@@ -804,16 +565,12 @@ describe("preflightDiscordMessage", () => {
|
|||||||
},
|
},
|
||||||
} as import("../../config/config.js").OpenClawConfig,
|
} as import("../../config/config.js").OpenClawConfig,
|
||||||
discordConfig: {} as DiscordConfig,
|
discordConfig: {} as DiscordConfig,
|
||||||
data: {
|
data: createGuildEvent({
|
||||||
channel_id: channelId,
|
channelId,
|
||||||
guild_id: "guild-1",
|
guildId: "guild-1",
|
||||||
guild: {
|
|
||||||
id: "guild-1",
|
|
||||||
name: "Guild One",
|
|
||||||
},
|
|
||||||
author: message.author,
|
author: message.author,
|
||||||
message,
|
message,
|
||||||
} as unknown as DiscordMessageEvent,
|
}),
|
||||||
client,
|
client,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user