import { ActionRowBuilder, ButtonBuilder, ButtonStyle, MessageActionRowComponentBuilder, MessageComponentInteraction, MessageCreateOptions, } from "discord.js"; import moment from "moment"; import { v4 as uuidv4 } from "uuid"; import { GenericCommandSource, isContextInteraction, sendContextResponse } from "../pluginUtils.js"; import { noop } from "../utils.js"; export async function waitForButtonConfirm( context: GenericCommandSource, toPost: Omit, options?: WaitForOptions, ): Promise { return new Promise(async (resolve) => { const contextIsInteraction = isContextInteraction(context); const idMod = `${context.id}-${moment.utc().valueOf()}`; const row = new ActionRowBuilder().addComponents([ new ButtonBuilder() .setStyle(ButtonStyle.Success) .setLabel(options?.confirmText || "Confirm") .setCustomId(`confirmButton:${idMod}:${uuidv4()}`), new ButtonBuilder() .setStyle(ButtonStyle.Danger) .setLabel(options?.cancelText || "Cancel") .setCustomId(`cancelButton:${idMod}:${uuidv4()}`), ]); const message = await sendContextResponse(context, { ...toPost, components: [row] }, true); const collector = message.createMessageComponentCollector({ time: 10000 }); collector.on("collect", (interaction: MessageComponentInteraction) => { if (options?.restrictToId && options.restrictToId !== interaction.user.id) { interaction .reply({ content: `You are not permitted to use these buttons.`, ephemeral: true }) // tslint:disable-next-line no-console .catch((err) => console.trace(err.message)); } else { if (interaction.customId.startsWith(`confirmButton:${idMod}:`)) { if (!contextIsInteraction) message.delete(); resolve(true); } else if (interaction.customId.startsWith(`cancelButton:${idMod}:`)) { if (!contextIsInteraction) message.delete(); resolve(false); } } }); collector.on("end", () => { if (!contextIsInteraction && message.deletable) message.delete().catch(noop); resolve(false); }); }); } export interface WaitForOptions { restrictToId?: string; confirmText?: string; cancelText?: string; }