Discord.js Modal报错getTextInputValue读取undefined排查
Discord.js Modal 命令报错修复
问题定位
你怀疑存在冲突的代码行const firstActionRow = new MessageActionRow().addComponents(favoriteColorInput);写法完全符合规范,没有问题——Discord.js 明确要求 Modal 内单个 MessageActionRow 只能承载一个 TextInput 组件,这行代码的写法是正确的。
抛出TypeError: Cannot read properties of undefined (reading 'getTextInputValue')错误的核心原因,是你把模态框提交后的处理逻辑写在了斜杠命令的execute回调里:
- 斜杠命令触发时,传入回调的
interaction是ChatInputCommandInteraction类型,调用interaction.showModal()只是向Discord发送弹出模态框的请求,该方法不会等待用户提交模态框就会继续执行后续代码。 - 用户提交模态框是独立的交互事件,会单独触发
interactionCreate事件,对应交互类型为ModalSubmitInteraction,根本不会在斜杠命令的本次回调中返回。 - 你在斜杠命令回调里直接访问
interaction.fields,但斜杠交互对象本身不存在fields属性,自然会抛出undefined错误。你写的if (!interaction.isModalSubmit()) return;在这个位置也没有任何作用,因为斜杠交互永远不可能是ModalSubmit类型。
修复方案
第一步:精简斜杠命令文件代码
把斜杠命令文件里模态框弹出之后的所有逻辑(取输入值、构造Embed、构造按钮、回复)全部移除,只保留弹出模态框的逻辑:
const { SlashCommandBuilder } = require('@discordjs/builders'); const { MessageActionRow, Modal, TextInputComponent } = require('discord.js'); module.exports = { data: new SlashCommandBuilder() .setName('modal') .setDescription('Site du serveur'), async execute(interaction, client) { // 创建模态框 const modal = new Modal() .setCustomId('myModal') .setTitle('My Modal'); // 创建文本输入组件 const favoriteColorInput = new TextInputComponent() .setCustomId('favoriteColorInput') .setLabel("What's your favorite color?") .setStyle('SHORT'); const hobbiesInput = new TextInputComponent() .setCustomId('hobbiesInput') .setLabel("What's some of your favorite hobbies?") .setStyle('PARAGRAPH'); // 每个输入组件单独放置到一个动作行 const firstActionRow = new MessageActionRow().addComponents(favoriteColorInput); const secondActionRow = new MessageActionRow().addComponents(hobbiesInput); // 将动作行添加到模态框 modal.addComponents(firstActionRow, secondActionRow); // 向用户展示模态框,斜杠命令处理到此结束 await interaction.showModal(modal); }, };
第二步:在交互入口增加模态框提交处理逻辑
找到你项目里监听interactionCreate事件的入口文件(就是你平时处理斜杠命令、按钮点击、下拉菜单选择的那个事件回调),在里面新增模态框提交的判断分支,把之前移除的处理逻辑放到这里:
client.on('interactionCreate', async interaction => { // 你原有的斜杠命令处理逻辑保持不变,不要修改 if (interaction.isChatInputCommand()) { // 原有匹配命令文件、执行命令的逻辑 } // 新增模态框提交处理分支 if (interaction.isModalSubmit()) { // 匹配我们自定义的模态框ID if (interaction.customId === 'myModal') { // 这里的interaction是ModalSubmitInteraction类型,才有fields属性 const favoriteColor = interaction.fields.getTextInputValue('favoriteColorInput'); const hobbies = interaction.fields.getTextInputValue('hobbiesInput'); console.log({ favoriteColor, hobbies }); // 构造返回内容 const embed = new client.discord.MessageEmbed() .setColor('#9900ff') .setTitle(favoriteColor) .setURL('http://mirano-rp.com') .setAuthor('Mirano RP ™', 'https://i.imgur.com/uHh71VQ.png', 'http://mirano-rp.com') .setThumbnail('https://i.imgur.com/uHh71VQ.png') .setTimestamp() .setFooter(hobbies, 'https://i.imgur.com/PNK8rlZ.png'); const row = new client.discord.MessageActionRow() .addComponents( new client.discord.MessageButton() .setLabel('Accéder au site !') .setEmoji('🛒') .setURL("http://mirano-rp.com") .setStyle('LINK'), ); // 回复用户提交 await interaction.reply({ embeds: [embed], components: [row] }); } } })
注意事项
- 确认你使用的discord.js版本:v13版本需要升级到13.7.0及以上才支持Modal API,v14版本直接原生支持,导入路径可根据你项目的现有写法调整,核心的交互分离逻辑不受版本影响。
- 模态框弹出后用户有15分钟的填写时间,只要在时限内提交,都会触发上述ModalSubmit事件,不需要额外加等待逻辑。
内容的提问来源于stack exchange,提问作者arthur hubaud
相关产品推荐
相关产品推荐

