Search code examples
javascriptdiscord.js

Interaction has already been acknowledged when responding to the second embed after the first embed, button discord.js


There's a ton of threads there already I know but I still can't get it to work. I'm building an embed with a button. The embed appears using command $test. The error happens when I trigger the embed for the second time (2nd $test) and click the button after clicking the button on the first trigger.

This flow should work but the error "Interaction has already been acknowledged" triggers.

Steps:

  1. Type $test to show the embed.
  2. User clicks "Click me." button on the embed.
  3. The embed updates to embed2 confirming the click on the button.
  4. Type $test again to show the embed.
  5. User clicks "Click me." button on the embed.

Result: Interaction has already been acknowledged.

Expected Result: The 2nd embed should be totally new. It should not remember my first interaction on the 1st embed.

Should I use .reply() instead of .update()? Does that matter?

I read a post saying this:

Interaction has already been acknowledged happens when you try to reply to the interaction that you already replied, and you can fix it by using .editReply() after you .reply() the interaction.

Here's the code:

client.on("messageCreate", (message) => {
  if (command === "test") {
    const button = new ActionRowBuilder()
    .addComponents(
    new ButtonBuilder()
    .setCustomId("button1")
    .setLabel("Click me.")
    .setStyle(ButtonStyle.Secondary)
  );

  const embed = new EmbedBuilder()
    .setColor("#5A5A5A")
    .setTitle("Embed")
    .setDescription("Did you receive this message? Click button if you did.")

  const embed2 = new EmbedBuilder()
    .setColor("#5A5A5A")
    .setTitle("Confirmation Embed")
    .setDescription("Thanks for confirming!")

  message.channel.send({embeds:[embed], components:[button]});

  const collector = message.channel.createMessageComponentCollector();

  collector.on("collect", (i) => {
    if(i.customId === "button1") {
      i.update({embeds: [embed2], components:[]});
    }
  })
});

Solution

  • the collector is in the channel you should tie it to the message

    
    client.on("messageCreate", async (message) => {
      if (command === "test") {
        const button = new ActionRowBuilder()
        .addComponents(
        new ButtonBuilder()
        .setCustomId("button1")
        .setLabel("Click me.")
        .setStyle(ButtonStyle.Secondary)
      );
    
      const embed = new EmbedBuilder()
        .setColor("#5A5A5A")
        .setTitle("Embed")
        .setDescription("Did you receive this message? Click button if you did.")
    
      const embed2 = new EmbedBuilder()
        .setColor("#5A5A5A")
        .setTitle("Confirmation Embed")
        .setDescription("Thanks for confirming!")
    
      const msg = await message.channel.send({embeds:[embed], components:[button]});
    
      const collector = msg.createMessageComponentCollector();
    
      collector.on("collect", (i) => {
        if(i.customId === "button1") {
          i.update({embeds: [embed2], components:[]});
        }
      })
    });