英文:
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('collect')
", 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: ''
}).then((m) => {
m.delete();
});
This is my full code as of now :
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;
}
}
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("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!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论