Discord经济机器人执行斜杠命令触发InteractionAlreadyReplied错误
问题:Discord机器人/give命令报错InteractionAlreadyReplied
执行/give斜杠命令时,机器人显示“bot is thinking”但无响应,终端报错:
PS C:\Discord Bot> node . Ready! Logged in as Money Bot#6039 Connected to the database! Error executing give Error [InteractionAlreadyReplied]: The reply to this interaction has already been sent or deferred. at ChatInputCommandInteraction.deferReply (C:\Discord Bot\node_modules\discord.js\src\structures\interfaces\InteractionResponses.js:67:46) at Object.execute (C:\Discord Bot\commands\give.js:48:25) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Object.execute (C:\Discord Bot\events\interactionCreate.js:33:7) { code: 'InteractionAlreadyReplied' }
错误原因
每个Discord互动只能被回复或延迟回复一次,你的代码在多个分支重复调用interaction.deferReply():
- 余额不足时调用了一次
deferReply - 后续流程又再次调用
deferReply - 接收用户不存在时再次调用
deferReply
多次调用触发了InteractionAlreadyReplied错误。
修复后的代码
const { SlashCommandBuilder } = require("discord.js"); const profileModel = require("../Models/profileSchema"); module.exports = { data: new SlashCommandBuilder() .setName("give") .setDescription("给其他用户转账金币") .addUserOption((option) => option .setName("user") .setDescription("接收金币的用户") .setRequired(true) ) .addIntegerOption((option) => option .setName("amount") .setDescription("转账的金币数量") .setRequired(true) .setMinValue(1) ), async execute(interaction, profileData) { const receiveUser = interaction.options.getUser("user"); const giveAmt = interaction.options.getInteger("amount"); const { balance } = profileData; // 余额不足直接回复(同步判断无需延迟) if (balance < giveAmt) { return await interaction.reply({ content: `你的余额不足${giveAmt}金币`, ephemeral: true }); } // 仅调用一次延迟回复,告知用户机器人正在处理 await interaction.deferReply(); // 先查询接收用户是否存在 let receiveUserData = await profileModel.findOne({ userId: receiveUser.id }); if (!receiveUserData) { return await interaction.editReply({ content: `${receiveUser.username}尚未加入货币系统`, ephemeral: true }); } // 更新接收用户余额 await profileModel.findOneAndUpdate( { userId: receiveUser.id }, { $inc: { balance: giveAmt } } ); // 更新转账用户余额 await profileModel.findOneAndUpdate( { userId: interaction.user.id }, { $inc: { balance: -giveAmt } } ); // 编辑延迟回复,告知最终结果 await interaction.editReply(`你已成功转账${giveAmt}金币给${receiveUser.username}`); }, };
关键改动说明
- 移除重复的deferReply调用:仅在需要处理异步数据库操作时调用一次
deferReply,同步判断逻辑直接用interaction.reply返回结果。 - 调整用户查询逻辑:先查询接收用户是否存在,避免原代码中
findOneAndUpdate返回null的歧义,不存在则直接回复提示。 - 统一回复方式:所有最终结果通过
editReply编辑延迟回复,彻底避免重复回复操作。
内容的提问来源于stack exchange,提问作者Jake Carpenter
相关产品推荐
相关产品推荐

