Discord Bot提交Bug报告时Modal不关闭且提示错误求助
问题原因
你遇到的问题核心是没有对Modal提交的交互对象(response)进行回应。Discord要求所有用户触发的交互(包括Modal提交)必须在3秒内通过回复/延迟回应来确认,否则会显示"Something went wrong",并且Modal无法正常关闭。你的代码里只处理了最初的interaction,但忽略了Modal提交产生的独立交互response。
另外,你尝试用原interaction回复的逻辑也有问题:调用showModal后,原交互已经处于"已响应"状态(因为Modal展示属于交互响应的一种),所以!interaction.replied && !interaction.deferred的判断永远为假,导致成功/失败消息都发不出去。
修复方案
修改代码中Modal提交后的处理逻辑,针对response对象进行回应,同时调整错误处理:
const { SlashCommandBuilder, EmbedBuilder, ModalBuilder, TextInputBuilder, TextInputStyle, ActionRowBuilder, ChatInputCommandInteraction, } = require("discord.js"); module.exports = { data: new SlashCommandBuilder() .setName("bugreport") .setDescription("Report a bug in the bot") .addStringOption((option) => option .setName("severity") .setDescription("Select the severity level of the bug") .addChoices( { name: "Low", value: "low" }, { name: "Medium", value: "medium" }, { name: "High", value: "high" } ) .setRequired(true) ), /** * @param {ChatInputCommandInteraction} interaction */ async execute(interaction) { const severity = interaction.options.getString("severity"); const reportModal = new ModalBuilder() .setCustomId("bugmodal") .setTitle("Report a bug"); const titleInput = new TextInputBuilder() .setCustomId("bugtitle") .setLabel("Title") .setStyle(TextInputStyle.Short) .setPlaceholder("Cool Title!") .setMaxLength(256) .setRequired(false); const descriptionInput = new TextInputBuilder() .setCustomId("bugdescription") .setLabel("Description") .setStyle(TextInputStyle.Paragraph) .setRequired(false); const titleactionRow = new ActionRowBuilder().addComponents(titleInput); const descriptionactionRow = new ActionRowBuilder().addComponents(descriptionInput); reportModal.addComponents(titleactionRow, descriptionactionRow); try { await interaction.showModal(reportModal); } catch (error) { console.error(error); return interaction.reply({ content: "Something went wrong", ephemeral: true, }); } try { const response = await interaction.awaitModalSubmit({ time: 300000 }); // 先延迟回应,避免超时(如果后续操作耗时超过3秒) await response.deferReply({ ephemeral: true }); const title = response.fields.getTextInputValue("bugtitle"); const description = response.fields.getTextInputValue("bugdescription"); const embed = new EmbedBuilder() .setColor("Red") .setTitle(`${severity.toUpperCase()} Priority Bug Report`) .addFields( { name: "Title", value: title || "无标题" }, { name: "Description", value: description || "无描述" }, { name: "Reported By:", value: interaction.user.tag }, { name: "Reported from:", value: interaction.guild.name } ) .setTimestamp(); const guildId = "1090231817795272725"; const channelId = "1090231818596397088"; const guild = await interaction.client.guilds.fetch(guildId); const channel = guild.channels.cache.get(channelId); await channel.send({ embeds: [embed] }); // 用response更新延迟的回应 await response.editReply({ content: "Bug report sent successfully!", ephemeral: true, }); } catch (err) { console.error(err); // 处理超时或其他错误,确保回应Modal交互 if (err.code === "INTERACTION_COLLECTOR_ERROR") { // 如果是超时,尝试给原交互发消息(如果还能发) if (!interaction.replied && !interaction.deferred) { return interaction.reply({ content: "Bug report timed out.", ephemeral: true, }); } } else { // 如果Modal已经提交但后续出错,检查response是否存在并回应 if (typeof response !== 'undefined' && !response.replied && !response.deferred) { return response.reply({ content: "Failed to send bug report.", ephemeral: true, }); } } } }, };
关键修改点
- 新增
await response.deferReply({ ephemeral: true }):在处理耗时操作前先延迟回应,避免Discord判定交互超时。 - 用
response.editReply替换原有的interaction.reply:因为Modal提交的交互是独立的,必须通过response对象来完成回应,这样Modal才能正常关闭。 - 补充了空内容的默认值(
title || "无标题"):避免Embed字段出现空值导致的潜在问题。 - 细化错误处理:区分超时和其他错误,确保所有情况下都能对相应的交互对象做出回应。
内容的提问来源于stack exchange,提问作者Xhani
相关产品推荐
相关产品推荐

