javascriptdiscorddiscord.jsdiscord-buttons

Discord.js collecting multiple interactions on multiple sets of buttons


I have a Discord.js bot that allows users to vote on the outcome of games. The admin uses a slash command that sends a message with 2 buttons attached representing the 2 possible votes. There will often be more than 1 game to vote on at a time. I am handling the interactions like this:

interaction.client.on("interactionCreate", async (i) => {
            if (!i.isButton()) return;

            let team; 

            try {
                if (i.customId === 'team1Button' || i.customId === 'team2Button') {
                    await i.deferReply({ ephemeral: true });
                    // Handle team vote 
                    team = await getTeamEmoji(i.message.id, i.customId); // Assign value to team variable
                    await castVote(team.name, i.user.username, i.message.id);
                    // Reply to interaction
                    await i.editReply({
                        content: `Vote for ${team.emoji} submitted.`,
                        ephemeral: true,
                    });
                }
            } catch (error) {
                console.error("Interaction handling error:", error);
                logError(error, i.message.id, i.user.username, 'Interaction handling error: ' + i);
            }
        });

So this works. The bot never crashes and votes do go through. However, if there are 2 active games (meaning 2 messages with 2 buttons each) my error log starts to fill up with these:

error
"DiscordAPIError[10062]: Unknown interaction"

or

error
"DiscordAPIError[40060]: Interaction has already been acknowledged."

The 1st game posted several people can vote at one time and all is perfect. 2nd game posted everything works successfully but everyone gets 1 error logged that is one of the above errors. 3rd game posted everything still works but everyone gets 2 errors this time when they vote. 4th game everyone gets 3 errors when they vote and so on..

There are far more Unknown interaction errors than Interaction has already been acknowledged.

This is my error logger function:

async function logError(error, message, user, description) {
    try {
        const today = new Date();
        const formattedDate = today.toLocaleDateString(); // e.g., "09/18/2023" (format may vary depending on your system's locale)
        const errorString = error instanceof Error ? error.toString() : String(error); // Convert error object to string

        data = {
            date: formattedDate,
            error: errorString,
            message: message,
            user: user,
            status: 'Open',
            description: description
        }
        const errorCollectionRef = collection(db, 'ErrorLog');
        await addDoc(errorCollectionRef, data);
    } catch (error) {
        console.error('An error occurred in logError:', error);
    }
}

So why is my error log getting filled with these error messages even though everything is working correctly? How can I resolve this? Is it a problem with how I am handling interactions or a problem with my error logging?


Solution

  • I think the problem comes from waiting longer than 3 seconds. Discord interactions must respond within 3 seconds, otherwise the interaction ends and an error is returned.

    Your retryOperation() has 1s or more delay so higher than 3 seconds in most of the case probably.

    You can avoid this by defer the reply:

    await i.deferReply({ ephemeral: true });
    

    It would look like this. Please note, edit your reply into an editReply to avoid error

    interaction.client.on("interactionCreate", async (i) => {
        if (!i.isButton()) return;
    
        let team; 
    
        try {
            if (i.customId === 'team1Button' || i.customId === 'team2Button') {
                await i.deferReply({ ephemeral: true });
                // Handle team vote with retry mechanism
                await retryOperation(async () => {
                    team = await getTeamEmoji(i.message.id, i.customId); // Assign value to team variable
                    await castVote(team.name, i.user.username, i.message.id);
                }, 3, i.message.id, i.user.username); // Retry team vote operation up to 3 times
    
                // Reply to interaction
                await i.editReply({
                    content: `Vote for ${team.emoji} submitted.`,
                    ephemeral: true,
                });
            }
        } catch (error) {
            console.error("Interaction handling error:", error);
            logError(error, i.message.id, i.user.username, 'Interaction handling error: ' + i);
        }
    });
    

    For your second error, Interaction has already been acknowledged this may come from a duplicate instance of your bot. So check that if your bot run in only one terminal (local or remote)