点击Discord复制消息按钮时出现「This interaction failed」错误求助
问题分析与修复方案
核心问题
- 未回应交互:Discord要求所有按钮点击这类组件交互必须在3秒内得到回应,否则会触发「This interaction failed」超时错误。
- 收集器绑定错误:你把按钮发送到用户的DM,但收集器却绑定在原交互的频道,导致无法捕获DM里的按钮点击事件。
修复后的完整代码
const rowCopyPaste = new Discord.MessageActionRow().addComponents( new Discord.MessageButton() .setLabel('Copy and Paste') .setStyle('SECONDARY') .setCustomId('copy_paste_button') ); // 发送消息到用户DM并保存消息对象 const embedMessage = await interaction.user.send({ embeds: [ new Discord.MessageEmbed() .setColor('#2F3136') .setTitle(interaction.user.username) .setDescription('Test') ], components: [rowCopyPaste] }); // 绑定收集器到DM消息,而非原频道 const CollectorCopyPaste = embedMessage.createMessageComponentCollector({ componentType: 'BUTTON', time: 5000 * 60, filter: i => i.user.id === interaction.user.id && i.customId === 'copy_paste_button', }); CollectorCopyPaste.on('collect', async i => { // 先回应交互,避免超时错误 await i.deferUpdate(); // 发送要复制的消息 await i.channel.send({ embeds: [ new Discord.MessageEmbed() .setDescription('Message to be copied') ] }); });
关键修复点
- 添加交互回应:在按钮点击的处理函数开头调用
await i.deferUpdate();,告知Discord已接收交互请求,避免超时。 - 修正收集器绑定对象:用
embedMessage.createMessageComponentCollector()替代原代码的interaction.channel.createMessageComponentCollector(),确保收集器监听的是按钮所在的DM消息。 - 规范变量声明:给
embedMessage添加const声明,避免全局变量污染。
针对Discord.js v14+版本的适配提示
如果你的项目使用v14及以上版本,Discord.js的组件类名有变更,需调整代码如下:
const { ActionRowBuilder, ButtonBuilder, EmbedBuilder } = require('discord.js'); const rowCopyPaste = new ActionRowBuilder().addComponents( new ButtonBuilder() .setLabel('Copy and Paste') .setStyle('Secondary') .setCustomId('copy_paste_button') ); const embedMessage = await interaction.user.send({ embeds: [ new EmbedBuilder() .setColor('#2F3136') .setTitle(interaction.user.username) .setDescription('Test') ], components: [rowCopyPaste] }); const CollectorCopyPaste = embedMessage.createMessageComponentCollector({ componentType: 'Button', time: 5000 * 60, filter: i => i.user.id === interaction.user.id && i.customId === 'copy_paste_button', }); CollectorCopyPaste.on('collect', async i => { await i.deferUpdate(); await i.channel.send({ embeds: [ new EmbedBuilder() .setDescription('Message to be copied') ] }); });
内容的提问来源于stack exchange,提问作者Taymetic
相关产品推荐
相关产品推荐

