'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 |