You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord.js v14按钮嵌入交互失败求助:点击按钮显示交互失败

问题与解决:Discord.js v14 按钮切换Embed报错处理

问题说明

  • 当前使用Discord.js v14,纠结是否要换回v13
  • 目标:实现Slash命令,通过按钮切换Embed内容
  • 异常:点击按钮后Discord提示“Interaction failed”,控制台无任何报错信息

原代码

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

module.exports = {
    data: new SlashCommandBuilder()
    .setName('testeando')
    .setDescription('test'),
    async execute(interaction, client) {
        const message = await interaction.deferReply({
            fetchReply: true
        });
        
        const embed = new EmbedBuilder()
            .setTitle('Test embed')
            .setDescription('Hola que ondaaaa');

        const embed2 = new EmbedBuilder()
            .setTitle('Seeee')
            .setDescription('Hola que ondaaaa');

        const row = new ActionRowBuilder()
            .addComponents(
                new ButtonBuilder()
                    .setLabel('Boton 1')
                    .setStyle(ButtonStyle.Primary)
                    .setCustomId('button1'),
                new ButtonBuilder()
                    .setLabel('Boton 2')
                    .setStyle(ButtonStyle.Secondary)
                    .setCustomId('button2'),
                new ButtonBuilder()
                    .setLabel('Boton 3')
                    .setStyle(ButtonStyle.Success)
                    .setCustomId('button3'),
            )

            
        await interaction.editReply({
            embeds: [embed], components: [row]
        });
        
        const filter = i => i.customId === 'button1' || i.customId === 'button2';
        const collector = interaction.channel.createMessageCollector({ filter, time: 15000 });
        
        collector.on('collect', async i => {
            await i.deferUpdate();
    
            if (i.customId === 'button1') {
                await interaction.editReply({ embeds: [embed], components: [row] });
            } else if (i.customId === 'button2') {
                await interaction.editReply({ embeds: [embed2], components: [row] });
            }

            collector.on('end', async () => {
                await interaction.editReply({ components: [] });
            });
        });
    }
}

错误分析

  1. 收集器类型错误:使用了createMessageCollector(监听频道消息的收集器),而非createMessageComponentCollector(专门处理按钮、选择菜单等组件交互的收集器),导致按钮点击事件未被正确捕获。
  2. 事件绑定位置错误:collector.on('end')被放在collect事件的回调内,每次收集到交互都会重复绑定end事件,引发逻辑混乱。
  3. 过滤器覆盖不全:过滤器只包含button1和button2,但存在button3,点击后交互未被处理,触发Discord的“Interaction failed”提示。

修正后的代码

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

module.exports = {
    data: new SlashCommandBuilder()
        .setName('testeando')
        .setDescription('test'),
    async execute(interaction, client) {
        // 延迟回复,避免超时
        await interaction.deferReply({ fetchReply: true });
        
        // 定义两个切换用的Embed
        const embed1 = new EmbedBuilder()
            .setTitle('Test embed')
            .setDescription('Hola que ondaaaa');

        const embed2 = new EmbedBuilder()
            .setTitle('Seeee')
            .setDescription('Hola que ondaaaa');

        // 构建按钮行
        const row = new ActionRowBuilder()
            .addComponents(
                new ButtonBuilder()
                    .setLabel('Boton 1')
                    .setStyle(ButtonStyle.Primary)
                    .setCustomId('button1'),
                new ButtonBuilder()
                    .setLabel('Boton 2')
                    .setStyle(ButtonStyle.Secondary)
                    .setCustomId('button2'),
                new ButtonBuilder()
                    .setLabel('Boton 3')
                    .setStyle(ButtonStyle.Success)
                    .setCustomId('button3'),
            );

        // 发送初始回复
        await interaction.editReply({ embeds: [embed1], components: [row] });

        // 创建组件交互收集器,绑定到当前回复消息,仅允许发起命令的用户操作
        const filter = i => ['button1', 'button2', 'button3'].includes(i.customId) && i.user.id === interaction.user.id;
        const collector = interaction.editReply.message.createMessageComponentCollector({ filter, time: 15000 });

        // 处理收集到的交互
        collector.on('collect', async i => {
            // 标记交互已接收,避免超时
            await i.deferUpdate();

            // 根据按钮ID切换Embed
            switch(i.customId) {
                case 'button1':
                    await i.editReply({ embeds: [embed1], components: [row] });
                    break;
                case 'button2':
                    await i.editReply({ embeds: [embed2], components: [row] });
                    break;
                case 'button3':
                    // 可自定义button3的逻辑,比如切换其他Embed或提示
                    await i.editReply({ embeds: [embed1], components: [row] });
                    break;
            }
        });

        // 收集器结束后移除按钮
        collector.on('end', async () => {
            await interaction.editReply({ components: [] });
        });
    }
}

版本建议

直接使用Discord.js v14即可,v13已停止官方维护,v14是当前稳定版本,拥有更完善的组件系统和API支持,后续更新和问题排查也更方便。

内容的提问来源于stack exchange,提问作者gTomii

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 11:53:17