Discord.js v14按钮分页指南报错:无法编辑未发送消息
问题描述
我想要制作如下样式的分页指南:
我希望通过消息下方的按钮来编辑Embed内容,但运行代码时出现错误,提示消息从未发送,无法编辑任何内容!
Embed/斜杠命令代码:
const { SlashCommandBuilder, EmbedBuilder, ButtonBuilder, ActionRowBuilder, SelectMenuBuilder, ButtonStyle } = require('discord.js') ; module.exports = { data: new SlashCommandBuilder() .setName('tutorial') .setDescription('Start the tutorial'), async execute(interaction, client) { const embed = new EmbedBuilder() .setColor(0x991be2) .setTitle('Tutorial') .setDescription('Welcome to the tutorial!') //all the buttons to change the page const buttons = new ActionRowBuilder() .addComponents( new ButtonBuilder() .setCustomId('no1') .setEmoji('1029435230668476476') .setDisabled(true) .setStyle(ButtonStyle.Primary), new ButtonBuilder() .setCustomId('no2') .setEmoji('1029435199462834207') .setDisabled(true) .setStyle(ButtonStyle.Primary), new ButtonBuilder() .setCustomId('page') .setLabel('setup') .setDisabled(true) .setStyle(ButtonStyle.Secondary), new ButtonBuilder() .setCustomId('step1') .setEmoji('1029435213157240892') .setStyle(ButtonStyle.Primary), new ButtonBuilder() .setCustomId('last') .setEmoji('1029435238948032582') .setStyle(ButtonStyle.Primary) ) await interaction.reply({ content: '', embeds: [embed], components: [buttons], ephemeral: false }) } }
自定义ID为'step1'的按钮代码:
//when the button with the right arrow is pressed('step1') //then it should edit the embed to Step One of the tutorial! const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js") module.exports = { data: { name: 'step1' }, async execute(interaction, client) { // test embed const embed = new EmbedBuilder() .setColor(0x00acee) .setTitle('Step One') .addFields( { name: 'a', value: 'a' }, { name: 'a', value: 'a' }, { name: 'a', value: 'a' }, ) const buttons = new ActionRowBuilder() .addComponents( new ButtonBuilder() .setCustomId('no1') .setEmoji('1029435230668476476') .setDisabled(true) .setStyle(ButtonStyle.Primary), new ButtonBuilder() .setCustomId('step1') .setEmoji('1029435199462834207') .setDisabled(false) .setStyle(ButtonStyle.Primary), //This button shows what step you are at as you can see on the label. new ButtonBuilder() .setCustomId('page') .setLabel('setup') .setDisabled(true) .setStyle(ButtonStyle.Secondary), new ButtonBuilder() .setCustomId('step2') .setEmoji('1029435213157240892') .setStyle(ButtonStyle.Primary), new ButtonBuilder() .setCustomId('last') .setEmoji('1029435238948032582') .setStyle(ButtonStyle.Primary) ) await interaction.editReply({ content: '', embeds: [embed], components: [buttons], ephemeral: false }) } }
我该如何解决?
解决方案
核心问题原因
按钮交互代码中使用的 interaction.editReply() 用于编辑当前交互自身发送的回复,但按钮触发的交互从未调用过 reply() 发送消息,因此会抛出“消息从未发送”的错误。要修改按钮所在的原消息(斜杠命令发送的带Embed和按钮的消息),需使用 interaction.update() 方法,它专门用于更新触发交互的组件所在的消息。
修改后的按钮代码
将按钮执行函数中的 interaction.editReply() 替换为 interaction.update(),同时移除无效的 ephemeral 参数(update() 不支持该参数,原消息可见性已由初始回复确定):
//when the button with the right arrow is pressed('step1') //then it should edit the embed to Step One of the tutorial! const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js") module.exports = { data: { name: 'step1' }, async execute(interaction, client) { // test embed const embed = new EmbedBuilder() .setColor(0x00acee) .setTitle('Step One') .addFields( { name: 'a', value: 'a' }, { name: 'a', value: 'a' }, { name: 'a', value: 'a' } ) const buttons = new ActionRowBuilder() .addComponents( new ButtonBuilder() .setCustomId('no1') .setEmoji('1029435230668476476') .setDisabled(true) .setStyle(ButtonStyle.Primary), new ButtonBuilder() .setCustomId('step1') .setEmoji('1029435199462834207') .setDisabled(false) .setStyle(ButtonStyle.Primary), //This button shows what step you are at as you can see on the label. new ButtonBuilder() .setCustomId('page') .setLabel('setup') .setDisabled(true) .setStyle(ButtonStyle.Secondary), new ButtonBuilder() .setCustomId('step2') .setEmoji('1029435213157240892') .setStyle(ButtonStyle.Primary), new ButtonBuilder() .setCustomId('last') .setEmoji('1029435238948032582') .setStyle(ButtonStyle.Primary) ) // 替换为update方法,移除ephemeral参数 await interaction.update({ content: '', embeds: [embed], components: [buttons] }) } }
额外检查项
- 确保机器人主文件中正确注册了按钮交互处理器,示例代码如下:
client.on('interactionCreate', async interaction => { if (interaction.isChatInputCommand()) { // 处理斜杠命令 const command = client.commands.get(interaction.commandName); if (!command) return; try { await command.execute(interaction, client); } catch (error) { console.error(error); await interaction.reply({ content: '执行命令时出错!', ephemeral: true }); } } else if (interaction.isButton()) { // 处理按钮交互 const button = client.buttons.get(interaction.customId); if (!button) return; try { await button.execute(interaction, client); } catch (error) { console.error(error); await interaction.reply({ content: '处理按钮时出错!', ephemeral: true }); } } });
- 确认按钮模块已正确加载到
client.buttons集合中,否则机器人无法识别按钮的自定义ID。
内容的提问来源于stack exchange,提问作者Leo Turlock
相关产品推荐
相关产品推荐

