Modales
Con los modales (modals) puedes crear formularios emergentes que permiten a los usuarios proporcionar entradas formateadas a través de envíos. Cubriremos cómo crear, mostrar y recibir formularios modales utilizando discord.js.
CONSEJO
Esta página es un seguimiento de la sección de interacciones (comandos de barra). Por favor, lee atentamente esa sección primero para que puedas comprender los métodos utilizados en esta sección.
Construyendo y respondiendo con modales
A diferencia de los componentes de mensaje, los modales no son estrictamente componentes en sí mismos. Son una estructura de devolución de llamada (callback) utilizada para responder a las interacciones.
CONSEJO
Puedes tener un máximo de cinco ActionRowBuilder
open in new window por constructor de modales y un TextInputBuilder
open in new window dentro de un ActionRowBuilder
open in new window. Actualmente, no puedes usar StringSelectMenuBuilder
open in new window p ButtonBuilder
open in new window en los contenedores de componentes de los modales.
Para crear un modal, crea un nuevo ModalBuilder
open in new window. Luego puedes usar los métodos "setters" para agregar el ID personalizado (custom_id
) y el título (title
).
const { Events, ModalBuilder } = require('discord.js');
client.on(Events.InteractionCreate, async interaction => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName === 'ping') {
const modal = new ModalBuilder()
.setCustomId('miModal')
.setTitle('Mi Modal');
// TODO: Agregar componentes al modal...
}
});
2
3
4
5
6
7
8
9
10
11
12
13
CONSEJO
La id personalizada (custom_id
) es una string definida por ti de hasta 100 caracteres. Utiliza este campo para asegurarte de que puedas definir de forma única todas las interacciones procedentes de tus modales.
El siguiente paso es agregar los campos de entrada en los cuales los usuarios pueden ingresar texto libremente al responder. Agregar los campos de entrada es similar a agregar componentes a los mensajes.
Al final, llamamos a ChatInputCommandInteraction#showModal
open in new window para mostrar el modal al usuario.
ADVERTENCIA
Si estás utilizando TypeScript, deberás especificar el tipo de componentes que contiene tu contenedor de componentes. Esto se puede hacer especificando el parámetro genérico en ActionRowBuilder
open in new window.
- new ActionRowBuilder()
+ new ActionRowBuilder<ModalActionRowComponentBuilder>()
2
const { ActionRowBuilder, Events, ModalBuilder, TextInputBuilder, TextInputStyle } = require('discord.js');
client.on(Events.InteractionCreate, async interaction => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName === 'ping') {
// Crear el modal
const modal = new ModalBuilder()
.setCustomId('miModal')
.setTitle('Mi Modal');
// Añadir componentes al modal
// Crear los componentes de entrada de texto
const favoriteColorInput = new TextInputBuilder()
.setCustomId('entradaColorFavorito')
// La etiqueta es el indicador que el usuario ve para esta entrada
.setLabel("What's your favorite color?")
// Corto significa una sola línea de texto
.setStyle(TextInputStyle.Short);
const hobbiesInput = new TextInputBuilder()
.setCustomId('entradaPasatiempos')
.setLabel('¿Cuáles son tus aficiones favoritas?')
// Párrafo significa varias líneas de texto.
.setStyle(TextInputStyle.Paragraph);
// Un contenedor de componentes solo contiene una entrada de texto,
// por lo que necesita un contenedor de componentes por cada entrada de texto.
const firstActionRow = new ActionRowBuilder().addComponents(favoriteColorInput);
const secondActionRow = new ActionRowBuilder().addComponents(hobbiesInput);
// Añadir entradas al modal
modal.addComponents(firstActionRow, secondActionRow);
// Mostrar el modal al usuario
await interaction.showModal(modal);
}
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Reinicia tu bot y vuelve a utilizar el comando /ping
. Deberías ver un formulario emergente parecido a la imagen de abajo:
![](/assets/modal-example.1a91ffff.png)
ADVERTENCIA
Mostrar un modal debe ser la primera respuesta a una interacción. No se puede defer()
o deferUpdate()
y mostrar un modal más tarde.
Estilos de entrada
Actualmente hay dos estilos de entrada disponibles::
Short
, una entrada de texto de una sola línea;Paragraph
, una entrada de texto de varias líneas similar a la etiqueta HTML<textarea>
;
Propiedades de entradas
Además del customId
, label
y style
, una entrada de texto puede personalizarse de varias formas para aplicar validación, preguntar al usuario o establecer valores por defecto a través de los métodos TextInputBuilder
open in new window:
const input = new TextInputBuilder()
// establece el número máximo de caracteres permitidos
.setMaxLength(1000)
// establece el número mínimo de caracteres necesarios para el envío
.setMinLength(10)
// establece un marcador de posición de cadena para preguntar al usuario
.setPlaceholder('¡Ingresa un texto!')
// establecer un valor por defecto para pre-llenar la entrada
.setValue('Predeterminado')
// requiere un valor en este campo de entrada
.setRequired(true);
2
3
4
5
6
7
8
9
10
11
Recibiendo envíos de modales
Colectores de interacciones
Los envíos de modales se pueden recopilar dentro del ámbito de la interacción que los mostró utilizando un InteractionCollector
open in new window, o el método ChatInputCommandInteraction#awaitModalSubmit
open in new window a modo de promesa. Ambos proporcionan instancias de la clase ModalSubmitInteraction
open in new window como elementos recogidos.
Para obtener una guía detallada sobre la recepción de componentes de mensajes a través de recopiladores, consulte la guía de recopiladores.
El evento interactionCreate
Para recibir un evento ModalSubmitInteraction
open in new window, adjunta un receptor de eventos Client#event:interactionCreate
open in new window a su cliente y usa la protección de tipado BaseInteraction#isModalSubmit
open in new window para asegurarte de que solo recibe modales:
client.on(Events.InteractionCreate, interaction => {
if (!interaction.isModalSubmit()) return;
console.log(interaction);
});
2
3
4
Responder a los envíos de modales
La clase ModalSubmitInteraction
open in new window proporciona los mismos métodos que la clase ChatInputCommandInteraction
open in new window. Estos métodos se comportan igual:
reply()
editReply()
deferReply()
fetchReply()
deleteReply()
followUp()
Si el modal se mostró desde un ButtonInteraction
open in new window o StringSelectMenuInteraction
open in new window, también proporcionará estos métodos, que se comportan igual:
update()
deferUpdate()
client.on(Events.InteractionCreate, async interaction => {
if (!interaction.isModalSubmit()) return;
if (interaction.customId === 'miModal') {
await interaction.reply({ content: '¡Tu envío se ha recibido correctamente!' });
}
});
2
3
4
5
6
CONSEJO
Si estás usando typescript, puedes usar la protección de tipado ModalSubmitInteraction#isFromMessage
open in new window, para asegurarte de que la interacción recibida proviene de un MessageComponentInteraction
.
Extrayendo datos desde un modal recibido
Lo más probable es que necesites leer los datos enviados por el usuario en el modal. Puedes hacerlo accediendo al ModalSubmitInteraction#fields
open in new window. Desde ahí puedes llamar a ModalSubmitFields#getTextInputValue
open in new window con el id personalizado de la entrada de texto para obtener el valor.
client.on(Events.InteractionCreate, interaction => {
if (!interaction.isModalSubmit()) return;
// Obtener los datos introducidos por el usuario
const favoriteColor = interaction.fields.getTextInputValue('entradaColorFavorito');
const hobbies = interaction.fields.getTextInputValue('entradaPasatiempos');
console.log({ favoriteColor, hobbies });
});
2
3
4
5
6
7
8