Discord: preserve component callback fallback

This commit is contained in:
huntharo
2026-03-20 15:49:59 -04:00
parent f4227e2787
commit 1fdff248f3
2 changed files with 25 additions and 5 deletions

View File

@@ -614,11 +614,15 @@ async function handleDiscordComponentEvent(params: {
return;
}
}
const eventText = formatDiscordComponentEventText({
kind: consumed.kind === "select" ? "select" : "button",
label: consumed.label,
values,
});
// Preserve explicit callback payloads for the built-in fallback path so
// Discord behaves like Telegram when buttons carry synthetic command text.
const eventText =
consumed.callbackData?.trim() ||
formatDiscordComponentEventText({
kind: consumed.kind === "select" ? "select" : "button",
label: consumed.label,
values,
});
try {
await params.interaction.reply({ content: "✓", ...replyOpts });

View File

@@ -517,6 +517,22 @@ describe("discord component interactions", () => {
expect(resolveDiscordComponentEntry({ id: "btn_1" })).toBeNull();
});
it("uses raw callbackData for built-in fallback when no plugin handler matches", async () => {
registerDiscordComponentEntries({
entries: [createButtonEntry({ callbackData: "/codex_resume --browse-projects" })],
modals: [],
});
const button = createDiscordComponentButton(createComponentContext());
const { interaction, reply } = createComponentButtonInteraction();
await button.run(interaction, { cid: "btn_1" } as ComponentData);
expect(reply).toHaveBeenCalledWith({ content: "✓" });
expect(lastDispatchCtx?.BodyForAgent).toBe("/codex_resume --browse-projects");
expect(dispatchReplyMock).toHaveBeenCalledTimes(1);
});
it("keeps reusable buttons active after use", async () => {
registerDiscordComponentEntries({
entries: [createButtonEntry({ reusable: true })],