import type { ButtonInteraction, Interaction } from "discord.js"; import { MessageFlags } from "discord.js"; import type { InteractionStep, InteractionStepContext } from "../../types/Step"; import type { ButtonResource } from "../../types/Resource"; import { runMiddleware } from "../../types/Middleware"; import { createContext } from "../../core/context"; export const buttonInteractionStep: InteractionStep = { name: "button", match(interaction: Interaction): boolean { return interaction.isButton(); }, async handle(interaction: Interaction, { client, cache }: InteractionStepContext): Promise { const i = interaction as ButtonInteraction; // Exact match first let button = cache.get("button", i.customId); // Prefix match for dynamic button IDs (e.g. "guild.MemberLogging-Kick-123") if (!button) { const allButtons = cache.getAll("button"); for (const [id, btn] of allButtons) { if (i.customId.startsWith(id)) { button = btn; break; } } } if (!button) { await i.reply({ content: `Sorry, but the button \`${i.customId}\` could not be found.`, flags: [MessageFlags.Ephemeral], }); return; } const lines = [ `# ButtonInteraction`, `### Metadata`, `- **Button:** \`${button.id}\``, `- **Custom ID:** \`${i.customId}\``, `- **User:** \`${i.user.tag}\` (${i.user.id})`, `- **Guild:** \`${i.guild?.name ?? "DM"}\` (${i.guildId ?? "N/A"})`, `- **Channel:** <#${i.channelId}>`, ]; client.logger.send(lines.join("\n")); const ctx = createContext(client, button, i); await runMiddleware(button.use, i, client, () => button.execute(ctx)); }, };