aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Bots Discord

Créer des commandes slash Discord (discord.js v14)

Créer une commande slash Discord est la première étape pour écrire un bot Discord moderne. Les anciennes commandes basées sur les messages (comme !ping) ont été remplacées par l'interface native des slash commands de Discord : lorsqu'un utilisateur tape /, les commandes et leurs options s'affichent automatiquement avec une saisie validée. C'est désormais la méthode officielle. Dans ce tutoriel, nous allons construire un bot à commandes slash fonctionnel à partir de zéro avec discord.js v14 et Node.js 18+ : configuration du projet, définition des commandes avec SlashCommandBuilder, déploiement via l'API REST et réponse grâce à l'événement interactionCreate.

Configuration du projet et dépendances

Node.js 18 ou une version plus récente est requis ; discord.js v14 ne prend pas en charge les versions plus anciennes. Initialisez le projet dans un dossier vide et installez l'unique dépendance, le paquet discord.js :

mkdir discord-bot && cd discord-bot
npm init -y
npm install discord.js

Nous utiliserons CommonJS plutôt qu'ESM, donc aucune configuration supplémentaire n'est nécessaire dans package.json ; si vous préférez la syntaxe import moderne, vous pouvez ajouter "type": "module". Ce guide utilise du JavaScript basé sur require (CommonJS). Ne codez jamais en dur les secrets comme votre token et vos identifiants ; utilisez un fichier config.json ou des variables d'environnement :

{
  "token": "VOTRE_TOKEN_BOT",
  "clientId": "ID_APPLICATION",
  "guildId": "ID_SERVEUR_TEST"
}
  • token : obtenu depuis le Discord Developer Portal → onglet Bot.
  • clientId : l'ID de votre Application.
  • guildId : l'ID de votre serveur de test (activez le mode développeur, puis faites un clic droit sur le serveur pour le copier).

Définir des commandes avec SlashCommandBuilder

Les commandes slash sont définies avec la classe SlashCommandBuilder. Cette classe fait partie de discord.js (anciennement @discordjs/builders) et vous permet de définir le nom, la description et les options d'une commande de manière typée. Définissons une simple commande ping et une commande saluer qui prend un paramètre. Placer chaque commande dans son propre fichier au sein d'un dossier commands est une bonne pratique, mais pour plus de clarté nous utilisons ici un seul tableau :

const { SlashCommandBuilder } = require('discord.js');

const commands = [
  new SlashCommandBuilder()
    .setName('ping')
    .setDescription('Mesure la latence du bot'),

  new SlashCommandBuilder()
    .setName('saluer')
    .setDescription('Salue un utilisateur')
    .addUserOption(option =>
      option
        .setName('utilisateur')
        .setDescription('La personne à saluer')
        .setRequired(true)
    ),
].map(command => command.toJSON());

module.exports = { commands };

Vous pouvez ajouter des paramètres avec des méthodes comme .addUserOption, .addStringOption et .addIntegerOption. setRequired(true) rend une option obligatoire. L'appel final à toJSON() convertit l'objet builder en la structure JSON brute attendue par l'API Discord.

Déployer les commandes avec REST

Définir les commandes ne suffit pas ; vous devez les enregistrer auprès de Discord. Pour cela, nous écrivons un script de déploiement séparé utilisant le client REST et les helpers Routes. Pendant le développement, utilisez Routes.applicationGuildCommands : cela enregistre sur un seul serveur instantanément. Les commandes globales (Routes.applicationCommands) apparaissent sur tous les serveurs mais leur propagation peut prendre jusqu'à une heure.

const { REST, Routes } = require('discord.js');
const { token, clientId, guildId } = require('./config.json');
const { commands } = require('./commands');

const rest = new REST({ version: '10' }).setToken(token);

(async () => {
  try {
    console.log(`Déploiement de ${commands.length} commandes...`);

    const data = await rest.put(
      Routes.applicationGuildCommands(clientId, guildId),
      { body: commands },
    );

    console.log(`${data.length} commandes enregistrées avec succès.`);
  } catch (error) {
    console.error(error);
  }
})();

Exécutez ce fichier une fois avec node deploy-commands.js. Vous devez le relancer chaque fois que vous modifiez vos commandes. La méthode rest.put remplace (écrase) l'ensemble complet des commandes existantes par la liste que vous envoyez, donc toute commande retirée de la liste est supprimée.

Configuration du Client et événement interactionCreate

Le bot lui-même réside dans un fichier séparé (index.js). Lors de la création de l'objet Client, vous devez déclarer quels événements vous souhaitez recevoir à l'aide de GatewayIntentBits. Pour les commandes slash, seul l'intent Guilds est nécessaire ; vous n'avez pas besoin de lire le contenu des messages. Nous répondons aux commandes dans l'événement interactionCreate et vérifions que l'interaction reçue est bien une commande avec interaction.isChatInputCommand() :

const { Client, GatewayIntentBits } = require('discord.js');
const { token } = require('./config.json');

const client = new Client({
  intents: [GatewayIntentBits.Guilds],
});

client.once('clientReady', () => {
  console.log(`Connecté en tant que ${client.user.tag}`);
});

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

  if (interaction.commandName === 'ping') {
    await interaction.reply(`Pong ! Latence : ${client.ws.ping}ms`);
  }

  if (interaction.commandName === 'saluer') {
    const user = interaction.options.getUser('utilisateur');
    await interaction.reply(`Bonjour ${user} ! Bienvenue.`);
  }
});

client.login(token);

Points importants à retenir ici :

  • isChatInputCommand() : ne traite que les commandes slash, pas les interactions de boutons ou de menus. Sans cette vérification, le code peut lever une erreur lors de la lecture de commandName.
  • interaction.options.getUser('utilisateur') : récupère la valeur de l'option que vous avez définie. Utilisez getString, getInteger et getBoolean pour ces types.
  • interaction.reply() : vous devez répondre à une interaction dans les 3 secondes. Pour les traitements longs, appelez d'abord interaction.deferReply(), puis envoyez le résultat avec interaction.editReply().

Pour lancer le bot, déployez d'abord les commandes, puis démarrez le client :

node deploy-commands.js
node index.js

Erreurs courantes

  • Erreur « Missing Access » : si vous n'avez pas invité le bot avec le scope applications.commands, les commandes ne s'enregistreront pas. Dans l'URL OAuth2, sélectionnez à la fois les scopes bot et applications.commands.
  • Commande qui n'apparaît pas : les commandes de guilde apparaissent instantanément, les commandes globales se propagent avec un délai. Utilisez toujours des commandes de guilde en développement.
  • « Unknown interaction » : la réponse est arrivée après 3 secondes. Utilisez deferReply().

Foire aux questions

Quelle est la différence entre une commande slash et une ancienne commande à préfixe ?

Les commandes à préfixe (!commande) nécessitent la lecture du contenu des messages et l'intent privilégié MessageContent de Discord. Les commandes slash sont intégrées à l'interface de Discord, offrent l'autocomplétion et la validation de saisie, et ne requièrent pas la permission de contenu des messages. Pour les nouveaux bots, les commandes slash sont le choix obligatoire.

Pourquoi les commandes globales n'apparaissent-elles pas immédiatement ?

Discord met en cache les commandes globales lors de leur distribution à tous les serveurs, et cette propagation peut prendre jusqu'à une heure. Pour le développement et les tests, enregistrez sur un seul serveur avec Routes.applicationGuildCommands, car les commandes de guilde s'activent instantanément.

Quelle version de Node.js discord.js v14 requiert-il ?

discord.js v14 requiert Node.js 18 ou une version plus récente. Sur des versions plus anciennes, vous obtiendrez une erreur d'incompatibilité lors de l'installation. Vérifiez votre version avec node -v.

Vous voulez faire passer votre bot au niveau supérieur ? Si vous avez besoin d'aide pour les sous-commandes, l'autocomplétion, les boutons et une architecture de bot personnalisée, contactez-moi et donnons vie à votre projet ensemble.

Devamı için