Un bot de vérification Discord est une petite mais essentielle couche de sécurité qui empêche chaque nouveau membre d'accéder à vos salons tant qu'il n'a pas prouvé qu'il est une vraie personne. Ceux qui franchissent la porte d'un simple clic ou avec un court code captcha sont admis ; les comptes bots, les scripts de raid et les vagues de spam restent dehors. Dans ce guide, nous allons construire un système de vérification de zéro avec discord.js, en commençant par un bouton puis en le renforçant avec un captcha. Vous mettrez en place le modèle de rôles et de permissions, l'attribution automatique de rôle et les bonnes pratiques de sécurité qui tiennent vraiment la route, étape par étape.
Pourquoi un système de vérification est nécessaire
Un serveur ouvert est un endroit où quiconque obtient le lien d'invitation peut entrer directement et commencer à écrire. Cela invite deux types d'attaques :
- Vagues de bots/self-bots : des comptes automatisés acceptent des centaines d'invitations en quelques minutes et déversent publicités et liens malveillants.
- Raids : des groupes coordonnés rejoignent en même temps, inondent les salons, harcèlent les membres et rendent le serveur inutilisable.
La vérification place cette friction exactement là où il faut : quelques secondes pour un humain, mais un obstacle fastidieux pour l'automatisation. Ajouter un captcha vous offre un niveau de protection supplémentaire contre les bots avancés qui imitent les simples flux « clique sur le bouton ».
Mettre en place le modèle de permissions et de rôles
Avant d'écrire le moindre code, la structure du serveur doit être correcte. La logique est simple : un membre non vérifié ne doit rien voir, et l'accès doit s'ouvrir une fois la vérification faite. Il existe deux schémas courants :
- Ouvrir avec un rôle Vérifié : masquez tous les salons au rôle
@everyonepour ne laisser visible qu'un seul salon#verification. Créez un rôle « Vérifié » et accordez-lui Voir le salon sur les vrais salons. Quand un membre se vérifie, le bot ajoute ce rôle et le serveur s'ouvre. - Restreindre avec un rôle Non vérifié : attribuez automatiquement un rôle « Non vérifié » à tous ceux qui rejoignent, refusez-lui l'accès partout, et retirez le rôle lors de la vérification.
La première méthode est généralement plus propre car l'état par défaut est « fermé », ce qui réduit le risque qu'un salon reste accidentellement ouvert. Quel que soit votre choix, retenez deux règles : le bot doit avoir la permission Gérer les rôles, et le rôle du bot doit se trouver au-dessus du rôle qu'il attribue. Sinon, Discord refuse d'ajouter le rôle.
Agir automatiquement à l'arrivée d'un membre
Pour capter les nouveaux membres, on écoute l'événement GuildMemberAdd. Pour que cet événement se déclenche, vous devez activer le Server Members Intent du bot, à la fois dans le portail développeur et dans les options du client.
const { Client, GatewayIntentBits, Events } = require('discord.js');
const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers],
});
client.on(Events.GuildMemberAdd, async (member) => {
// Si vous utilisez le schéma Non vérifié, attribuez le rôle à l'arrivée :
await member.roles.add(process.env.UNVERIFIED_ROLE_ID);
});
client.login(process.env.TOKEN);
Avec le schéma Vérifié, cette étape est inutile ; le membre ne voit déjà rien par défaut, à part le salon de vérification.
Bot de vérification Discord : vérifier avec un bouton
La méthode la plus simple et la plus rapide est la vérification par bouton. D'abord, vous envoyez un message de panneau permanent dans le salon de vérification :
const { ButtonBuilder, ButtonStyle, ActionRowBuilder } = require('discord.js');
const row = new ActionRowBuilder().addComponents(
new ButtonBuilder()
.setCustomId('verify')
.setLabel('Vérifier mon compte')
.setEmoji('✅')
.setStyle(ButtonStyle.Success),
);
await channel.send({
content: 'Cliquez sur le bouton ci-dessous pour accéder au serveur.',
components: [row],
});
Le champ customId est ici crucial : c'est l'identifiant unique qui vous permet de reconnaître le clic. Écoutons maintenant les clics sur ce bouton. On envoie les réponses en privé avec flags: MessageFlags.Ephemeral pour que le salon ne se remplisse pas de messages « vous êtes vérifié » :
const { Events, MessageFlags } = require('discord.js');
client.on(Events.InteractionCreate, async (interaction) => {
if (!interaction.isButton() || interaction.customId !== 'verify') return;
const role = interaction.guild.roles.cache.get(process.env.VERIFIED_ROLE_ID);
if (interaction.member.roles.cache.has(role.id)) {
return interaction.reply({
content: 'Vous êtes déjà vérifié.',
flags: MessageFlags.Ephemeral,
});
}
await interaction.member.roles.add(role);
await interaction.reply({
content: 'Vérifié — bienvenue parmi nous !',
flags: MessageFlags.Ephemeral,
});
});
Cela suffit à la plupart des petites communautés. Mais si vous voulez aller plus loin contre les bots qui cliquent le bouton par programmation, c'est là que le captcha entre en jeu.
Vérification avancée avec un captcha
Dans le flux captcha, lorsqu'un membre clique sur le bouton, on lui montre un code aléatoire et on lui demande de le saisir dans un formulaire modal. Une simple Map suffit pour conserver le code en mémoire (sur les grands serveurs, Redis est préférable). D'abord, ouvrez le modal au clic du bouton :
const {
Events,
ModalBuilder,
TextInputBuilder,
TextInputStyle,
ActionRowBuilder,
} = require('discord.js');
const pending = new Map();
client.on(Events.InteractionCreate, async (interaction) => {
if (!interaction.isButton() || interaction.customId !== 'verify') return;
const code = Math.random().toString(36).slice(2, 8).toUpperCase();
pending.set(interaction.user.id, code);
const input = new TextInputBuilder()
.setCustomId('captcha_input')
.setLabel(`Saisissez ce code à l'identique : ${code}`)
.setStyle(TextInputStyle.Short)
.setRequired(true);
const modal = new ModalBuilder()
.setCustomId('captcha_modal')
.setTitle('Vérification')
.addComponents(new ActionRowBuilder().addComponents(input));
await interaction.showModal(modal);
});
Quand le membre soumet le formulaire, une interaction ModalSubmit arrive. On compare la valeur saisie au code attendu et on attribue le rôle si elles correspondent :
client.on(Events.InteractionCreate, async (interaction) => {
if (!interaction.isModalSubmit() || interaction.customId !== 'captcha_modal') return;
const expected = pending.get(interaction.user.id);
const given = interaction.fields
.getTextInputValue('captcha_input')
.trim()
.toUpperCase();
if (!expected || given !== expected) {
return interaction.reply({
content: 'Code incorrect. Veuillez recliquer sur le bouton.',
flags: MessageFlags.Ephemeral,
});
}
pending.delete(interaction.user.id);
const role = interaction.guild.roles.cache.get(process.env.VERIFIED_ROLE_ID);
await interaction.member.roles.add(role);
await interaction.reply({
content: 'Vérifié — bienvenue ! 🎉',
flags: MessageFlags.Ephemeral,
});
});
Si vous voulez intégrer le code dans une image plutôt qu'en texte brut, vous pouvez générer un visuel avec une bibliothèque comme canvas et l'envoyer en MP ou par un message éphémère au lieu du modal ; la logique reste la même, vous rendez simplement le code plus difficile à lire pour les machines.
Conseils de sécurité et bonnes pratiques
- Ajoutez un délai d'expiration : effacez les entrées de
pendingaprès quelques minutes avecsetTimeoutpour que les codes périmés ne s'accumulent pas en mémoire. - Appliquez une limite de débit : empêchez un même utilisateur de multiplier les tentatives rapidement ; expulsez automatiquement ceux qui échouent sans cesse.
- Gardez des journaux : écrivez les vérifications réussies et échouées dans un salon de logs via webhook ; voir qui est passé pendant un raid est inestimable.
- Filtre d'ancienneté du compte : expulsez automatiquement les comptes très récents (par ex. de moins de 7 jours) avant la vérification pour arrêter les vagues de bots dès la porte.
- Protégez le token : ne codez jamais le token du bot en dur ; utilisez
process.envavec un fichier.envet ajoutez-le à.gitignore.
Questions fréquentes
Quelles permissions un bot de vérification nécessite-t-il ?
Le bot a besoin au minimum de la permission Gérer les rôles, et son rôle doit se trouver au-dessus du rôle « Vérifié » qu'il attribue. Pour capter les arrivées de membres, le Server Members Intent doit aussi être activé.
Captcha ou bouton — lequel est préférable ?
Pour les petits serveurs calmes, un bouton à un clic suffit généralement. Sur les grands serveurs ou ceux souvent raidés, un captcha offre une protection supplémentaire nette en filtrant les bots qui cliquent automatiquement le panneau. Combiner les deux est la solution la plus robuste.
Dois-je stocker le code dans une base de données plutôt qu'une Map ?
Pour les petits bots à processus unique, une Map est rapide et suffisante. Les codes en attente sont effacés au redémarrage du bot, ce qui n'est pas un problème. Si vous utilisez le sharding ou avez besoin de persistance, choisissez un stockage partagé comme Redis.
Besoin d'un système de vérification fiable pour votre serveur ? Je peux concevoir et développer un bot Discord sur mesure pour votre communauté, avec bouton, captcha, anti-raid et journalisation. Contactez-moi et parlons de votre projet.