Reputation: 393
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:
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], });
});
}
});
Upvotes: 3
Views: 3090
Reputation: 1
You're deferring the update of the interaction, you should instead defer the reply of the interaction
matchCollector.on("collect", async (int) => {
await int.deferReply();
if (int.customId == "fold") {
matchEmbed.setDescription(`${codeLine(players[i].name)} folded!`);
players.splice(players[i], 1);
}
int.editReply({ embeds: [matchEmbed], components: [matchRow], });
});
Upvotes: 0
Reputation: 21
You should add an function that diagnoses discord api errors. Add this anywhere on your "index.js" file.
process.on("unhandledRejection", async (err) => {
console.error("Unhandled Promise Rejection:\n", err);
});
process.on("uncaughtException", async (err) => {
console.error("Uncaught Promise Exception:\n", err);
});
process.on("uncaughtExceptionMonitor", async (err) => {
console.error("Uncaught Promise Exception (Monitor):\n", err);
});
process.on("multipleResolves", async (type, promise, reason) => {
console.error("Multiple Resolves:\n", type, promise, reason);
});
Upvotes: 2
Reputation: 1
Your int
object that comes in your matchCollector
is a ButtonInteraction. Thus, you can't edit a reply, because you don't have a reply. Instead, if you want to edit the message where is located the Button, you need to use the ButtonInteraction#update method:
int.update({ embeds: [matchEmbed], components: [matchRow] });
Upvotes: 0