mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 20:30:45 +00:00
fix(discord): keep slash follow-ups ephemeral
This commit is contained in:
@@ -80,6 +80,7 @@ export type DispatchDiscordCommandInteractionParams = {
|
||||
sessionPrefix: string;
|
||||
preferFollowUp: boolean;
|
||||
threadBindings: ThreadBindingManager;
|
||||
responseEphemeral?: boolean;
|
||||
suppressReplies?: boolean;
|
||||
};
|
||||
|
||||
@@ -918,6 +919,7 @@ export async function handleDiscordCommandArgInteraction(params: {
|
||||
sessionPrefix: ctx.sessionPrefix,
|
||||
preferFollowUp: true,
|
||||
threadBindings: ctx.threadBindings,
|
||||
responseEphemeral: true,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -152,11 +152,32 @@ describe("discord native /status", () => {
|
||||
expect(interaction.followUp).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
content: "status reply",
|
||||
ephemeral: true,
|
||||
}),
|
||||
);
|
||||
expect(interaction.reply).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("keeps every direct status chunk ephemeral", async () => {
|
||||
runtimeModuleMocks.resolveDirectStatusReplyForSession.mockResolvedValue({
|
||||
text: `fallback models\nruntime info\n${"x".repeat(2200)}`,
|
||||
});
|
||||
const cfg = createConfig();
|
||||
const command = await createStatusCommand(cfg);
|
||||
const interaction = createInteraction();
|
||||
|
||||
await (command as { run: (interaction: unknown) => Promise<void> }).run(interaction as unknown);
|
||||
|
||||
expect(interaction.followUp.mock.calls.length).toBeGreaterThan(1);
|
||||
for (const [payload] of interaction.followUp.mock.calls) {
|
||||
expect(payload).toEqual(
|
||||
expect.objectContaining({
|
||||
ephemeral: true,
|
||||
}),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("passes through the effective guild activation when requireMention is disabled", async () => {
|
||||
const cfg = createConfig({ requireMention: false });
|
||||
const command = await createStatusCommand(cfg);
|
||||
|
||||
@@ -742,6 +742,7 @@ export function createDiscordNativeCommand(params: {
|
||||
// follow-up/edit semantics instead of the initial reply endpoint.
|
||||
preferFollowUp: true,
|
||||
threadBindings,
|
||||
responseEphemeral: ephemeralDefault,
|
||||
});
|
||||
}
|
||||
})();
|
||||
@@ -758,6 +759,7 @@ async function dispatchDiscordCommandInteraction(params: {
|
||||
sessionPrefix: string;
|
||||
preferFollowUp: boolean;
|
||||
threadBindings: ThreadBindingManager;
|
||||
responseEphemeral?: boolean;
|
||||
suppressReplies?: boolean;
|
||||
}) {
|
||||
const {
|
||||
@@ -771,13 +773,15 @@ async function dispatchDiscordCommandInteraction(params: {
|
||||
sessionPrefix,
|
||||
preferFollowUp,
|
||||
threadBindings,
|
||||
responseEphemeral,
|
||||
suppressReplies,
|
||||
} = params;
|
||||
const commandName = command.nativeName ?? command.key;
|
||||
const respond = async (content: string, options?: { ephemeral?: boolean }) => {
|
||||
const ephemeral = options?.ephemeral ?? responseEphemeral;
|
||||
const payload = {
|
||||
content,
|
||||
...(options?.ephemeral !== undefined ? { ephemeral: options.ephemeral } : {}),
|
||||
...(ephemeral !== undefined ? { ephemeral } : {}),
|
||||
};
|
||||
await safeDiscordInteractionCall("interaction reply", async () => {
|
||||
if (preferFollowUp) {
|
||||
@@ -1099,6 +1103,7 @@ async function dispatchDiscordCommandInteraction(params: {
|
||||
}),
|
||||
maxLinesPerMessage: resolveDiscordMaxLinesPerMessage({ cfg, discordConfig, accountId }),
|
||||
preferFollowUp,
|
||||
responseEphemeral,
|
||||
chunkMode: resolveChunkMode(cfg, "discord", accountId),
|
||||
});
|
||||
return;
|
||||
@@ -1168,6 +1173,7 @@ async function dispatchDiscordCommandInteraction(params: {
|
||||
}),
|
||||
maxLinesPerMessage: resolveDiscordMaxLinesPerMessage({ cfg, discordConfig, accountId }),
|
||||
preferFollowUp,
|
||||
responseEphemeral,
|
||||
chunkMode: resolveChunkMode(cfg, "discord", accountId),
|
||||
});
|
||||
return;
|
||||
@@ -1233,6 +1239,7 @@ async function dispatchDiscordCommandInteraction(params: {
|
||||
}),
|
||||
maxLinesPerMessage: resolveDiscordMaxLinesPerMessage({ cfg, discordConfig, accountId }),
|
||||
preferFollowUp: preferFollowUp || didReply,
|
||||
responseEphemeral,
|
||||
chunkMode: resolveChunkMode(cfg, "discord", accountId),
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -1314,6 +1321,7 @@ async function deliverDiscordInteractionReply(params: {
|
||||
textLimit: number;
|
||||
maxLinesPerMessage?: number;
|
||||
preferFollowUp: boolean;
|
||||
responseEphemeral?: boolean;
|
||||
chunkMode: "length" | "newline";
|
||||
}) {
|
||||
const { interaction, payload, textLimit, maxLinesPerMessage, preferFollowUp, chunkMode } = params;
|
||||
@@ -1337,6 +1345,9 @@ async function deliverDiscordInteractionReply(params: {
|
||||
? {
|
||||
content,
|
||||
...(components ? { components } : {}),
|
||||
...(params.responseEphemeral !== undefined
|
||||
? { ephemeral: params.responseEphemeral }
|
||||
: {}),
|
||||
files: files.map((file) => {
|
||||
if (file.data instanceof Blob) {
|
||||
return { name: file.name, data: file.data };
|
||||
@@ -1348,6 +1359,9 @@ async function deliverDiscordInteractionReply(params: {
|
||||
: {
|
||||
content,
|
||||
...(components ? { components } : {}),
|
||||
...(params.responseEphemeral !== undefined
|
||||
? { ephemeral: params.responseEphemeral }
|
||||
: {}),
|
||||
};
|
||||
await safeDiscordInteractionCall("interaction send", async () => {
|
||||
if (!preferFollowUp && !hasReplied) {
|
||||
@@ -1388,7 +1402,10 @@ async function deliverDiscordInteractionReply(params: {
|
||||
if (!chunk.trim()) {
|
||||
continue;
|
||||
}
|
||||
await interaction.followUp({ content: chunk });
|
||||
await interaction.followUp({
|
||||
content: chunk,
|
||||
...(params.responseEphemeral !== undefined ? { ephemeral: params.responseEphemeral } : {}),
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user