Discord.js:交互已被确认。不和谐按钮

发布于 2025-01-16 20:00:17 字数 3831 浏览 4 评论 0原文

我正在尝试为我的 Discord 机器人制作扑克命令,并且我想使用 Discord 按钮实现回合系统。现在的命令是:

  1. 有人使用命令
  2. 机器人发送带有加入按钮的嵌入
  3. 如果按下加入,玩家元素将被推入玩家数组
  4. 如果单击开始比赛,机器人会在 dm 中发送卡片
  5. 然后机器人会询问每个玩家如果他们想按顺序做什么
  6. 如果玩家选择,机器人就会崩溃并向我发送以下错误:DiscordAPIError:交互已被确认。

我不知道是什么导致了问题。这是代码:

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], });
        });
    }
});

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:

  1. Someone uses the command
  2. The bot sends an embed with a button to join
  3. If join is pressed the player element gets pushed into players array
  4. If start match is clicked, the bot sends cards in dm
  5. Then the bot asks each player if what they want to do in order
  6. 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], });
        });
    }
});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

甜妞爱困 2025-01-23 20:00:17

您应该添加一个诊断不和谐 api 错误的函数。将其添加到“index.js”文件中的任意位置。

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);
});

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);
});

不打扰别人 2025-01-23 20:00:17

matchCollector 中的 int 对象是一个 按钮交互。因此,您无法编辑回复,因为您没有回复。相反,如果您想编辑按钮所在位置的消息,则需要使用 ButtonInteraction#update 方法:

int.update({ embeds: [matchEmbed], components: [matchRow] });

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] });
小…红帽 2025-01-23 20:00:17

您正在推迟交互的更新,而应该推迟交互的回复

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], });
});

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], });
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文