Discord机器人Modal无法保存数据,提交表单失败求助
Discord机器人注册模态框数据获取失败修复方案
问题现象
- 触发注册命令弹出模态框,提交时提示「Failed to send registration form」错误
- 后台日志输出
Submitted Data: { components: undefined, fields: undefined },无法获取用户输入的字段数据 - 数据无法正常写入MongoDB数据库
核心代码(index.js)
const userSchema = new mongoose.Schema({ discordId: { type: String, unique: true }, username: String, team: { type: mongoose.Schema.Types.ObjectId, ref: "Team" }, idCardNumber: String, phoneNumber: String, name: String, platform: String, platformId: String, }); const User = mongoose.model("User", userSchema); // Define schema and model for storing teams const teamSchema = new mongoose.Schema({ name: { type: String, unique: true }, members: [{ discordId: String, username: String }], }); const Team = mongoose.model("Team", teamSchema); // Set up Discord client const token = process.env.DISCORD_BOT_SECRET; const CLIENT_ID = process.env.CLIENT_ID; const GUILD_ID = process.env.GUILD_ID; const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, ], }); const rest = new REST({ version: "10" }).setToken(token); client.on("ready", () => console.log(`${client.user.tag} has logged in!`)); client.on("interactionCreate", async (interaction) => { if (!interaction.isCommand()) return; const { commandName, options } = interaction; if (commandName === "register") { await handleRegister(interaction, User, client.guilds); } else if (commandName === "team") { await handleTeam(interaction, User, Team); } });
使用依赖版本
@discordjs/rest: ^2.2.0@types/node: ^18.0.6discord.js: ^14.14.1
修复步骤
1. 补充模态框提交事件处理
原代码仅监听了Slash Command类型的交互,未处理模态框提交的modalSubmit交互,导致无法获取提交数据。修改interactionCreate事件监听:
client.on("interactionCreate", async (interaction) => { // 处理Slash Command if (interaction.isCommand()) { const { commandName, options } = interaction; if (commandName === "register") { await handleRegister(interaction, User, client.guilds); } else if (commandName === "team") { await handleTeam(interaction, User, Team); } } // 处理模态框提交 else if (interaction.isModalSubmit()) { // 匹配注册模态框的自定义ID(需与handleRegister中设置的一致) if (interaction.customId === 'registration-modal') { try { // 通过组件ID获取用户输入值 const idCardNumber = interaction.fields.getTextInputValue('id-card-input'); const phoneNumber = interaction.fields.getTextInputValue('phone-input'); const name = interaction.fields.getTextInputValue('name-input'); const platform = interaction.fields.getTextInputValue('platform-input'); const platformId = interaction.fields.getTextInputValue('platform-id-input'); // 写入MongoDB await User.create({ discordId: interaction.user.id, username: interaction.user.tag, idCardNumber, phoneNumber, name, platform, platformId }); await interaction.reply({ content: '注册成功!', ephemeral: true }); } catch (err) { console.error('注册失败:', err); await interaction.reply({ content: 'Failed to send registration form', ephemeral: true }); } } } });
2. 确保模态框组件ID与处理逻辑匹配
检查handleRegister函数中创建模态框的代码,确保每个输入框的customId与上述提交处理中使用的ID一致。示例:
async function handleRegister(interaction) { const modal = new ModalBuilder() .setCustomId('registration-modal') // 需与提交处理中的ID一致 .setTitle('用户注册'); // 身份证号输入框 const idCardInput = new TextInputBuilder() .setCustomId('id-card-input') .setLabel('身份证号') .setStyle(TextInputStyle.Short) .setRequired(true); // 手机号输入框 const phoneInput = new TextInputBuilder() .setCustomId('phone-input') .setLabel('手机号') .setStyle(TextInputStyle.Short) .setRequired(true); // 真实姓名输入框 const nameInput = new TextInputBuilder() .setCustomId('name-input') .setLabel('真实姓名') .setStyle(TextInputStyle.Short) .setRequired(true); // 将输入框添加到ActionRow const rows = [ new ActionRowBuilder().addComponents(idCardInput), new ActionRowBuilder().addComponents(phoneInput), new ActionRowBuilder().addComponents(nameInput) // 补充其他字段的ActionRow ]; modal.addComponents(...rows); await interaction.showModal(modal); }
3. 验证字段完整性
确保所有需要存入MongoDB的字段,都在模态框中设置了对应的输入组件,且在提交处理中正确获取值。
问题根源
原代码未监听模态框提交的modalSubmit交互类型,导致用户提交表单时无对应逻辑处理,无法读取输入字段数据,最终触发错误并无法写入数据库。
内容的提问来源于stack exchange,提问作者Eamaan Adam
相关产品推荐
相关产品推荐

