Guide discord.js
Autres interactions

Modales

Avec les modales, vous pouvez créer des formulaires contextuels qui permettent aux utilisateurs de vous fournir des entrées formatées par des soumissions. Nous couvrirons comment créer, afficher et recevoir des formulaires modaux avec discord.js !

Cette page est un suivi de la page interactions (commandes slash). Veuillez lire attentivement cette section en premier, afin que vous puissiez comprendre les méthodes utilisées dans cette section.

Construction et réponse avec les modales

Contrairement aux composants de message, les modales ne sont pas strictement des composants eux-mêmes. Ce sont des structures de rappel utilisées pour répondre aux interactions.

Vous pouvez avoir un maximum de cinq ActionRowBuilders par constructeur de modal, et un TextInputBuilder dans un ActionRowBuilder. Actuellement, vous ne pouvez utiliser que des TextInputBuilders dans les constructeurs de lignes d'action modale.

Pour créer une modal, vous construisez un nouveau ModalBuilder. Vous pouvez ensuite utiliser les setters pour ajouter l'ID personnalisé et le titre.

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('myModal').setTitle('My Modal');

		// TODO: Add components to modal...
	}
});

L'ID personnalisé est une chaîne définie par le développeur de jusqu'à 100 caractères. Utilisez ce champ pour vous assurer que vous pouvez définir de manière unique toutes les interactions entrantes de vos modales !

L'étape suivante consiste à ajouter les champs de saisie dans lesquels les utilisateurs qui répondent peuvent entrer du texte libre. L'ajout d'entrées est similaire à l'ajout de composants aux messages.

En fin de compte, nous appelons ensuite ChatInputCommandInteraction#showModal pour afficher la modal à l'utilisateur.

Si vous utilisez typescript, vous devez spécifier le type de composants que votre ligne d'action contient. Cela peut être fait en spécifiant le paramètre générique dans ActionRowBuilder:

- new ActionRowBuilder()
+ new ActionRowBuilder<ModalActionRowComponentBuilder>()
const { ActionRowBuilder, Events, ModalBuilder, TextInputBuilder, TextInputStyle } = require('discord.js');

client.on(Events.InteractionCreate, async (interaction) => {
	if (!interaction.isChatInputCommand()) return;

	if (interaction.commandName === 'ping') {
		// Create the modal
		const modal = new ModalBuilder().setCustomId('myModal').setTitle('My Modal');

		// Add components to modal

		// Create the text input components
		const favoriteColorInput = new TextInputBuilder()
			.setCustomId('favoriteColorInput')
			// The label is the prompt the user sees for this input
			.setLabel("What's your favorite color?")
			// Short means only a single line of text
			.setStyle(TextInputStyle.Short);

		const hobbiesInput = new TextInputBuilder()
			.setCustomId('hobbiesInput')
			.setLabel("What's some of your favorite hobbies?")
			// Paragraph means multiple lines of text.
			.setStyle(TextInputStyle.Paragraph);

		// An action row only holds one text input,
		// so you need one action row per text input.
		const firstActionRow = new ActionRowBuilder().addComponents(favoriteColorInput);
		const secondActionRow = new ActionRowBuilder().addComponents(hobbiesInput);

		// Add inputs to the modal
		modal.addComponents(firstActionRow, secondActionRow);

		// Show the modal to the user
		await interaction.showModal(modal); 
	}
});

Redémarrez votre bot et invoquez la commande /ping à nouveau. Vous devriez voir un formulaire contextuel ressemblant à l'image ci-dessous :

Afficher une modal doit être la première réponse à une interaction. Vous ne pouvez pas defer() ou deferUpdate() puis afficher une modal plus tard.

Styles de saisie

Actélement, il existe deux styles de saisie différents disponibles :

  • Short, une entrée de texte d'une seule ligne ;
  • Paragraph, une entrée de texte multi-lignes similaire au HTML <textarea> ;

Propriétés d'entrée

En plus du customId, label et style, une entrée de texte peut être personnalisée de plusieurs façons pour appliquer une validation, inviter l'utilisateur ou définir des valeurs par défaut via les méthodes TextInputBuilder :

const input = new TextInputBuilder()
	// set the maximum number of characters to allow
	.setMaxLength(1_000)
	// set the minimum number of characters required for submission
	.setMinLength(10)
	// set a placeholder string to prompt the user
	.setPlaceholder('Enter some text!')
	// set a default value to pre-fill the input
	.setValue('Default')
	// require a value in this input field
	.setRequired(true);

Réception des soumissions de modalités

Collecteurs d'interactions

Les soumissions de modal peuvent être collectées dans le cadre de l'interaction qui l'a affiché en utilisant un InteractionCollector, ou la méthode promisifiée ChatInputCommandInteraction#awaitModalSubmit. Ces deux fournissent des instances de la classe ModalSubmitInteraction en tant qu'éléments collectés.

Pour un guide détaillé sur la réception des composants de message via des collecteurs, veuillez vous référer au guide des collecteurs.

L'événement interactionCreate

Pour recevoir un événement ModalSubmitInteraction, attachez un écouteur d'événement Client#interactionCreate à votre client et utilisez la garde de type BaseInteraction#isModalSubmit pour vous assurer que vous ne recevez que des modales :

client.on(Events.InteractionCreate, (interaction) => {
	if (!interaction.isModalSubmit()) return;
	console.log(interaction);
});

Répondre aux soumissions de modalités

La classe ModalSubmitInteraction fournit les mêmes méthodes que la classe ChatInputCommandInteraction. Ces méthodes se comportent également :

  • reply()
  • editReply()
  • deferReply()
  • fetchReply()
  • deleteReply()
  • followUp()

Si la modal a été affichée à partir d'une ButtonInteraction ou d'une StringSelectMenuInteraction, elle fournira également ces méthodes, qui se comportent également :

  • update()
  • deferUpdate()
client.on(Events.InteractionCreate, async (interaction) => {
	if (!interaction.isModalSubmit()) return;
	if (interaction.customId === 'myModal') {
		await interaction.reply({ content: 'Your submission was received successfully!' });
	}
});

Si vous utilisez typescript, vous pouvez utiliser la garde de type ModalSubmitInteraction#isFromMessage, pour vous assurer que l'interaction reçue provient d'une MessageComponentInteraction.

Extraction de données des soumissions de modalités

Vous devrez très probablement lire les données envoyées par l'utilisateur dans la modal. Vous pouvez le faire en accédant au ModalSubmitInteraction#fields. À partir de là, vous pouvez appeler ModalSubmitFields#getTextInputValue avec l'ID personnalisé de l'entrée de texte pour obtenir la valeur.

client.on(Events.InteractionCreate, (interaction) => {
	if (!interaction.isModalSubmit()) return;

	// Get the data entered by the user
	const favoriteColor = interaction.fields.getTextInputValue('favoriteColorInput');
	const hobbies = interaction.fields.getTextInputValue('hobbiesInput');
	console.log({ favoriteColor, hobbies });
});