Discord.JS v14西部对决Slash命令:点击反应后消息无法编辑求助
Discord.JS v14西部对决Slash命令问题:点击反应后消息无法编辑
我在使用Discord.JS v14开发西部对决Slash命令时,遇到点击反应后消息无法编辑的问题。已查阅官方文档、尝试多种方法仍未解决,以下是相关代码,恳请帮忙排查:
const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, Events, Embed, } = require('discord.js') const chalk = require('chalk'); const wait = require('node:timers/promises').setTimeout; module.exports = { data: new SlashCommandBuilder() .setName('standoff') .setDescription(`Have a western standoff with another user.`) .addUserOption(option => option.setName('user') .setDescription(`Who do you want to have a standoff with?`) .setRequired(true)), async execute (interaction) { const { client } = interaction; const target = interaction.options.getUser('user'); const intUser = interaction.user let today = new Date(); let date = today.getMonth()+1+`/`+today.getDate()+`/`+today.getFullYear(); let logTime = today.getHours() + `:` + today.getMinutes() let dateTime = date+' '+logTime; const standoffErrorEmbed = new EmbedBuilder() standoffErrorEmbed.setTitle(`STANDOFF`) standoffErrorEmbed.setColor(`Red`) if (target.bot) { standoffErrorEmbed.setDescription(`<@${interaction.user.id}>, you can't have a standoff against a bot.`) interaction.reply({ embeds: [standoffErrorEmbed] }) console.log(chalk.white(`${dateTime} │ `,chalk.green(`${interaction.user.tag} in ${interaction.guild.name} tried using /standoff on a bot.`))); return; } else if (target.id === interaction.user.id) { standoffErrorEmbed.setDescription(`<@${interaction.user.id}>, you can't have a standoff with yourself.`) interaction.reply({ embeds: [standoffErrorEmbed] }) console.log(chalk.white(`${dateTime} │ `,chalk.green(`${interaction.user.tag} in ${interaction.guild.name} tried using /standoff on themself.`))); return; } else if (!target || target === null) { standoffErrorEmbed.setDescription(`<@${interaction.user.id}>, you need to select a valid opponent`) interaction.reply({ embeds: [standoffErrorEmbed] }) console.log(chalk.white(`${dateTime} │ `,chalk.green(`${interaction.user.tag} in ${interaction.guild.name} tried using /standoff on an invalid user.`))); return; } else { const standoffEmbed = new EmbedBuilder() standoffEmbed.setTitle(`STANDOFF`) standoffEmbed.setColor('Yellow') standoffEmbed.setThumbnail('https://cdn.discordapp.com/attachments/762927301108695141/1137185724286902272/R.png') standoffEmbed.setDescription(`<@${interaction.user.id}> challenged <@${target.id}> to a standoff! \nThe first person to click the <:revolver_left:1137134967697182741> when it appears will win!`) const shootTimeList = [4000, 5000, 6000, 7000, 8000] const shootTime = shootTimeList[Math.floor(Math.random() * shootTimeList.length)] let standoffMessage = `🤠<:revolver_left:1137134967697182741> <:revolver_right:1137134969374900275>🤠` const standoffEmbedShot = await interaction.reply({ content: `${standoffMessage}`, embeds: [standoffEmbed], fetchReply: true }) const collectorFilter = (reaction, user) => { return reaction.emoji.id === '<:revolver_left:1137134967697182741>' && user.id === interaction.user.id || user.id === target.id; }; const collector = standoffEmbedShot.createReactionCollector({ filter: collectorFilter, time: shootTime + 15000 }); wait(shootTime); standoffEmbedShot.react('<:revolver_left:1137134967697182741>') collector.on('collect', (reaction, user) => { if (user.id === interaction.user.id && reaction.emoji.id === `<:revolver_left:1137134967697182741>`) { standoffEmbedShot.reactions.removeAll() standoffMessage = `🤠<:revolver_left:1137134967697182741>💥 <:revolver_right:1137134969374900275>💀` standoffEmbed.setDescription(`<@${interaction.user.id}> won the standoff!`) standoffEmbed.setColor('Green') standoffEmbedShot.editReply({ content: `${standoffMessage}`, embeds: [standoffEmbed] }) console.log(chalk.white(`${dateTime} │ `,chalk.green(`${interaction.user.tag} in ${interaction.guild.name} used /standoff on ${target.tag}. The winner was ${interaction.user.tag}.`))); return; } else if (user.id === target.id && reaction.emoji.id === `<:revolver_left:1137134967697182741>`) { standoffEmbedShot.reactions.removeAll() standoffMessage = `💀<:revolver_left:1137134967697182741> 💥<:revolver_right:1137134969374900275>🤠` standoffEmbed.setDescription(`<@${target.id}> won the standoff!`) standoffEmbed.setColor('Green') standoffEmbedShot.editReply({ content: `${standoffMessage}`, embeds: [standoffEmbed] }) console.log(chalk.white(`${dateTime} │ `,chalk.green(`${interaction.user.tag} in ${interaction.guild.name} used /standoff on ${target.tag}. The winner was ${target.tag}.`))); return; } }); } } }
问题排查与修复方案
1. 表情ID匹配错误
代码中判断表情ID时使用了HTML转义后的字符串<:revolver_left:1137134967697182741>,但Discord自定义表情的id属性是纯数字,正确的ID应为1137134967697182741。
2. wait未使用await
wait(shootTime);没有添加await,会导致代码跳过等待直接执行后续逻辑,出现反应提前添加的问题,需改为await wait(shootTime);。
3. 编辑回复的方法调用错误
standoffEmbedShot.editReply()是错误的调用方式,编辑Slash命令的回复应使用interaction.editReply(),而非消息对象的方法。
4. 表情添加格式错误
standoffEmbedShot.react('<:revolver_left:1137134967697182741>')中的表情格式错误,应直接传入表情ID'1137134967697182741'或正确的表情格式<:revolver_left:1137134967697182741>。
修复后的代码示例
const { SlashCommandBuilder, EmbedBuilder } = require('discord.js') const chalk = require('chalk'); const wait = require('node:timers/promises').setTimeout; module.exports = { data: new SlashCommandBuilder() .setName('standoff') .setDescription('与另一位用户进行西部对决') .addUserOption(option => option.setName('user') .setDescription('你想和谁对决?') .setRequired(true)), async execute(interaction) { const target = interaction.options.getUser('user'); const intUser = interaction.user; let today = new Date(); let date = `${today.getMonth() + 1}/${today.getDate()}/${today.getFullYear()}`; let logTime = `${today.getHours()}:${today.getMinutes()}`; let dateTime = `${date} ${logTime}`; const standoffErrorEmbed = new EmbedBuilder() .setTitle('STANDOFF') .setColor('Red'); if (target.bot) { standoffErrorEmbed.setDescription(`<@${interaction.user.id}>,你不能和机器人对决!`); await interaction.reply({ embeds: [standoffErrorEmbed] }); console.log(chalk.white(`${dateTime} │ `, chalk.green(`${interaction.user.tag} 在 ${interaction.guild.name} 尝试对机器人使用/standoff命令。`))); return; } else if (target.id === interaction.user.id) { standoffErrorEmbed.setDescription(`<@${interaction.user.id}>,你不能和自己对决!`); await interaction.reply({ embeds: [standoffErrorEmbed] }); console.log(chalk.white(`${dateTime} │ `, chalk.green(`${interaction.user.tag} 在 ${interaction.guild.name} 尝试对自己使用/standoff命令。`))); return; } else if (!target) { standoffErrorEmbed.setDescription(`<@${interaction.user.id}>,请选择一个有效的对手!`); await interaction.reply({ embeds: [standoffErrorEmbed] }); console.log(chalk.white(`${dateTime} │ `, chalk.green(`${interaction.user.tag} 在 ${interaction.guild.name} 尝试对无效用户使用/standoff命令。`))); return; } const revolverEmojiId = '1137134967697182741'; const revolverRightEmoji = '<:revolver_right:1137134969374900275>'; const standoffEmbed = new EmbedBuilder() .setTitle('STANDOFF') .setColor('Yellow') .setThumbnail('https://cdn.discordapp.com/attachments/762927301108695141/1137185724286902272/R.png') .setDescription(`<@${interaction.user.id}> 向 <@${target.id}> 发起了西部对决!\n出现<revolver_left:${revolverEmojiId}>时,第一个点击的人获胜!`); const shootTimeList = [4000, 5000, 6000, 7000, 8000]; const shootTime = shootTimeList[Math.floor(Math.random() * shootTimeList.length)]; let standoffMessage = `🤠<:revolver_left:${revolverEmojiId}> ${revolverRightEmoji}🤠`; const standoffMessageObj = await interaction.reply({ content: standoffMessage, embeds: [standoffEmbed], fetchReply: true }); const collectorFilter = (reaction, user) => { return reaction.emoji.id === revolverEmojiId && (user.id === interaction.user.id || user.id === target.id); }; const collector = standoffMessageObj.createReactionCollector({ filter: collectorFilter, time: shootTime + 15000 }); await wait(shootTime); await standoffMessageObj.react(revolverEmojiId); collector.on('collect', async (reaction, user) => { await standoffMessageObj.reactions.removeAll(); collector.stop(); if (user.id === interaction.user.id) { standoffMessage = `🤠<:revolver_left:${revolverEmojiId}>💥 ${revolverRightEmoji}💀`; standoffEmbed.setDescription(`<@${interaction.user.id}> 赢得了对决!`).setColor('Green'); } else if (user.id === target.id) { standoffMessage = `💀<:revolver_left:${revolverEmojiId}> 💥${revolverRightEmoji}🤠`; standoffEmbed.setDescription(`<@${target.id}> 赢得了对决!`).setColor('Green'); } await interaction.editReply({ content: standoffMessage, embeds: [standoffEmbed] }); console.log(chalk.white(`${dateTime} │ `, chalk.green(`${interaction.user.tag} 在 ${interaction.guild.name} 对 ${target.tag} 使用了/standoff命令。获胜者是 ${user.tag}。`))); }); collector.on('end', async () => { if (!collector.collected.size) { standoffEmbed.setDescription(`对决超时,无人获胜!`).setColor('Orange'); await interaction.editReply({ embeds: [standoffEmbed] }); console.log(chalk.white(`${dateTime} │ `, chalk.green(`${interaction.user.tag} 在 ${interaction.guild.name} 发起的对决超时。`))); } }); } }
内容的提问来源于stack exchange,提问作者BOSSx
相关产品推荐
相关产品推荐

