Écrire un écouteur d'événements discord bot event est l'étape qui transforme votre bot, d'une simple machine à commandes statiques, en une application qui réagit en temps réel. Discord transmet à votre bot tout ce qui se passe sur un serveur — l'envoi d'un message, l'arrivée d'un membre, l'ajout d'une réaction — sous forme d'événement via une connexion WebSocket persistante. Dans cet article, je détaille le fonctionnement du flux d'événements, pourquoi les gateway intents sont obligatoires, et comment construire une structure d'écouteurs solide, le tout avec discord.js.
Qu'est-ce que la gateway et comment fonctionne le flux d'événements ?
Les bots Discord communiquent en réalité par deux canaux distincts. Les actions comme envoyer un message ou créer un salon se font par des requêtes HTTP vers l'API REST. À l'inverse, écouter ce qui se passe sur un serveur s'effectue via une connexion WebSocket persistante appelée la Gateway.
Le flux se déroule ainsi : au démarrage, votre bot se connecte à la Gateway et s'authentifie avec son token (IDENTIFY). Discord attend des heartbeats réguliers pour s'assurer que la connexion reste active. Une fois la connexion établie, dès qu'un événement survient sur un serveur, Discord pousse un paquet d'événement (par exemple MESSAGE_CREATE) vers votre bot. La bibliothèque capte ce paquet brut, l'analyse et déclenche la fonction d'écoute que vous avez enregistrée.
C'est pourquoi un bot événementiel ne « pose jamais une question en attendant une réponse » ; au contraire, il reçoit les événements selon un modèle push sur une ligne ouverte en permanence. L'architecture du bot doit être pensée autour de cette réalité.
Les intents : la clé qui décide ce que vous pouvez écouter
Depuis 2020, Discord restreint les types d'événements reçus par les bots via les Gateway Intents. Un intent est un drapeau d'autorisation qui dit « je veux recevoir les événements de cette catégorie ». Si vous ne demandez pas les événements inutiles, le trafic réseau comme l'usage mémoire diminuent ; surtout, vous n'aurez pas accès à des données superflues.
Si vous ne déclarez pas explicitement les intents, les événements correspondants n'atteindront jamais votre bot. La réponse à la question si courante « pourquoi mon événement de message ne se déclenche-t-il pas ? » est généralement un intent manquant. Certains intents sont considérés comme privilégiés et doivent être activés à la fois dans le Discord Developer Portal et déclarés dans le code :
GuildMembers— arrivée/départ de membres, liste des membres (privilégié).MessageContent— accès au contenu textuel des messages (privilégié).GuildPresences— statut en ligne et activité (privilégié).
Pour les bots présents sur plus de 100 serveurs, vous devez obtenir une vérification de Discord pour les intents privilégiés. Limiter votre bot aux intents dont il a réellement besoin est donc à la fois une bonne pratique et une nécessité pour la mise à l'échelle.
Mettre en place votre premier écouteur d'événements
Un squelette de bot minimal avec discord.js v14 ressemble à ceci. On crée l'objet Client avec les intents requis, puis on attache des écouteurs aux événements :
const { Client, GatewayIntentBits, Events } = require('discord.js');
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
],
});
// Se déclenche une fois lorsque la connexion est prête
client.once(Events.ClientReady, (c) => {
console.log(`Connecté en tant que : ${c.user.tag}`);
});
// Se déclenche à chaque nouveau message
client.on(Events.MessageCreate, (message) => {
if (message.author.bot) return; // ignorer les messages des bots
if (message.content === '!ping') {
message.reply('Pong !');
}
});
client.login(process.env.DISCORD_TOKEN);
Il y a ici deux distinctions importantes. client.once exécute l'écouteur une seule fois — idéal pour les événements de cycle de vie qui ne surviennent qu'une fois, comme ClientReady. client.on, en revanche, se déclenche à chaque occurrence. La vérification message.author.bot empêche aussi les bots de se déclencher mutuellement en boucle infinie ; c'est une protection facile à oublier mais cruciale.
Les événements courants et leur bon usage
Un vrai bot ne réagit pas à un seul événement, mais à plusieurs à la fois. Les événements que vous utiliserez le plus sont :
GuildMemberAdd— pour un message de bienvenue ou un rôle automatique à l'arrivée d'un membre (nécessite l'intentGuildMembers).InteractionCreate— la voie moderne et recommandée pour les slash commands, boutons et menus.MessageReactionAdd— pour les systèmes de rôles par réaction.GuildCreate— lorsque le bot est ajouté à un nouveau serveur, pour la configuration.
Dans les bots modernes, il faut construire la logique des commandes sur InteractionCreate et les slash commands plutôt que sur MessageCreate, car MessageContent est un intent privilégié et Discord n'encourage pas, à long terme, les commandes basées sur le contenu des messages.
Garder une structure d'événements évolutive
Entasser tous les écouteurs dans un seul fichier devient ingérable à mesure que le bot grandit. Une approche solide consiste à construire un gestionnaire d'événements qui place chaque événement dans son propre fichier. Chaque fichier exporte le nom de l'événement et la fonction à exécuter :
// events/messageCreate.js
const { Events } = require('discord.js');
module.exports = {
name: Events.MessageCreate,
once: false,
execute(message) {
if (message.author.bot) return;
// ... logique
},
};
// la partie qui charge automatiquement les écouteurs
const fs = require('node:fs');
const path = require('node:path');
const eventsPath = path.join(__dirname, 'events');
const files = fs.readdirSync(eventsPath).filter((f) => f.endsWith('.js'));
for (const file of files) {
const event = require(path.join(eventsPath, file));
if (event.once) {
client.once(event.name, (...args) => event.execute(...args));
} else {
client.on(event.name, (...args) => event.execute(...args));
}
}
Grâce à cette structure, ajouter un nouvel événement revient simplement à déposer un fichier dans le dossier events/. Le code reste lisible, la responsabilité de chaque événement est isolée, et le débogage devient bien plus simple.
Erreurs courantes
Les pièges les plus fréquents avec les écouteurs d'événements sont : (1) Intents manquants — la raison numéro un pour qu'un événement ne se déclenche pas. (2) Choisir uniquement les événements réellement nécessaires au lieu d'en écouter trop. (3) Ne pas capturer les erreurs lors de l'await de requêtes réseau dans un écouteur ; une seule erreur non gérée peut faire planter le bot. Envelopper les écouteurs dans un try/catch et exécuter le bot sous un gestionnaire de processus (comme PM2) améliore nettement la stabilité en production.
Questions fréquentes
Ajouter l'intent dans le code suffit-il à lui seul ?
Pour les intents privilégiés, non. Vous devez déclarer MessageContent, GuildMembers et GuildPresences dans le code et les activer dans les paramètres du bot sur le Discord Developer Portal. S'il en manque un, les événements n'arriveront pas.
Quelle est la différence entre client.on et client.once ?
client.on exécute l'écouteur à chaque récurrence de l'événement ; client.once ne l'exécute qu'à la première fois puis supprime automatiquement l'écouteur. Pour un événement unique comme ClientReady, once est le bon choix.
Le contenu des messages arrive vide — pourquoi ?
Très probablement, l'intent MessageContent manque. Sans cet intent privilégié, message.content arrive vide ; le contenu n'est rempli que pour les messages où le bot est mentionné ou qui sont des messages privés.
Vous voulez une architecture d'événements solide pour votre bot ? Des gateway intents à une structure de gestionnaire évolutive, je développe des bots Discord de bout en bout. Pour discuter de votre projet, contactez-moi.