Skip to main content

Chapitre 6 - Les commandes (partie 2)

Nous rejoindre sur Discord

Le chapitre précédent, nous avons vu la structure à adopter lorsque l'on veut créer une commande et comment envoyer une réponse à celle-ci. Lorsque l'on déclare des commandes, il est également possible d'ajouter des options à celle-ci. C'est ce que nous verrons dans ce chapitre.

Rappel sur la structure d'une commande :

const { SlashCommandBuilder } = require('discord.js'); // Constructeur de notre commande

module.exports = {
    data: new SlashCommandBuilder()
      .setName('command_name') // Nom de notre commande
      .setDescription('description'), // Description de notre commande
    async execute(interaction) { // Lorsque l'on éxécute une commande, on réalise une interaction
        /**
         * Instruction de l'évènement
         */
    },
};

Les options

Les options sont des paramètres que l'on peut ajouter à nos commandes. En fonction du type d'option que l'on choisit, il sera possible de récupérer des informations par la suite.

Liste des options disponibles :

  • Subcommand : défini l'option comme une sous commande
  • SubcommandGroup : défini l'option comme étant un groupe de sous commande
  • String : demande à l'utilisateur de saisir une chaine de caractère
  • Integer : demande à l'utilisateur de saisir un entier
  • Number : demande à l'utilisateur de saisir un nombre (la présence d'une , est possible)
  • Boolean : demande à l'utilisateur de sélectionner une valeur booléenne
  • User : demande à l'utilisateur de sélectionner un utilisateur
  • Channel : demande à l'utilisateur de sélectionner un channel
  • Role : demande à l'utilisateur de sélectionner un rôle
  • Mentionable : demande à l'utilisateur de sélectionner un élément mentionnable (channel, role, utilisateur, ...)
  • Attachment : demande à l'utilisateur d'envoyer un fichier dans la commande

Utiliser les options

Définir les options dans une commande : pour ajouter une option dans une commande, on ajoute la méthode correspondant à l'option souhaitée dans la déclaration de la commande. Voici un exemple de déclaration de commande :

const data = new SlashCommandBuilder()
	.setName('nom de la commande')
	.setDescription('Description de la commande')
	.addStringOption(option => option.setName('string').setDescription('Sélectionner une phrase'))
	.addIntegerOption(option => option.setName('int').setDescription('Sélectionner un entier'))
	.addBooleanOption(option => option.setName('choice').setDescription('Sélectionner un booléen'))
	.addUserOption(option => option.setName('user').setDescription('Sélectionner un utilisateur'))
	.addChannelOption(option => option.setName('channel').setDescription('Sélectionner un channel'))
	.addRoleOption(option => option.setName('role').setDescription('Sélectionner un role'))
	.addNumberOption(option => option.setName('num').setDescription('Sélectionner un nombre'))
	.addMentionableOption(option => option.setName('mentionable').setDescription('Mentionner quelque chose'))
	.addAttachmentOption(option => option.setName('attachment').setDescription('Ajouter une pièce jointe'));

À noter : lorsque vous déclarez une option, le nom de celle-ci est très important. Ce dernier ne peut pas contenir de majuscule, ni d'espace. Chaque nom est unique au sein d'une même commande, lorsque l'on veut récupérer la valeur d'une option, il faudra utiliser son nom.

Récupérer la valeur d'une option : pour récupérer les valeurs d'une option, allons dans notre variable interaction. Cette variable contient un attribut options qui contient toutes les valeurs des options sélectionnés par l'utilisateur (interaction.options). Voici comment récupérer les valeurs pour chaque option :

const string = interaction.options.getString('string');
const integer = interaction.options.getInteger('int');
const boolean = interaction.options.getBoolean('choice');
const user = interaction.options.getUser('user'); // Les deux appels sont autorisés
const member = interaction.options.getMember('user'); // Récupère plus d'informations sur l'utilsiateur
const channel = interaction.options.getChannel('channel');
const role = interaction.options.getRole('role');
const number = interaction.options.getNumber('number');
const mentionable = interaction.options.getMentionable('mentionable');
const attachment = interaction.options.getAttachment('attachment');

console.log({ string, integer, boolean, user, member, channel, role, mentionable, attachment, number }); // Utilisons les logs pour voir ce qu'il se passe avec les valeurs d'options.

Paramétrer les options

Lorsque vous ajoutez une option dans une commande, il est possible de lui ajouter d'ajouter des paramètres à cette option. Les paramètres vont modifier le comportement.

Parmi la liste des paramètres pour une option, certains sont communs à tous les types d'options :

  • setName() : (Obligatoire) nom à l'option
  • setDescription() : (obligatoire) description de l'option
  • setRequired() : est-ce que l'option est obligatoire ou non

Les paramètres globaux : ces paramètres peuvent être utilisés sur chaque type d'options

option
  .setName("Nom de l'option")
  .setDescription("Description de l'option")
  .setRequired(true) // option obligatoire pour exécuter la commande

Les choix : les choix sont des valeurs prédéterminées auquel on a associé une valeur lorsqu'il est sélectionné.

Lorsque dans une commande, vous ajoutez des choix, l'utilisateur ne sera pas en mesure de choisir une valeur personnelle. L'ajout de choix est possible sur les options de types : String, Number et Integer. Pour définir les choix dans une option, il faudra ajouter la méthode suivante dans la déclaration de l'option :

option
  .addChoices(
    { name: 'Nom option 1', value: "valeur de l'opion 1" },
    { name: 'Nom option 2', value: "valeur de l'opion 2" },
  )

Min et Max : Il est possible de déterminer des valeurs minimums et maximum. Pour les options Integer et Number, les méthodes setMin() et setMax sont des filtres qui permettent de définir une limite dans la saisie de l'utilisateur. La même option est possible pour la taille d'une phrase envoyée dans un String avec setMinLength() et setMaxLength().

Les complètes des paramètres d'options


Les sous commandes et groupes de commandes

Pour comprendre le fonctionnement des sous commandes, nous allons créer une nouvelle commande que nous allons appeler mentions. L'objectif de cette commande va être de mentionner des utilisateurs, des rôles et des channels.

const wait = require('node:timers/promises').setTimeout;

const { SlashCommandBuilder } = require('discord.js'); // Constructeur de notre commande

module.exports = {
    data: new SlashCommandBuilder()
        .setName('mentions')
        .setDescription('Mentionner quelque chose')
        .setDMPermission(false),
    async execute(interaction) {
        await interaction.reply({
            content: 'Utilisation de la commande mention',
        });
    },
};

Les sous commandes

Les sous commandes ont les mêmes prérequis que les commandes, elles ont besoin d'un nom, d'une description, ... L'utilisation d'une sous commande permet de regrouper un ensemble de commande dans un même endroit. On peut, par exemple, l'utiliser pour des commandes de configuration. Dans notre exemple, on va créer 2 sous commandes :

  • La première pour mentionner un utilisateur
  • La seconde pour mentionner un rôle

Pour ajouter ces deux sous commandes, nous allons modifier la déclaration de notre commande principale en ajoutant une méthode .addSubCommand :

data: new SlashCommandBuilder()
    .setName('mentions')
    .setDescription('Mentionner quelque chose')
    .setDMPermission(false)
    .addSubcommand((subcommand) =>
        subcommand
            .setName('utilisateur')
            .setDescription('Mentionner un utilisateur')
            .addUserOption((option) =>
                option.setName('user').setDescription("Sélectionner l'utilisateur").setRequired(true)
            )
    )
    .addSubcommand((subcommand) =>
        subcommand
            .setName('role')
            .setDescription('Mentionner un role')
            .addRoleOption((option) =>
                option.setName('role').setDescription('Sélectionner le role à mentionner').setRequired(true)
            )
    )

Résultat :

Pour récupérer une sous commande, utilisez interaction.options.getSubCommand(). Ensuite, en fonction du nom de la sous commande récupérée, on peut choisir les instructions à réaliser :

const subcommand = interaction.options.getSubcommand();

if (subcommand === 'utilisateur') {
    // On va mentionner un utilisateur
    const user = interaction.options.getMember('utilisateur');
    console.log(user);
}

if (subcommand === 'role') {
    // On va mentionner un role
    const role = interaction.options.getRole('role');
    console.log(role);
}

Dans une subcommand, il est impossible d'ajouter de nouvelle sous commande. Pour cela, il faut utiliser les groupes de sous commandes

Les groupes de sous commandes

Comme pour les sous commandes, les groupes de sous commandes doivent être ajoutés dans la déclaration de notre commande principale. La particularité de cette méthode est qu'elle peut accepter plusieurs sous commandes dans ses paramètres.

data: new SlashCommandBuilder()
    .setName('mentions')
    .setDescription('Mentionner quelque chose')
    .setDMPermission(false)
    .addSubcommandGroup((group) =>
        group
            .setName('channels')
            .setDescription("Sélection d'un channel")
            .addSubcommand((subcommand) =>
                subcommand.setName('subcommand-1').setDescription('Première sous commande')
            )
            .addSubcommand((subcommand) =>
                subcommand.setName('subcommand-2').setDescription('Seconde sous commande')
            )
    ),

L'utilisation des groupes de sous commandes est identique à celui des commandes, récupérez le sous-groupe utilisé et ensuite récupéré la sous commande :

const subgroup = interaction.options.getSubcommandGroup();
const subcommand = interaction.options.getSubcommand();

switch (subgroup) {
  case "sous-groupe-1":
    if (subcommand === 'sous-commande-1') {
      // Action
    }
    
    if (subcommand === 'sous-commande-2') {
      // Action
    }
  case "sous-groupe-2":
    if (subcommand === 'sous-commande-1') {
      // Action
    }
    
    if (subcommand === 'sous-commande-2') {
      // Action
    }
}

Les permissions

Il est possible de définir des permissions pour une commande, ces permissions permettent de filtrer l'utilisation de celle-ci. Par exemple, il est possible de choisir si une commande peut être utilisée en MP ou non avec .setDMPermission(true|false) :

const data = new SlashCommandBuilder()
	.setName('ping')
	.setDescription('Répond pong')
	.setDMPermission(false); // False : non utilisable en MP | True : Utilisable en MP

Si vous souhaitez plus d'informations sur les permissions de commandes, vous pouvez aller sur ce lien : Slash command permissions


Exercice

Ping un utilisateur (Facile)

Modifier la commande /ping pour que l'utilisateur soit obligé de sélectionner un membre présent sur le serveur et obtenir la réponse suivante :

Minuteur 2.0 (Facile)

Reprenez l'exercice du minuteur du chapitre précédent, et avec les options, demander à l'utilisateur de sélectionner la valeur du minuteur.