Discord.js v14 分页需要使用 deferReply(),但它会一直发送“Bot is thinking…..”。

huangapple go评论60阅读模式
英文:

Discord.js v14 Pagination requiring deferReply() but it sends "Bot is thinking....." forever

问题

我正在使用JavaScript制作一个基于discord.js v14的机器人,并尝试按照此教程制作嵌入式分页。但在教程中,他们在“collector.on('collect')”中的“if condition”之后添加了“i.deferReply();”,但当我做同样的操作时,它会发送“Bot is thinking...”消息,该消息不会消失,其中的按钮也无法工作。

如果我删除deferReply方法并在嵌入中单击按钮,则需要一些时间才能更新嵌入,但会显示“This interaction failed”,即使嵌入已更新。

所以,我尝试了一种发送空白消息(零宽度Unicode字符)的方法:

i.reply({
    content: '​'
}).then((m) => {
    m.delete();
});

这是我的完整代码:

const { ActionRowBuilder, ButtonBuilder, ButtonStyle, ComponentType, EmbedBuilder } = require('discord.js');

module.exports = {
    async execute(interaction, pages, time = 60000) {
        await interaction.deferReply();

        if (pages.length == 1) {
            const page = interaction.editReply({
                embeds: [pages],
                components: [],
                fetchReply: true
            });

            return page;
        }

        const prev = new ButtonBuilder()
            .setCustomId('prev')
            .setEmoji('◀️')
            .setStyle(ButtonStyle.Primary)
            .setDisabled(true)

        const home = new ButtonBuilder()
            .setCustomId('home')
            .setEmoji('🏠')
            .setStyle(ButtonStyle.Secondary)
            .setDisabled(true)

        const next = new ButtonBuilder()
            .setCustomId('next')
            .setEmoji('▶️')
            .setStyle(ButtonStyle.Primary)

        const buttonRow = new ActionRowBuilder()
            .addComponents(prev, home, next)
        let index = 0;

        let currentPage = await interaction.editReply({
            embeds: [pages[index]],
            components: [buttonRow],
            fetchReply: true
        });

        const collector = await currentPage.createMessageComponentCollector({
            componentType: ComponentType.Button,
            time
        });

        collector.on('collect', async (i) => {
            if (i.user.id != interaction.user.id) {
                const embed = new EmbedBuilder()
                    .setDescription('You can\'t use these buttons!')

                return i.reply({
                    embeds: [embed],
                    ephemeral: true
                });
            }

            i.reply({
                content: '​'
            }).then((m) => {
                m.delete();
            });

            if (i.customId == 'prev') {
                if (index > 0) index--;
            } else if (i.customId == 'home') {
                index = 0;
            } else if (i.customId == 'next') {
                if (index < pages.length - 1) index++;
            }

            if (index == 0) prev.setDisabled(true);
            else prev.setDisabled(false);

            if (index == 0) home.setDisabled(true);
            else home.setDisabled(false);

            if (index == pages.length - 1) next.setDisabled(true);
            else next.setDisabled(false);

            await currentPage.edit({
                embeds: [pages[index]],
                components: [buttonRow]
            });

            collector.resetTimer();
        });

        collector.on('end', async (i) => {
            await currentPage.edit({
                embeds: [pages[index]],
                components: []
            });
        });
        return currentPage;
    }
}

请帮忙查看是否有可能不发送空白消息的方法。任何帮助将不胜感激。

英文:

I am making a discord.js v14 bot using Javascript and was trying to make embed pagination by following this tutorial. But in the tutorial they add "i.deferReply();" after the "if condition" in "collector.on(&#39;collect&#39;)", but when I am doing the same, it sends "Bot is thinking..." message that doesn't go away and the buttons in it also do not work.

If I remove the deferReply method and click a button in the embed, it takes some time then updates the embed but shows "This interaction failed" even though the embed was updated.

So, I tried and came up with this method of sending a blank message (zero width unicode character) :

i.reply({
    content: &#39;&#39;
}).then((m) =&gt; {
    m.delete();
});

This is my full code as of now :

const { ActionRowBuilder, ButtonBuilder, ButtonStyle, ComponentType, EmbedBuilder } = require(&#39;discord.js&#39;);

module.exports = {
    async execute(interaction, pages, time = 60000) {
        await interaction.deferReply();

        if (pages.length == 1) {
            const page = interaction.editReply({
                embeds: [pages],
                components: [],
                fetchReply: true
            });

            return page;
        }

        const prev = new ButtonBuilder()
            .setCustomId(&#39;prev&#39;)
            .setEmoji(&#39;◀️&#39;)
            .setStyle(ButtonStyle.Primary)
            .setDisabled(true)

        const home = new ButtonBuilder()
            .setCustomId(&#39;home&#39;)
            .setEmoji(&#39;&#127968;&#39;)
            .setStyle(ButtonStyle.Secondary)
            .setDisabled(true)

        const next = new ButtonBuilder()
            .setCustomId(&#39;next&#39;)
            .setEmoji(&#39;▶️&#39;)
            .setStyle(ButtonStyle.Primary)

        const buttonRow = new ActionRowBuilder()
            .addComponents(prev, home, next)
        let index = 0;

        let currentPage = await interaction.editReply({
            embeds: [pages[index]],
            components: [buttonRow],
            fetchReply: true
        });

        const collector = await currentPage.createMessageComponentCollector({
            componentType: ComponentType.Button,
            time
        });

        collector.on(&#39;collect&#39;, async (i) =&gt; {
            if (i.user.id != interaction.user.id) {
                const embed = new EmbedBuilder()
                    .setDescription(&#39;You can\&#39;t use these buttons!&#39;)

                return i.reply({
                    embeds: [embed],
                    ephemeral: true
                });
            }

            i.reply({
                content: &#39;&#39;
            }).then((m) =&gt; {
                m.delete();
            });

            if (i.customId == &#39;prev&#39;) {
                if (index &gt; 0) index--;
            } else if (i.customId == &#39;home&#39;) {
                index = 0;
            } else if (i.customId == &#39;next&#39;) {
                if (index &lt; pages.length - 1) index++;
            }

            if (index == 0) prev.setDisabled(true);
            else prev.setDisabled(false);

            if (index == 0) home.setDisabled(true);
            else home.setDisabled(false);

            if (index == pages.length - 1) next.setDisabled(true);
            else next.setDisabled(false);

            await currentPage.edit({
                embeds: [pages[index]],
                components: [buttonRow]
            });

            collector.resetTimer();
        });

        collector.on(&#39;end&#39;, async (i) =&gt; {
            await currentPage.edit({
                embeds: [pages[index]],
                components: []
            });
        });
        return currentPage;
    }
}

Please help if any way of not sending a blank message is possible. Any help will be appreciated.

答案1

得分: 1

Your i.deferReply() creates a new message with a "Bot is thinking ..." message, as it waits for a reply. Whereas not deferring it suggests shows the "failed" message. This is because your bot has not replied to this interaction, so Discord assumes that it broke and didn't respond before breaking.

Discord.JS will resolve the defer or interaction when you call one of the following in the interaction (your i variable):

  • reply() - Does not work with deferred messages.
  • editReply()
  • deferReply()
  • fetchReply()
  • deleteReply()
  • followUp()

So how can we solve it? We could send a message (thus resolving the message) and remove it again. You can remove your defer reply, and replace it like so:

i.reply("We got your interaction!")
.then((msg) => { 
  setInterval(() => {
    msg.delete()
  }, 3000)
});

Let's break this down. It sends the message "We got your interaction", and once it has sent, it gets the message that it sent, waits 3 seconds (3000 ms) and deletes it again. It has resolved the defer, but has also removed the message to reduce clutter in your channel.

Bonus Tip: You can send the message only to the person who interacted by changing the ephemeral option to true, changing the i.reply like accordingly:

i.reply({content: "We got your interaction", ephemeral: true})

Happy coding!

英文:

Your i.deferReply() creates a new message with a "Bot is thinking ..." message, as it waits for a reply. Whereas not deferring it suggests shows the "failed" message. This is because your bot has not replied to this interaction, so Discord assumes that it broke and didn't respond before breaking.

Discord.JS will resolve the defer or interaction when you call one of the following in the interaction (your i variable):

  • reply() - Does not work with deferred messages.
  • editReply()
  • deferReply()
  • fetchReply()
  • deleteReply()
  • followUp()

So how can we solve it? We could send a message (thus resolving the message) and remove it again. You can remove your defer reply, and replace it like so:

i.reply(&quot;We got your interaction!&quot;)
.then((msg) =&gt; { 
  setInterval(() =&gt; {
    msg.delete()
  }, 3000)
});

Let's break this down. It sends the message "We got your interaction", and once it has sent, it gets the message that it sent, waits 3 seconds (3000 ms) and deletes it again. It has resolved the defer, but has also removed the message to reduce clutter in your channel.

Bonus Tip: You can send the message only to the person who interacted by changing the ephemeral option to true, changing the i.reply like accordingly:

i.reply({content: &quot;We got your interaction&quot;, ephemeral: true})

Happy coding!

huangapple
  • 本文由 发表于 2023年6月16日 03:03:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/76484777.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定