DiscordJS v13石头剪刀布命令触发Interaction Failed无报错排查
问题排查与修复方案
核心错误点(直接导致Interaction Failed)
- 未定义
button变量:代码中直接调用button.deferUpdate()、判断button.id,但collect事件返回的交互实例是参数i,不存在全局button对象,直接抛出未捕获异常,交互未在3秒内响应就会触发失败提示 - 未等待
deferUpdate执行:deferUpdate是异步方法,不加await会导致交互还没完成延期响应就开始处理后续逻辑,依旧可能超时 - 收集器绑定位置错误:在
collect事件内部绑定collector.on("end"),每触发一次按钮点击就会重复绑定一次end事件,逻辑混乱 - 重复生成机器人出拳值:已经在逻辑开头生成
botPick赋值botChoose,后续每个按钮判断分支又重新生成botPick但未更新botChoose,导致出拳逻辑完全混乱 - 变量名冲突:发送按钮消息后的回调参数命名为
message,和外层触发指令的message变量重名,容易出现取值错误 - 收集器创建对象错误:使用
channel.createMessageComponentCollector会监听整个频道的所有组件交互,应该绑定到你刚发送的带按钮的消息上
修复后完整代码
const { MessageActionRow, MessageButton, MessageEmbed } = require('discord.js'); module.exports = new Command({ name: 'rps', description: "play rock paper scissors", permission: "ADMINISTRATOR", async run(message, args, client) { let botChoose; let playerScore = 0; let botScore = 0; const rock = ":fist: Rock"; const paper = ":hand_splayed: Paper"; const scissor = ":v: Scissor"; const rockButton = new MessageButton().setCustomId("rock").setStyle('SECONDARY').setLabel("Rock"); const paperButton = new MessageButton().setCustomId("paper").setStyle('SECONDARY').setLabel("Paper"); const scissorButton = new MessageButton().setCustomId("scissor").setStyle('SECONDARY').setLabel("Scissor"); const row = new MessageActionRow().addComponents([rockButton, paperButton, scissorButton]); const embed = new MessageEmbed() .setColor("RANDOM") .setDescription("Winner: **-**") .addField(`Score RPS`, `\`->\` ${message.author}: **${playerScore} Point**\n\`->\` ${client.user}: **${botScore} Point**`) // 重命名回调参数避免重名 message.channel.send({ embeds: [embed], components: [row] }).then(async (sentMsg) => { const ifilter = i => i.user.id === message.author.id; // 绑定到发送的消息本身创建收集器 const collector = sentMsg.createMessageComponentCollector({ filter: ifilter, time: 30000 }) collector.on("collect", async i => { // 正确调用延期响应,加await await i.deferUpdate(); // 生成机器人出拳,删掉后续重复生成的冗余代码 const botPick = Math.floor(Math.random() * 3) + 1; if (botPick === 1) botChoose = "rock"; else if (botPick === 2) botChoose = "paper"; else if (botPick === 3) botChoose = "scissor"; const embed1 = new MessageEmbed() .setColor("RANDOM") .setDescription('Winner: **-**') .addField(`Score RPS`, `\`->\` ${message.author}: **${playerScore} Point**\n\`->\` ${client.user}: **${botScore} Point**`) // 正确从交互实例取customId判断按钮 if (i.customId === "rock") { if (botChoose === "paper") { botScore++; const embed2 = new MessageEmbed() .setColor("RANDOM") .setDescription('Winner: **-**') .addField(`Score RPS`, `\`->\` ${message.author}: **${playerScore} Point**\n\`->\` ${client.user}: **${botScore} Point**`) return sentMsg.edit({ content: `I picked: **${paper}**\nYou picked: **${rock}**\n**Result**: You lost`, embeds: [embed2], components: [row] }) } if (botChoose === "rock") { return sentMsg.edit({ content: `I picked: **${rock}**\nYou picked: **${rock}**\n**Result**: We tied`, embeds: [embed1], components: [row] }) } if (botChoose === "scissor") { playerScore++; const embed2 = new MessageEmbed() .setColor("RANDOM") .setDescription('Winner: **-**') .addField(`Score RPS`, `\`->\` ${message.author}: **${playerScore} Point**\n\`->\` ${client.user}: **${botScore} Point**`) return sentMsg.edit({ content: `I picked: **${scissor}**\nYou picked: **${rock}**\n**Result**: You Won`, embeds: [embed2], components: [row] }) } } if (i.customId === "paper") { if (botChoose === "scissor") { botScore++; const embed2 = new MessageEmbed() .setColor("RANDOM") .setDescription('Winner: **-**') .addField(`Score RPS`, `\`->\` ${message.author}: **${playerScore} Point**\n\`->\` ${client.user}: **${botScore} Point**`) return sentMsg.edit({ content: `I picked: **${scissor}**\nYou picked: **${paper}**\n**Result**: You lost`, embeds: [embed2], components: [row] }) } if (botChoose === "paper") { return sentMsg.edit({ content: `I picked: **${paper}**\nYou picked: **${paper}**\n**Result**: We tied`, embeds: [embed1], components: [row] }) } if (botChoose === "rock") { playerScore++; const embed2 = new MessageEmbed() .setColor("RANDOM") .setDescription('Winner: **-**') .addField(`Score RPS`, `\`->\` ${message.author}: **${playerScore} Point**\n\`->\` ${client.user}: **${botScore} Point**`) return sentMsg.edit({ content: `I picked: **${rock}**\nYou picked: **${paper}**\n**Result**: You Won`, embeds: [embed2], components: [row] }) } } if (i.customId === "scissor") { if (botChoose === "rock") { botScore++; const embed2 = new MessageEmbed() .setColor("RANDOM") .setDescription('Winner: **-**') .addField(`Score RPS`, `\`->\` ${message.author}: **${playerScore} Point**\n\`->\` ${client.user}: **${botScore} Point**`) return sentMsg.edit({ content: `I picked: **${rock}**\nYou picked: **${scissor}**\n**Result**: You lost`, embeds: [embed2], components: [row] }) } if (botChoose === "scissor") { return sentMsg.edit({ content: `I picked: **${scissor}**\nYou picked: **${scissor}**\n**Result**: We tied`, embeds: [embed1], components: [row] }) } if (botChoose === "paper") { playerScore++; const embed2 = new MessageEmbed() .setColor("RANDOM") .setDescription('Winner: **-**') .addField(`Score RPS`, `\`->\` ${message.author}: **${playerScore} Point**\n\`->\` ${client.user}: **${botScore} Point**`) return sentMsg.edit({ content: `I picked: **${paper}**\nYou picked: **${scissor}**\n**Result**: You Won`, embeds: [embed2], components: [row] }) } } }) // end事件移到collect事件外面绑定 collector.on("end", async(x) => { if (x.size === 0) { sentMsg.edit({ content: `No one even played againts me lol!`, embeds: [], components: [] }); } else { if (playerScore === botScore) { const embed2 = new MessageEmbed() .setColor("BLACK") .setDescription('Winner: **TIED**') .addField(`Score RPS`, `\`->\` ${message.author}: **${playerScore} Point**\n\`->\` ${client.user}: **${botScore} Point**`) sentMsg.edit({ content: "", embeds: [embed2], components: [] }) } else if (playerScore > botScore) { const embed2 = new MessageEmbed() .setColor("GREEN") .setDescription(`Winner: **${message.author}**`) .addField(`Score RPS`, `\`->\` ${message.author}: **${playerScore} Point**\n\`->\` ${client.user}: **${botScore} Point**`) sentMsg.edit({ content: "", embeds: [embed2], components: [] }) } else { const embed2 = new MessageEmbed() .setColor("RED") .setDescription(`Winner: **${client.user}**`) .addField(`Score RPS`, `\`->\` ${message.author}: **${playerScore} Point**\n\`->\` ${client.user}: **${botScore} Point**`) sentMsg.edit({ content: "", embeds: [embed2], components: [] }) } } }) }) } });
内容的提问来源于stack exchange,提问作者JerZ
相关产品推荐
相关产品推荐

