Search code examples
javascriptdiscorddiscord.js

The reply to this interaction has already been sent


Hello so I'm trying to do a fun interaction for a high low command but it is not working since it is sending an error Here is the full error down here:

C:\Users\Matthew\OneDrive\Documents\Moria Calliope\interactions\slash\fun\highlow.js:105
                                buttons.forEach((b) => b.setDisabled(true));
                                                         ^

TypeError: b.setDisabled is not a function
    at C:\Users\Matthew\OneDrive\Documents\Moria Calliope\interactions\slash\fun\highlow.js:105:30
    at Array.forEach (<anonymous>)
    at InteractionCollector.<anonymous> (C:\Users\Matthew\OneDrive\Documents\Moria Calliope\interactions\slash\fun\highlow.js:105:13)
    at InteractionCollector.emit (node:events:525:35)
    at InteractionCollector.stop (C:\Users\Matthew\OneDrive\Documents\Moria Calliope\node_modules\discord.js\src\structures\interfaces\Collector.js:218:10)
    at Timeout.<anonymous> (C:\Users\Matthew\OneDrive\Documents\Moria Calliope\node_modules\discord.js\src\structures\interfaces\Collector.js:96:61)
    at listOnTimeout (node:internal/timers:559:17)
    at processTimers (node:internal/timers:502:7)

And here's the code down here:

const {
    ActionRowBuilder,
    ButtonBuilder,
    SlashCommandBuilder,
    ButtonStyle,
} = require("discord.js");

module.exports = {
    data: new SlashCommandBuilder()
        .setName("highlow")
        .setDescription("Starts a new high or low game!"),
    async execute(interaction) {
        const randomNumber = Math.floor(Math.random() * 100) + 1;
        // create a hint random number
        const hintNumber = Math.floor(Math.random() * 100) + 1;
        let row = new ActionRowBuilder().addComponents(
            new ButtonBuilder()
                .setCustomId("high")
                .setLabel("High")
                .setStyle(ButtonStyle.Secondary),
            new ButtonBuilder()
                .setCustomId("low")
                .setLabel("Low")
                .setStyle(ButtonStyle.Secondary),
            new ButtonBuilder()
                .setCustomId("correct")
                .setLabel("Same")
                .setStyle(ButtonStyle.Secondary)
        );
        const buttons = [row];
        const sent = await interaction.reply({
            content: `Is my number higher or lower than ${hintNumber}?`,
            components: [row],
        });
        const collector = sent.createMessageComponentCollector({
            filter: (i) =>
                i.user.id === interaction.user.id && i.message.id === sent.id,
            time: 30000,
            max: 1,
        });
        let won = false;
        collector.on("collect", async (i) => {
            await i.deferUpdate({ fetchReply: true });
            buttons.forEach((b) => b.setDisabled(true));
            if (i.customId === "high") {
                if (hintNumber > randomNumber) {
                    buttons.forEach((b) => {
                        if (b.customId === "high") b.setStyle(ButtonStyle.Danger);
                    });
                    await i.editReply({
                        content: `Sadge, you got it wrong! It was ${randomNumber}`,
                        components: [new ActionRowBuilder().addComponents(buttons)],
                    });
                    won = false;
                } else {
                    buttons.forEach((b) => {
                        if (b.customId === "high") b.setStyle(ButtonStyle.Success);
                    });
                    await i.editReply({
                        content: `You guessed the number! It was ${randomNumber}`,
                        components: [new ActionRowBuilder().addComponents(buttons)],
                    });
                    won = true;
                }
            } else if (i.customId === "low") {
                if (hintNumber < randomNumber) {
                    buttons.forEach((b) => {
                        if (b.customId === "low") b.setStyle(ButtonStyle.Danger);
                    });
                    await i.editReply({
                        content: `Sadge, you got it wrong! It was ${randomNumber}`,
                        components: [new ActionRowBuilder().addComponents(buttons)],
                    });
                    won = false;
                } else {
                    buttons.forEach((b) => {
                        if (b.customId === "low") b.setStyle(ButtonStyle.Success);
                    });
                    await i.editReply({
                        content: `You are right! It was ${randomNumber}`,
                        components: [new ActionRowBuilder().addComponents(buttons)],
                    });
                    won = true;
                }
            } else if (i.customId === "correct" && hintNumber === randomNumber) {
                buttons.forEach((b) => {
                    if (b.customId === "correct") b.setStyle(ButtonStyle.Success);
                });
                await i.editReply({
                    content: `You guessed the number! It was ${randomNumber}`,
                    components: [new ActionRowBuilder().addComponents(buttons)],
                });
                won = true;
            } else {
                await i.editReply({
                    content: `Sadge, you got it wrong! It was ${randomNumber}`,
                    components: [new ActionRowBuilder().addComponents(buttons)],
                });
                won = false;
            }
        });
        collector.on("end", async (collected) => {
            if (!won && collected.size === 0) {
                buttons.forEach((b) => b.setDisabled(true));
                await i.editReply({
                    content: `You didn't guess the number! It was ${randomNumber}`,
                    components: [new ActionRowBuilder().addComponents(buttons)],
                });
            }
        });
    },
};

I would really appreciate since I've been struggling with this code for a while and I'm pretty new to slash commands and the latest version of discord.js :).


Solution

  • Your buttons are stored as an array in the components property of your row. Thus b.setDisabled is undefined and returns an error.

    Like this:

    row.components.forEach(button => button.setDisabled(true));
    

    Also make sure that when you reply to your interaction you change .addComponents(buttons) to:

    await i.editReply({
      content: `Sadge, you got it wrong! It was ${randomNumber}`,
      components: [new ActionRowBuilder().addComponents(row)], // or [row]
    });