Composants d'Affichage
Bien que vous puissiez être familier avec les embeds dans Discord, il existe d'autres façons de styliser et de formater les messages de votre application en utilisant les composants d'affichage, un ensemble complet d'éléments de mise en page et de contenu.
Pour utiliser les composants d'affichage, vous devez passer le drapeau IsComponentsV2 (dans les docs : MessageFlags) lors de l'envoi d'un message. Vous n'avez besoin d'utiliser ce drapeau que lors de l'envoi d'un message utilisant le système de composants d'affichage, pas lors du report des réponses d'interaction.
L'utilisation de ce système en passant le drapeau IsComponentsV2 comporte un ensemble de mises en garde :
- Vous ne pouvez pas envoyer
content,poll,embeds, oustickers. - Vous ne pouvez pas désactiver l'utilisation des composants d'affichage lors de la modification d'un message
- Vous pouvez opter pour l'utilisation des composants d'affichage lors de la modification d'un message tout en définissant explicitement
content,poll,embeds, etstickersà null. - Les messages peuvent avoir jusqu'à 40 composants au total (les composants imbriqués comptent !)
- La quantité de texte sur tous les composants d'affichage de texte ne peut pas dépasser 4000 caractères.
- Tous les fichiers joints doivent être explicitement référencés dans un composant (consultez les sections Miniature, Galerie Média, et Fichier).
L'id du composant
Tous les composants peuvent recevoir un champ id optionnel et unique contenant un identifiant entier 32 bits pour les identifier ultérieurement dans les réponses d'interaction. Ne confondez pas ceci avec le champ custom_id pour les composants interactifs ! Vous pouvez trouver plus d'informations à ce sujet dans la documentation de l'API Discord. Discord remplira automatiquement l'id des composants qui n'ont pas l'id spécifié dans la charge utile de manière séquentielle en commençant par 1. La valeur id 0 est traitée comme vide. L'ordre dans lequel les composants sont remplis automatiquement est un détail d'implémentation et n'est pas officiellement documenté. Si vous souhaitez travailler avec l'id (par exemple pour trouver et remplacer le contenu d'un composant spécifique plus tard), vous devez le spécifier explicitement.
Dans les sections suivantes, nous expliquons en détail tous les types de composants d'affichage disponibles et vous montrons quelques exemples sur comment vous pouvez les utiliser.
Affichage de texte
Les composants Text Display vous permettent d'ajouter du texte formaté en markdown à votre message et de remplacer directement le champ content lorsque vous choisissez d'utiliser des composants d'affichage. Vous pouvez utiliser la classe TextDisplayBuilder pour créer facilement un composant Text Display.
L'envoi de mentions d'utilisateurs et de rôles dans les composants d'affichage de texte notifiera les utilisateurs et les rôles ! Vous pouvez et devez contrôler
les mentions avec l'option de message allowedMentions.
L'exemple ci-dessous montre comment vous pouvez envoyer un composant Text Display dans un canal.
const { TextDisplayBuilder, MessageFlags } = require('discord.js');
const exampleTextDisplay = new TextDisplayBuilder().setContent(
'This text is inside a Text Display component! You can use **any __markdown__** available inside this component too.',
);
await channel.send({
components: [exampleTextDisplay],
flags: MessageFlags.IsComponentsV2,
});Section
Les sections représentent du texte (un à trois composants Text Display) avec un accessoire. L'accessoire peut être soit une image (miniature) soit un bouton. Si vous ne souhaitez pas envoyer d'accessoire, utilisez plutôt un composant Text Display. Vous pouvez utiliser la classe SectionBuilder pour créer facilement un composant Section :
const { SectionBuilder, ButtonStyle, MessageFlags } = require('discord.js');
const exampleSection = new SectionBuilder()
.addTextDisplayComponents(
(textDisplay) =>
textDisplay.setContent(
'This text is inside a Text Display component! You can use **any __markdown__** available inside this component too.',
),
(textDisplay) => textDisplay.setContent('Using a section, you may only use up to three Text Display components.'),
(textDisplay) => textDisplay.setContent('And you can place one button or one thumbnail component next to it!'),
)
.setButtonAccessory((button) =>
button.setCustomId('exampleButton').setLabel('Button inside a Section').setStyle(ButtonStyle.Primary),
);
await channel.send({
components: [exampleSection],
flags: MessageFlags.IsComponentsV2,
});Miniature
Une Miniature est un composant d'affichage qui est visuellement similaire au champ thumbnail à l'intérieur d'un embed. Les miniatures sont ajoutées comme accessoire dans un composant Section, supportent le texte alternatif pour l'accessibilité, et peuvent être marquées comme spoiler. Vous pouvez utiliser la classe ThumbnailBuilder pour créer facilement un composant Miniature :
const { AttachmentBuilder, SectionBuilder, MessageFlags } = require('discord.js');
const file = new AttachmentBuilder('../assets/image.png');
const exampleSection = new SectionBuilder()
.addTextDisplayComponents((textDisplay) =>
textDisplay.setContent(
'This text is inside a Text Display component! You can use **any __markdown__** available inside this component too.',
),
)
.setThumbnailAccessory(
(thumbnail) => thumbnail.setDescription('alt text displaying on the image').setURL('attachment://image.png'), // Supports arbitrary URLs such as 'https://i.imgur.com/AfFp7pu.png' as well.
);
await channel.send({
components: [exampleSection],
files: [file],
flags: MessageFlags.IsComponentsV2,
});Pour plus d'informations sur l'utilisation des pièces jointes dans les composants, consultez le guide sur l'attachement d'images dans les embeds.
Galerie Médias
Une Galerie Médias est un composant d'affichage qui peut afficher une grille de jusqu'à 10 pièces jointes multimédias. Chaque élément média peut avoir un texte alternatif optionnel (description) et peut être marqué comme spoiler. Vous pouvez utiliser les classes MediaGalleryBuilder et MediaGalleryItemBuilder pour créer facilement un composant Galerie Médias et ses éléments :
const { AttachmentBuilder, MediaGalleryBuilder, MessageFlags } = require('discord.js');
const file = new AttachmentBuilder('../assets/image.png');
const exampleGallery = new MediaGalleryBuilder().addItems(
(mediaGalleryItem) =>
mediaGalleryItem
.setDescription('alt text displaying on an image from the AttachmentBuilder')
.setURL('attachment://image.png'),
(mediaGalleryItem) =>
mediaGalleryItem
.setDescription('alt text displaying on an image from an external URL')
.setURL('https://i.imgur.com/AfFp7pu.png')
.setSpoiler(true), // Will display as a blurred image
);
await channel.send({
components: [exampleGallery],
files: [file],
flags: MessageFlags.IsComponentsV2,
});Fichier
Un Fichier est un composant d'affichage qui peut afficher un seul fichier téléchargé dans le corps du message. En utilisant plusieurs composants Fichier, vous pouvez télécharger et afficher plusieurs fichiers dans un seul message. Les composants Fichier ne peuvent pas avoir de textes alternatifs (description), contrairement à un composant Miniature ou Galerie Médias, mais peuvent être marqués comme spoiler. Vous pouvez utiliser la classe FileBuilder pour créer facilement un composant Fichier :
const { AttachmentBuilder, FileBuilder, MessageFlags } = require('discord.js');
const file = new AttachmentBuilder('../assets/guide.pdf');
const exampleFile = new FileBuilder().setURL('attachment://guide.pdf');
await channel.send({
components: [exampleFile],
files: [file],
flags: MessageFlags.IsComponentsV2,
});Séparateur
Un Séparateur est un composant de mise en page qui ajoute un remplissage vertical et une division visuelle optionnelle entre les composants. Vous pouvez sélectionner la quantité de remplissage utilisée pour le composant Séparateur (petit ou grand) ainsi que si un séparateur visuel doit être affiché (par défaut true). Vous pouvez utiliser la classe SeparatorBuilder pour créer facilement un composant Séparateur.
Lorsqu'un composant Séparateur est utilisé sans aucun composant non-Séparateur dans la charge utile du message, le message n'aura pas de contenu visible.
L'exemple ci-dessous montre comment vous pouvez envoyer un composant Séparateur dans un canal, en séparant deux composants Text Display.
const { TextDisplayBuilder, SeparatorBuilder, SeparatorSpacingSize, MessageFlags } = require('discord.js');
const exampleTextDisplay = new TextDisplayBuilder().setContent(
'This text is inside a Text Display component! You can use **any __markdown__** available inside this component too.',
);
const exampleSeparator = new SeparatorBuilder()
.setDivider(false) // No line displayed
.setSpacing(SeparatorSpacingSize.Large);
await channel.send({
components: [exampleTextDisplay, exampleSeparator, exampleTextDisplay],
flags: MessageFlags.IsComponentsV2,
});Conteneur
Un Conteneur est un composant de mise en page qui regroupe ses composants enfants à l'intérieur d'une boîte arrondie visuellement distincte avec une couleur d'accent optionnelle sur la gauche, similaire à l'apparence du message embed. Contrairement aux embeds, ne pas spécifier de couleur fera correspondre le côté gauche du composant Conteneur à la couleur de fond. Vous pouvez marquer les composants Conteneur comme spoiler, ce qui floute tout le contenu dans le conteneur. Vous pouvez utiliser la classe ContainerBuilder pour créer facilement un composant Conteneur.
L'exemple ci-dessous montre comment envoyer un composant Conteneur dans un canal. Il contient :
- un composant Text Display ;
- un composant Action Row avec un composant User Select ;
- un composant Séparateur ;
- un composant Section avec deux composants Text Display et un accessoire de composant Button.
const { ContainerBuilder, UserSelectMenuBuilder, ButtonStyle, MessageFlags } = require('discord.js');
const exampleContainer = new ContainerBuilder()
.setAccentColor(0x0099ff)
.addTextDisplayComponents((textDisplay) =>
textDisplay.setContent(
'This text is inside a Text Display component! You can use **any __markdown__** available inside this component too.',
),
)
.addActionRowComponents((actionRow) =>
actionRow.setComponents(new UserSelectMenuBuilder().setCustomId('exampleSelect').setPlaceholder('Select users')),
)
.addSeparatorComponents((separator) => separator)
.addSectionComponents((section) =>
section
.addTextDisplayComponents(
(textDisplay) =>
textDisplay.setContent(
'This text is inside a Text Display component! You can use **any __markdown__** available inside this component too.',
),
(textDisplay) => textDisplay.setContent('And you can place one button or one thumbnail component next to it!'),
)
.setButtonAccessory((button) =>
button.setCustomId('exampleButton').setLabel('Button inside a Section').setStyle(ButtonStyle.Primary),
),
);
await channel.send({
components: [exampleContainer],
flags: MessageFlags.IsComponentsV2,
});