skip to Main Content

I have 2 slash commands in Discordjs.
In both commands I have a button and a collector like this :

const message = await interaction.reply({ components: [row] });
const collector = message.createMessageComponentCollector({ComponentType: ComponentType.Button});
collector.on('collect', async (i) => {}

If I understand correctly, it should only collect interactions within the message.
But in my case, if user1 type /command1 and user2 type /command2 and then user2 click on the button of /command1, the code from the collector of the button of /command2 can be executed

ex :

/command1 :
async execute(interaction: any) {
 const button = new ButtonBuilder().setLabel('Command 1').setStyle(ButtonStyle.Primary).setCustomId(`command1`);
 const row = new ActionRowBuilder().addComponents(button);
 const message = await interaction.reply({ components: [row] });
 const collector = message.createMessageComponentCollector({ComponentType: ComponentType.Button});
 collector.on('collect', async (i) => {i.reply('collector 1')}
}
/command2 :
async execute(interaction: any) {
 const button = new ButtonBuilder().setLabel('Command 2').setStyle(ButtonStyle.Primary).setCustomId(`command2`);
 const row = new ActionRowBuilder().addComponents(button);
 const message = await interaction.reply({ components: [row] });
 const collector = message.createMessageComponentCollector({ComponentType: ComponentType.Button});
 collector.on('collect', async (i) => {i.reply('collector 2')}
}

In the scenario I wrote before, if user2 click on button of /command1 from user1, the bot will reply

collector 2

It actually sometimes reply collector 1 so I think both collectors are being triggered and I get the error DiscordAPIError[10062]: Unknown interaction from the second collector trying to reply at the same time.

Shouldn’t createMessageComponentCollector collect interaction from only one specific message ? Why are both collectors being triggered ?

I can write something like if (i.customId != 'command1') return; in the collector but I feel like it shouldn’t be needed? It also doesn’t fix collectors of same /command that will all be triggered too, and have to add a bunch of filters to every collectors I make which is not practical.

Thank you

2

Answers


  1. Chosen as BEST ANSWER

    Found the solution. This is wrong :

    const message = await interaction.reply({ components: [row] });
    const collector = message.createMessageComponentCollector({ComponentType: ComponentType.Button});
    

    This is correct :

    await interaction.reply({ components: [row] });
    const message = interaction.fetchReply();
    const collector = message.createMessageComponentCollector({ComponentType: ComponentType.Button});
    

    It's working as expected now.


  2. You could use a filter to ignore unwanted interactions.

    Here’s an example I modified from the docs (it’s untested, be forewarned):

    // make sure the interaction's message is the correct message
    const filter = (interaction) => interaction.message.id === message.id;
    
    const collector = message.createMessageComponentCollector({ filter, time: 15_000 });
    collector.on('collect', i => console.log(`Collected ${i.customId}`));
    collector.on('end', collected => console.log(`Collected ${collected.size} items`));
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search