I'm trying to make a Poker command for my Discord bot, and I want to implement turn system with Discord buttons. The command for now is:
- Someone uses the command
- The bot sends an embed with a button to join
- If join is pressed the player element gets pushed into players array
- If start match is clicked, the bot sends cards in dm
- Then the bot asks each player if what they want to do in order
- If the player chooses, the bot crashes and send me this error:
DiscordAPIError: Interaction has already been acknowledged.
I don't know what is causing the problem. Here's code:
const players = [new Player(interaction.user.id, interaction.user.username)];
const hasJoined = [interaction.user];
const playerRow = new Discord.MessageActionRow().addComponents(
new Discord.MessageButton().setCustomId("join").setLabel("Join").setStyle("SUCCESS"),
new Discord.MessageButton().setCustomId("start").setLabel("Start Game").setStyle("SUCCESS")
);
const playerEmbed = new Discord.MessageEmbed()
.setTitle(`${interaction.user.username} started a game of Poker Texas hold'em! \nClick the button if you wanna join!`)
.setAuthor({ name: `${interaction.user.username}`, iconURL: interaction.user.displayAvatarURL({ format: "png"})})
.setDescription(`**players:** \n${codeLine(players.map(a => a.name).join("\n"))}`)
interaction.reply({ embeds: [playerEmbed], components: [playerRow] });
const collector = interaction.channel.createMessageComponentCollector({ time: 90000 });
collector.on("collect", async (i) => {
await i.deferUpdate();
if (i.customId == "join") {
//if (hasJoined.includes(i.user)) return i.editReply(`You are already in game ${i.user}!`);
players.push(new Player(i.user.id, i.user.username));
hasJoined.push(i.user);
playerEmbed.setDescription(`**Players:** \n${codeLine(hasJoined.map(a => a.username).join("\n"))}`);
interaction.editReply({ embeds: [playerEmbed], components: [playerRow] });
if (hasJoined.length == 8) playerRow.components[0].setDisabled(true);
}
if (i.customId == "start") collector.stop();
});
collector.on("end", async () => {
for (let i = 0; i < players.length; i++) {
const rcard1 = chance.pickone(deck);
deck.splice(deck.indexOf(rcard1), 1);
const rcard2 = chance.pickone(deck);
deck.splice(deck.indexOf(rcard2), 1);
players[i].card1 = rcard1;
players[i].card2 = rcard2;
client.users.fetch(players[i].id).then((user) => {
user.send(`here you are ${players[i].name}! These are your cards: ${players[i].card1.emoji} ${players[i].card2.emoji}.`);
});
}
const matchRow = new Discord.MessageActionRow().addComponents(
new Discord.MessageButton().setCustomId("stand").setLabel("Stand").setStyle("SECONDARY"),
new Discord.MessageButton().setCustomId("double").setLabel("Double").setStyle("SECONDARY"),
new Discord.MessageButton().setCustomId("fold").setLabel("Fold").setStyle("DANGER")
);
const matchEmbed = new Discord.MessageEmbed()
.setTitle("**Texas hold'em!**")
.setDescription(`The Small Blind is ${codeLine(players[0].name)} and they bet ${codeLine(bet)} bananas!
The Large Blind is ${codeLine(players[1].name)} and they double! So ${codeLine(bet * 2)} bananas!`);
await interaction.editReply({ embeds: [matchEmbed], components: [matchRow] });
for (let i = 0; i < players.length; i++) {
const playerFilter = (pInt) => { return pInt.user.id == players[i].id}
const matchCollector = interaction.channel.createMessageComponentCollector({ playerFilter, time: 90000 });
matchCollector.on("collect", async (int) => {
await int.deferUpdate();
if (int.customId == "fold") {
matchEmbed.setDescription(`${codeLine(players[i].name)} folded!`);
players.splice(players[i], 1);
}
int.editReply({ embeds: [matchEmbed], components: [matchRow], });
});
}
});