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

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.6
  • discord.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 19:17:06