'Discord.js Bot can't handle multiple buttons in the same channel (Version 13)

Is there a way to have a command with buttons be used by two people at the same time in the same channel?

I made an adventure system which is going well so far, but I found out that only one person can use it in a channel. If another person uses it in the same channel, the "DiscordAPIError: Unknown Interaction" error comes as soon as a button is used. I tried adding the message author's id to the custom ID of the buttons, but it still doesn't work for some reason and I am utterly confused.

From what I understand, I think it's unrelated to there being multiple button instances, but I can't think of any other reason. Here is the filter:

const filter = async (interaction) => {
        if (interaction.user.id === message.author.id) return true;
        await interaction.deferReply()
        await interaction.editReply({ content: `**${interaction.user.username}**, You can't use this button!`, ephemeral: true})
        return false
    }

And the button click detector goes something like this:

GameCollect.on('collect', async ButtonInteraction => {
            ButtonInteraction.deferUpdate()
            // My code
})

I have tried:

  • Removing ButtonInteraction.deferUpdate() from all my click collectors.

  • Making the custom ids for the buttons have the message author's id at the end and making my code compatible with that change.

  • Smashing my head on my keyboard from confusion. Didn't work either... (satire)

If it's necessary, I can copy my code into a repl so that you can identify the problem easier, but I don't think the other portions would have any effect on this. I think it's just a piece of code/slight adjustment that I have to add for it to work with two people in the same channel.

EDIT: Alright, here is a source bin so that you can identify the problem better. Check the comments on the recent answer for some clarifications on my testing too. I will keep you updated if I find a solution.

DISCLAIMER: I still haven't found a way to make this work in over a month, and I am essentially just giving up on buttons. Thank you to everyone who helped though.



Solution 1:[1]

Try it:

  • Remove await interaction.deferReply() from filter
  • Create dynamic customIds like Math.random()

EDIT:

  • description: i had the same issue recently on my own bot, The problem is that when 2 messages that the have collectors(basically they're waiting for a interaction), if you call await interaction.deferReply() soon, it wil get messy, So here's the solution
  • First of all lets go for the filter function for checking the interaction, We need 2 things:
    • Checking the button id with the incoming interaction button id
    • Checking the user to be the real one
  • After all of these
    • delete deferReply from the filter func, Because when you didn't check the interactions, calling deferReply, will call both of messages or all of the messages that are waiting for interaction
    • add the deferReply to the function that is after filter

And don't remember to use random ids for components(Buttons, select menus and ...)

Solution 2:[2]

Instead of creating a collector on the text channel, you should create the collector on the actual message

const GameCollect = message.channel.createMessageComponentCollector({ filter, time: 60000 * 15 })

To

const GameCollect = <Message>.createMessageComponentCollector({ filter, time: 60000 * 15 })

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Hackel