Skip to content

Commit 942b8d0

Browse files
authored
Merge pull request #537 from seeyebe/fix/button-interaction-acknowledgment
fix: handle button interactions properly for slash commands
2 parents 0ff6d91 + 67a3e2a commit 942b8d0

File tree

2 files changed

+38
-13
lines changed

2 files changed

+38
-13
lines changed

backend/src/utils.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import {
2+
ActionRowBuilder,
23
APIEmbed,
4+
ButtonBuilder,
35
ChannelType,
46
Client,
57
DiscordAPIError,
@@ -18,6 +20,7 @@ import {
1820
InviteType,
1921
LimitedCollection,
2022
Message,
23+
MessageActionRowComponentBuilder,
2124
MessageCreateOptions,
2225
MessageMentionOptions,
2326
PartialGroupDMChannel,
@@ -1306,6 +1309,20 @@ export async function confirm(
13061309
return waitForButtonConfirm(context, content, { restrictToId: userId });
13071310
}
13081311

1312+
export function createDisabledButtonRow(
1313+
row: ActionRowBuilder<MessageActionRowComponentBuilder>
1314+
): ActionRowBuilder<MessageActionRowComponentBuilder> {
1315+
const newRow = new ActionRowBuilder<MessageActionRowComponentBuilder>();
1316+
for (const component of row.components) {
1317+
if (component instanceof ButtonBuilder) {
1318+
newRow.addComponents(
1319+
ButtonBuilder.from(component).setDisabled(true)
1320+
);
1321+
}
1322+
}
1323+
return newRow;
1324+
}
1325+
13091326
export function messageSummary(msg: SavedMessage) {
13101327
// Regular text content
13111328
let result = "```\n" + (msg.data.content ? escapeCodeBlock(msg.data.content) : "<no text content>") + "```";

backend/src/utils/waitForInteraction.ts

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
import moment from "moment-timezone";
1010
import { v4 as uuidv4 } from "uuid";
1111
import { GenericCommandSource, isContextInteraction, sendContextResponse } from "../pluginUtils.js";
12-
import { noop } from "../utils.js";
12+
import { noop, createDisabledButtonRow } from "../utils.js";
1313

1414
export async function waitForButtonConfirm(
1515
context: GenericCommandSource,
@@ -24,34 +24,42 @@ export async function waitForButtonConfirm(
2424
.setStyle(ButtonStyle.Success)
2525
.setLabel(options?.confirmText || "Confirm")
2626
.setCustomId(`confirmButton:${idMod}:${uuidv4()}`),
27-
2827
new ButtonBuilder()
2928
.setStyle(ButtonStyle.Danger)
3029
.setLabel(options?.cancelText || "Cancel")
3130
.setCustomId(`cancelButton:${idMod}:${uuidv4()}`),
3231
]);
3332
const message = await sendContextResponse(context, { ...toPost, components: [row] }, true);
34-
3533
const collector = message.createMessageComponentCollector({ time: 10000 });
3634

3735
collector.on("collect", (interaction: MessageComponentInteraction) => {
3836
if (options?.restrictToId && options.restrictToId !== interaction.user.id) {
3937
interaction
4038
.reply({ content: `You are not permitted to use these buttons.`, ephemeral: true })
41-
// tslint:disable-next-line no-console
42-
.catch((err) => console.trace(err.message));
43-
} else {
44-
if (interaction.customId.startsWith(`confirmButton:${idMod}:`)) {
45-
if (!contextIsInteraction) message.delete();
46-
resolve(true);
47-
} else if (interaction.customId.startsWith(`cancelButton:${idMod}:`)) {
48-
if (!contextIsInteraction) message.delete();
49-
resolve(false);
39+
.catch(noop);
40+
} else if (interaction.customId.startsWith(`confirmButton:${idMod}:`)) {
41+
if (!contextIsInteraction) {
42+
message.delete().catch(noop);
43+
} else {
44+
interaction.update({ components: [createDisabledButtonRow(row)] }).catch(noop);
45+
}
46+
resolve(true);
47+
} else if (interaction.customId.startsWith(`cancelButton:${idMod}:`)) {
48+
if (!contextIsInteraction) {
49+
message.delete().catch(noop);
50+
} else {
51+
interaction.update({ components: [createDisabledButtonRow(row)] }).catch(noop);
5052
}
53+
resolve(false);
5154
}
5255
});
56+
5357
collector.on("end", () => {
54-
if (!contextIsInteraction && message.deletable) message.delete().catch(noop);
58+
if (!contextIsInteraction) {
59+
if (message.deletable) message.delete().catch(noop);
60+
} else {
61+
message.edit({ components: [createDisabledButtonRow(row)] }).catch(noop);
62+
}
5563
resolve(false);
5664
});
5765
});

0 commit comments

Comments
 (0)