You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 09:22:32