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

Discord.js /giveaway命令无控制台报错但无法正常运行求助

问题:Discord抽奖命令弹窗报错且modalData返回undefined

执行自定义的/giveaway抽奖命令时,弹窗顶部显示“Something went wrong. Try again”,控制台输出如下:

Starting giveaway command
Showing modal to user
Modal data: undefined

已尝试更新Node.js、discord.js至最新版本,问题仍存在。

问题根源

interaction.showModal()仅负责触发模态框展示,不会返回用户提交的模态框数据。原代码错误地将该方法的返回值赋值给modalData,导致其为undefined,后续依赖该数据的逻辑无法执行,最终触发弹窗报错。

正确的做法是使用interaction.awaitModalSubmit()监听用户提交模态框的操作,以此获取用户输入的数据。

修复后的完整代码

const { ActionRowBuilder, ModalBuilder, SlashCommandBuilder, TextInputBuilder, TextInputStyle } = require('discord.js');

module.exports = {
    data: new SlashCommandBuilder().setName('giveaway').setDescription("Starts a giveaway."),
    run: async ({ interaction }) => {
        try {
            console.log('Starting giveaway command');

            const modal = new ModalBuilder()
                .setCustomId('giveawayModal')
                .setTitle('Start a Giveaway');

            const prizeInput = new TextInputBuilder()
                .setCustomId('prizeInput')
                .setLabel("What is the prize for this giveaway?")
                .setStyle(TextInputStyle.Short)
                .setRequired(true); // 设为必填,避免用户空提交

            const durationInput = new TextInputBuilder()
                .setCustomId('durationInput')
                .setLabel("Giveaway duration (in minutes)")
                .setStyle(TextInputStyle.Short)
                .setRequired(true); // 设为必填

            const firstActionRow = new ActionRowBuilder().addComponents(prizeInput);
            const secondActionRow = new ActionRowBuilder().addComponents(durationInput);

            modal.addComponents(firstActionRow, secondActionRow);

            console.log('Showing modal to user');
            // 展示模态框,无返回值
            await interaction.showModal(modal);

            // 监听模态框提交,设置超时时间(10分钟),仅允许命令发起者提交
            const submitted = await interaction.awaitModalSubmit({
                time: 600000,
                filter: i => i.user.id === interaction.user.id,
            }).catch(err => {
                console.error('Modal submit error:', err);
                interaction.followUp({ content: 'Giveaway setup timed out or failed.', ephemeral: true });
                return null;
            });

            if (!submitted) return;

            // 通过submitted对象获取用户输入的数据
            const prize = submitted.fields.getTextInputValue('prizeInput');
            const duration = parseInt(submitted.fields.getTextInputValue('durationInput')) * 60; // 转换为秒

            // 校验时长是否为有效数字
            if (isNaN(duration)) {
                return submitted.reply({ content: 'Please enter a valid number for duration.', ephemeral: true });
            }

            const data = { prize, duration };
            console.log('Giveaway data:', data);

            console.log('Starting giveaway');
            const announcementMessage = await submitted.channel.send(`The giveaway for "${data.prize}" has started! React with 🎉 to enter. It will end in ${data.duration / 60} minutes.`);

            await announcementMessage.react('🎉');

            await new Promise(resolve => setTimeout(resolve, data.duration * 1000));

            const reaction = announcementMessage.reactions.cache.get('🎉');
            const users = await reaction.users.fetch();

            const participants = users.filter(user => !user.bot).array();
            console.log('Participants:', participants);

            // 处理无参与者的情况
            if (participants.length === 0) {
                return submitted.channel.send('No one entered the giveaway, so there\'s no winner.');
            }
            
            const winner = participants[Math.floor(Math.random() * participants.length)];
            console.log('Winner:', winner);

            await submitted.channel.send(`Congratulations, ${winner}! You won the "${data.prize}" giveaway! 🎉`);
            // 回复模态框提交,关闭用户侧的加载状态
            await submitted.reply({ content: 'Giveaway started successfully!', ephemeral: true });
        } catch (error) {
            console.error(error);
            // 全局错误提示
            if (interaction.replied || interaction.deferred) {
                interaction.followUp({ content: 'An error occurred while starting the giveaway.', ephemeral: true });
            } else {
                interaction.reply({ content: 'An error occurred while starting the giveaway.', ephemeral: true });
            }
        }
    },
};

额外优化说明

  • 给输入框添加setRequired(true),强制用户填写必要信息
  • 为awaitModalSubmit设置超时时间和用户过滤规则,确保操作安全性
  • 增加时长合法性校验,避免非数字输入导致后续逻辑崩溃
  • 处理无参与者的边界情况,防止报错
  • 添加多场景错误提示,让用户明确知晓问题状态

内容的提问来源于stack exchange,提问作者delyrious

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 04:50:42