Discord.js按钮收集器运行异常:交互失败、数据串改及Unknown interaction报错求助
存在的问题
- 模板字符串语法错误:所有需要插值
${变量}的地方你都用了单引号包裹,导致变量不会被解析,始终显示为原始文本。 - 变量作用域错误:
users数组、buttonclicker等变量定义在interactionCreate事件回调内部,每次有用户点击按钮都会重新创建空的users数组,且存储的点击者昵称永远是首次触发事件的用户昵称,所以会出现其他用户点击修改你的昵称的问题。 - 重复创建组件收集器:每次触发
interactionCreate事件都会新建一个收集器,多次点击后会有多个收集器同时处理同一个交互,交互被首次更新后就会失效,后续收集器再调用i.update就会抛出Unknown interaction错误。 - 交互未及时响应:首次点击按钮时,你没有在3秒的交互有效期内给出响应,Discord会直接判定交互失败。
- 命令监听错误:你用了
client.once监听messageCreate事件,导致!createrecord命令只能执行一次,第二次发送命令不会有任何响应。
修正后完整代码
const { Client, Intents, MessageActionRow, MessageButton, MessageEmbed} = require("discord.js"); // 初始化机器人客户端,按需开启权限 const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] }); // 全局存储报名用户数组,放在事件外部避免每次初始化被清空 let users = []; // 按钮行全局定义 const row = new MessageActionRow() .addComponents( new MessageButton() .setCustomId("green") .setStyle("SUCCESS") .setLabel("green") .setEmoji("🟢"), new MessageButton() .setCustomId("red") .setStyle("DANGER") .setLabel("red") .setEmoji("🔴"), new MessageButton() .setCustomId("yellow") .setStyle("SECONDARY") .setLabel("yellow") .setEmoji("🟡"), ); // 把once改成on,支持多次调用创建报名帖命令 client.on("messageCreate", async (msg) => { if(msg.content.toLowerCase() == "!createrecord" && msg.guild && !msg.member.user.bot){ await msg.delete() // 每次新建报名帖清空之前的用户列表,不需要可以删掉这行 users = []; const embed = new MessageEmbed() .setColor('#208c3d') .setTitle('Active list') .setDescription("No active players") .setFooter("Footer") await msg.channel.send({ embeds: [embed], components: [row] }) } }) client.on('interactionCreate', async interaction => { // 先判断是不是按钮交互,不是直接返回 if(!interaction.isButton()) return; // 每次点击都取当前点击用户的昵称,没有昵称就用用户名兜底 const buttonclicker = interaction.member.nickname || interaction.user.username; const greenbtnclicker = `🟢 ${buttonclicker}` const yellowbtnclicker = `🟡 ${buttonclicker}` try { if (interaction.customId === 'green') { if(users.indexOf(greenbtnclicker) == -1) { const yellowIndex = users.indexOf(yellowbtnclicker) if(yellowIndex > -1) { users.splice(yellowIndex, 1) } users.push(greenbtnclicker) users.sort(); } } else if (interaction.customId === 'red') { const yellowIndex = users.indexOf(yellowbtnclicker) if(yellowIndex != -1) { users.splice(yellowIndex, 1) } const greenIndex = users.indexOf(greenbtnclicker) if(greenIndex != -1) { users.splice(greenIndex, 1) } } else if (interaction.customId === 'yellow') { if(users.indexOf(yellowbtnclicker) == -1) { const greenIndex = users.indexOf(greenbtnclicker) if(greenIndex != -1) { users.splice(greenIndex, 1) } users.push(yellowbtnclicker) users.sort(); } } // 统一生成新Embed,避免重复写冗余代码 const newEmbed = new MessageEmbed() .setColor('#208c3d') .setTitle('Active list') .setDescription(users.length ? `Active Players: ${users.length}` : "No active players") .setFooter('Footer') users.forEach(user => { newEmbed.addField('--------------------------------', user) }) // 统一更新交互,确保3秒内响应避免超时 await interaction.update({ embeds: [newEmbed], components: [row] }); } catch (err) { // 捕获异常避免机器人崩溃,可根据需要打印错误日志排查问题 console.error('交互处理失败:', err) } }); client.login('你的机器人Token')
内容的提问来源于stack exchange,提问作者Baumii
相关产品推荐
相关产品推荐

