mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:20:43 +00:00
fix(discord): preserve fetched thread parent for plugin commands (#69908) (thanks @neeravmakwana)
This commit is contained in:
@@ -542,10 +542,12 @@ describe("Discord native plugin command dispatch", () => {
|
||||
"thread-123": {
|
||||
enabled: true,
|
||||
requireMention: false,
|
||||
users: ["owner"],
|
||||
},
|
||||
"parent-456": {
|
||||
enabled: true,
|
||||
requireMention: false,
|
||||
users: ["owner"],
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -596,6 +598,95 @@ describe("Discord native plugin command dispatch", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("preserves fetched thread parent metadata when interaction parentId getter throws", async () => {
|
||||
const cfg = {
|
||||
commands: {
|
||||
useAccessGroups: false,
|
||||
},
|
||||
channels: {
|
||||
discord: {
|
||||
groupPolicy: "allowlist",
|
||||
guilds: {
|
||||
"345678901234567890": {
|
||||
channels: {
|
||||
"partial-thread-123": {
|
||||
enabled: true,
|
||||
requireMention: false,
|
||||
users: ["owner"],
|
||||
},
|
||||
"partial-parent-456": {
|
||||
enabled: true,
|
||||
requireMention: false,
|
||||
users: ["owner"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
const commandSpec: NativeCommandSpec = {
|
||||
name: "cron_jobs",
|
||||
description: "List cron jobs",
|
||||
acceptsArgs: false,
|
||||
};
|
||||
const interaction = createInteraction({
|
||||
channelType: ChannelType.PublicThread,
|
||||
channelId: "partial-thread-123",
|
||||
guildId: "345678901234567890",
|
||||
guildName: "Test Guild",
|
||||
});
|
||||
Object.defineProperty(interaction.channel, "parentId", {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get() {
|
||||
throw new Error("Cannot access rawData on partial Channel. Use fetch() to populate data.");
|
||||
},
|
||||
});
|
||||
(interaction.client as { fetchChannel: ReturnType<typeof vi.fn> }).fetchChannel = vi.fn(
|
||||
async (channelId: string) => {
|
||||
if (channelId === "partial-thread-123") {
|
||||
return {
|
||||
id: "partial-thread-123",
|
||||
type: ChannelType.PublicThread,
|
||||
parentId: "partial-parent-456",
|
||||
};
|
||||
}
|
||||
if (channelId === "partial-parent-456") {
|
||||
return { id: "partial-parent-456", type: ChannelType.GuildText, name: "Parent" };
|
||||
}
|
||||
return null;
|
||||
},
|
||||
);
|
||||
const pluginMatch = {
|
||||
command: {
|
||||
name: "cron_jobs",
|
||||
description: "List cron jobs",
|
||||
pluginId: "cron-jobs",
|
||||
acceptsArgs: false,
|
||||
handler: vi.fn().mockResolvedValue({ text: "jobs" }),
|
||||
},
|
||||
args: undefined,
|
||||
};
|
||||
|
||||
runtimeModuleMocks.matchPluginCommand.mockReturnValue(pluginMatch as never);
|
||||
const executeSpy = runtimeModuleMocks.executePluginCommand.mockResolvedValue({
|
||||
text: "direct plugin output",
|
||||
});
|
||||
const command = await createNativeCommand(cfg, commandSpec);
|
||||
|
||||
await (command as { run: (interaction: unknown) => Promise<void> }).run(interaction as unknown);
|
||||
|
||||
expect(executeSpy).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
channel: "discord",
|
||||
from: "discord:channel:partial-thread-123",
|
||||
messageThreadId: "partial-thread-123",
|
||||
threadParentId: "partial-parent-456",
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("routes native slash commands through configured ACP Discord channel bindings", async () => {
|
||||
const { cfg, interaction } = createConfiguredAcpCase({
|
||||
channelType: ChannelType.GuildText,
|
||||
|
||||
@@ -1075,10 +1075,7 @@ async function dispatchDiscordCommandInteraction(params: {
|
||||
interaction.channel?.type === ChannelType.PrivateThread ||
|
||||
interaction.channel?.type === ChannelType.AnnouncementThread;
|
||||
const messageThreadId = !isDirectMessage && isThreadChannel ? channelId : undefined;
|
||||
const threadParentId =
|
||||
!isDirectMessage && isThreadChannel
|
||||
? resolveDiscordChannelParentIdSafe(interaction.channel)
|
||||
: undefined;
|
||||
const pluginThreadParentId = !isDirectMessage && isThreadChannel ? threadParentId : undefined;
|
||||
const { effectiveRoute } = await getNativeRouteState();
|
||||
const pluginReply = await executePluginCommandImpl({
|
||||
command: pluginMatch.command,
|
||||
@@ -1098,7 +1095,7 @@ async function dispatchDiscordCommandInteraction(params: {
|
||||
to: `slash:${user.id}`,
|
||||
accountId,
|
||||
messageThreadId,
|
||||
threadParentId,
|
||||
threadParentId: pluginThreadParentId,
|
||||
});
|
||||
if (!hasRenderableReplyPayload(pluginReply)) {
|
||||
await respond("Done.");
|
||||
|
||||
Reference in New Issue
Block a user