I was trying to create a collector for my modal using Discord.js. With the code below I don't get an error, but the modal fails in Discord and the code in collector.on
never runs.
I have used a similar approach to be able to create a button collector by replaycing the pententType:
with "BUTTON"
, which runs perfectly fine. I am not sure if there is a different way to listen for modals but I cant find much about it in the documentation.
//create modal and input field and display them
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)
//create collector
const collector = await interaction.channel.createMessageComponentCollector({ ponentType: 'TEXT_INPUT', time: 15000 })
//listen to collector
await collector.on("collect", modal=>{
if (modal.isModalSubmit() && modal.customId === 'test_modal') { //only left side
console.log(modal)
modal.reply("Modal collected")
}
})
Thanks for your help in advance
I was trying to create a collector for my modal using Discord.js. With the code below I don't get an error, but the modal fails in Discord and the code in collector.on
never runs.
I have used a similar approach to be able to create a button collector by replaycing the pententType:
with "BUTTON"
, which runs perfectly fine. I am not sure if there is a different way to listen for modals but I cant find much about it in the documentation.
//create modal and input field and display them
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)
//create collector
const collector = await interaction.channel.createMessageComponentCollector({ ponentType: 'TEXT_INPUT', time: 15000 })
//listen to collector
await collector.on("collect", modal=>{
if (modal.isModalSubmit() && modal.customId === 'test_modal') { //only left side
console.log(modal)
modal.reply("Modal collected")
}
})
Thanks for your help in advance
Share Improve this question asked Jun 28, 2022 at 19:14 N0rmalN0rmal 371 gold badge1 silver badge9 bronze badges1 Answer
Reset to default 5Discord.JS implementation for Modal
s is a little bit tricky (or at least, unintuitive if you have experience with handling interactions for buttons, etc). To summarize, the Interaction
you get when the DiscordClient
receives a Modal
does not extend the same type of Interaction
you get when you receive a MessageComponentInteraction
(note the subtext: extends Interaction implements InteractionResponses
) (e.g. a ButtonInteraction
(note the subtext: 'extends MessageComponentInteraction'), SelectMenuInteraction
, etc). As such, the createMessageComponentCollector
does not ever receive Interaction
s that hold a ModalSubmitInteraction
(notice the subtext: extends Interaction implements InteractionResponses
)-- since a ModalSubmitInteraction
is not a MessageComponentInteraction
(the former examples ButtonInteraction
and SelectMenuInteraction
are).
The ModalSubmitInteraction
is to a ModalInteraction
what a MessageComponentInteraction
is to a ButtonInteraction
. Does that make sense? ModalSubmitInteraction
and MessageComponentInteraction
can be considered as 'siblings', while ButtonInteraction
and/or SelectMenuInteraction
, etc. would be considered as 'children of MessageComponentInteraction
'. For further clarification I would take a look at Discord's Documentation for Modal
s, as it provides some context for how you'd use them with Discord.JS.
There are likely other ways to handle the 'collection' of a Modal
, but the way I would do it in the example you posted is through the awaitModalSubmit
method on the MessageComponentInteraction
class. For example:
const fields = {
age: new TextInputComponent()
.setCustomId(`age`)
.setLabel(`What is your age?`)
.setStyle(`SHORT`)
.setRequired(true),
.setPlaceholder(`90 years young`)
name: new TextInputComponent()
.setCustomId(`name`)
.setLabel(`What is your name?`)
.setStyle(`SHORT`)
.setRequired(true)
.setPlaceholder(`John Doe`)
}
const modal = new Modal()
.setCustomId(`test_modal`)
.setTitle(`test`)
.setComponents(
// Note that unlike how you might expect when sending a Message with Components,
// MessageActionRows for Modals **can only accept TextInputComponents** (no Buttons or
// SelectMenus or other Components), and each Action Row can have a maximum of just one
// TextInputComponent. You can have a maximum of 5 Action Rows in a Modal, so you have
// a maximum of 5 Text Inputs per Modal.
new MessageActionRow().setComponents(fields.age),
new MessageActionRow().setComponents(fields.name),
)
// Show the Modal to the User in response to the Interaction
await interaction.showModal(modal)
// Get the Modal Submit Interaction that is emitted once the User submits the Modal
const submitted = await interaction.awaitModalSubmit({
// Timeout after a minute of not receiving any valid Modals
time: 60000,
// Make sure we only accept Modals from the User who sent the original Interaction we're responding to
filter: i => i.user.id === interaction.user.id,
}).catch(error => {
// Catch any Errors that are thrown (e.g. if the awaitModalSubmit times out after 60000 ms)
console.error(error)
return null
})
// If we got our Modal, we can do whatever we want with it down here. Remember that the Modal
// can have multiple Action Rows, but each Action Row can have only one TextInputComponent. You
// can use the ModalSubmitInteraction.fields helper property to get the value of an input field
// from it's Custom ID. See https://old.discordjs.dev/#/docs/discord.js/stable/class/ModalSubmitFieldsResolver for more info.
if (submitted) {
const [ age, name ] = Object.keys(fields).map(key => submitted.fields.getTextInputValue(fields[key].customId))
await submitted.reply({
content: `Your age is ${age}, and your name is ${name}. Hi!`
})
}
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742287671a4415617.html
评论列表(0条)