Discord.js中Modal Collector提交回调不触发问题求助
问题原因
你的代码有两个核心错误,导致收集器永远触发不了。你之前用同思路写按钮收集器能生效,是因为按钮属于挂载在频道消息上的组件,在消息组件收集器的捕获范围内,但模态框提交不适用这套逻辑:
- 收集器挂载位置、类型完全错误
channel.createMessageComponentCollector只能收集频道消息上挂载的按钮、下拉选择菜单这类组件触发的交互,根本捕获不到模态框提交事件- 你传入的
componentType: 'TEXT_INPUT'对应的是模态框内部的输入框组件,这类组件本身不会单独触发交互事件,只有用户提交整个模态框时才会统一返回提交数据,且TEXT_INPUT组件无法挂载在普通频道消息上,传这个参数没有任何意义
- 模态框提交的专属收集器,必须绑定在你调用
showModal()的那个原始交互对象上,不是绑定在频道对象上。
修正后的代码
直接替换原有收集器相关逻辑即可,弹出模态框的基础逻辑无需改动:
// 创建模态框和输入框、弹出模态框的逻辑保持不变 const testModal = new Modal() .setCustomId("test_modal") .setTitle("Test") const input = new Discord.MessageActionRow().addComponents( new Discord.TextInputComponent() .setCustomId("test_input") .setLabel("Test Input:") .setStyle("SHORT") .setPlaceholder("Input Something") .setRequired(true) ) testModal.addComponents(input) await interaction.showModal(testModal) // 正确:在弹出模态框的原始交互上创建模态框专属收集器 // 加filter过滤无关交互,避免其他用户操作、错配模态框导致异常 const filter = (i) => i.customId === 'test_modal' && i.user.id === interaction.user.id; const collector = interaction.createModalSubmitCollector({ filter, time: 15000 }); collector.on("collect", async (modalSubmitInteraction) => { // 可以通过getTextInputValue拿到输入框的提交内容 const submitContent = modalSubmitInteraction.fields.getTextInputValue('test_input') console.log('收到模态框提交,输入内容:', submitContent) // 必须在3秒内回复提交交互,否则Discord客户端会判定提交失败 await modalSubmitInteraction.reply({ content: "模态框收集成功", ephemeral: true }) }) collector.on("end", (collected) => { if (collected.size === 0) { // 这里可以写15秒超时未提交的兜底逻辑 console.log('模态框提交超时') } })
补充说明
- 如果只需要接收一次模态框提交,可以不用写收集器事件,直接用更简洁的
await interaction.awaitModalSubmit({ filter, time: 15000 })接收提交对象即可 - 模态框提交交互的回复规则和按钮、斜杠命令完全一致,超过3秒未回复就会触发客户端报错,需要延迟回复的话记得先调用
deferReply()占位 - 不要在
collect回调里额外判断isModalSubmit(),专属收集器只会返回模态框提交类型的交互,这个判断属于冗余逻辑
内容的提问来源于stack exchange,提问作者N0rmal
相关产品推荐
相关产品推荐

