Un bot IA Discord est un bot capable de répondre aux messages de votre serveur avec des réponses fluides propulsées par l'intelligence artificielle. Dans ce guide, nous allons construire un bot entièrement fonctionnel qui capte les messages entrants avec discord.js, les envoie à l'API Claude d'Anthropic et publie la réponse dans le salon. Contrairement aux bots classiques pilotés par commandes, l'objectif ici est un assistant qui converse en langage naturel et se souvient du contexte.
Ce dont vous avez besoin pour un bot IA Discord
Avant de commencer, préparez quelques éléments essentiels :
- Node.js 18+ — discord.js v14 et le SDK officiel d'Anthropic exigent une version récente de Node.
- Une application Discord et un token de bot — créez une application dans le
Discord Developer Portal, transformez-la en bot et copiez le token. - Une clé API Anthropic — obtenue sur
console.anthropic.comet stockée dans un fichier.env. - Le Message Content Intent — vous devez activer cet intent privilégié dans le Developer Portal pour que le bot puisse lire le contenu des messages.
Ne codez jamais le token ni la clé API en dur dans votre source ; gardez les deux comme variables d'environnement. Si la clé fuit, la facture d'abus retombe sur vous.
Mise en place du projet et des dépendances
Initialisez le projet dans un dossier vide et installez les paquets nécessaires :
mkdir discord-ai-bot && cd discord-ai-bot
npm init -y
npm install discord.js @anthropic-ai/sdk dotenv
Ajoutez "type": "module" à votre package.json pour utiliser la syntaxe des modules ES (import). Créez ensuite un fichier .env à la racine :
DISCORD_TOKEN=votre_token_de_bot_discord
ANTHROPIC_API_KEY=votre_cle_anthropic
Le SDK lit automatiquement la variable d'environnement ANTHROPIC_API_KEY, vous n'avez donc pas besoin de passer la clé à la main lors de la création du client.
Dialoguer avec l'API Claude : le code de base
Le vrai travail se déroule dans l'API Messages de Claude : vous choisissez un modèle et fournissez un tableau messages (rôle et contenu), et vous recevez un message composé de blocs de contenu. Le index.js ci-dessous interroge Claude dès que le bot est mentionné et réécrit la réponse :
import 'dotenv/config';
import { Client, GatewayIntentBits, Events } from 'discord.js';
import Anthropic from '@anthropic-ai/sdk';
const anthropic = new Anthropic(); // la clé est lue depuis l'environnement
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
],
});
const SYSTEM_PROMPT =
'Tu es un assistant communautaire Discord serviable. Réponds de manière courte et claire.';
client.once(Events.ClientReady, (c) => {
console.log(`Connecté en tant que ${c.user.tag}`);
});
client.on(Events.MessageCreate, async (message) => {
if (message.author.bot) return;
if (!message.mentions.has(client.user)) return;
const prompt = message.content.replace(/<@!?\d+>/g, '').trim();
if (!prompt) return;
await message.channel.sendTyping();
const response = await anthropic.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 1024,
system: SYSTEM_PROMPT,
messages: [{ role: 'user', content: prompt }],
});
const reply = response.content
.filter((block) => block.type === 'text')
.map((block) => block.text)
.join('');
await message.reply(reply.slice(0, 2000));
});
client.login(process.env.DISCORD_TOKEN);
Quelques détails à noter : la réponse de Claude se trouve dans response.content sous forme de tableau de blocs ; pour obtenir le texte, on filtre les blocs de type text et on les concatène. On tronque la réponse car la limite d'un message Discord est de 2000 caractères. Le champ system est l'invite système qui définit la personnalité et la langue du bot.
Mémoire de conversation et gestion du contexte
Le bot ci-dessus traite chaque message à zéro ; il ne se souvient pas de la conversation précédente. Pour un vrai chat, vous stockez les messages récents par salon et renvoyez l'historique à chaque requête. L'API Claude est sans état (stateless) : c'est vous qui transportez le contexte.
const history = new Map();
// dans MessageCreate :
const channelId = message.channelId;
const messages = history.get(channelId) ?? [];
messages.push({ role: 'user', content: prompt });
const response = await anthropic.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 1024,
system: SYSTEM_PROMPT,
messages,
});
const reply = response.content
.filter((block) => block.type === 'text')
.map((block) => block.text)
.join('');
messages.push({ role: 'assistant', content: reply });
// Limiter le contexte aux 10 derniers messages (contrôle des tokens et du coût)
history.set(channelId, messages.slice(-10));
Une règle importante ici : les messages alternent entre les rôles user et assistant, et le premier message doit toujours être user. Si vous laissez l'historique grandir sans limite, le coût en tokens augmente et vous remplissez la fenêtre de contexte ; rogner aux N derniers messages est donc une bonne pratique. Pour une persistance à long terme, stockez ce tableau dans une base de données (SQLite, par exemple).
Conseils de coût, de vitesse et de sécurité
- Gestion des erreurs : entourez l'appel à l'API d'un
try/catch; en cas d'erreur réseau ou de limite de débit (rate limit), renvoyez un message poli à l'utilisateur et journalisez l'erreur. - Cooldown : ajoutez un simple délai d'attente par utilisateur pour bloquer à la fois le spam et le coût d'API inutile.
- Choix du modèle : pour des charges volumineuses et sensibles à la vitesse, la famille Sonnet est un choix équilibré ; envisagez Opus pour les tâches plus complexes et Haiku pour des réponses simples et rapides.
- max_tokens : fixez une borne supérieure raisonnable pour garder des réponses courtes — une réponse longue est à la fois coûteuse et peut dépasser la limite de Discord.
- Invite système : définissez clairement le rôle, les limites et le ton du bot dans le champ
system; c'est le moyen le plus efficace d'orienter le comportement du modèle.
Assemblez ces éléments et vous obtenez un assistant solide qui parle en langage naturel, se souvient du contexte et garde le coût maîtrisé.
Questions fréquentes
Mon bot ne peut pas lire les messages — pourquoi ?
Le Message Content Intent est très probablement désactivé. Activez cet intent privilégié dans les paramètres du bot dans le Developer Portal et assurez-vous d'avoir ajouté l'intent GatewayIntentBits.MessageContent dans votre code.
Quel modèle Claude utiliser ?
Pour les bots de chat, un modèle récent comme claude-sonnet-4-6 offre un bon équilibre entre vitesse et qualité. Vous pouvez passer à un modèle plus puissant ou plus rapide selon le besoin ; il suffit de changer l'identifiant de modèle dans le champ model de la requête.
Comment garder ma clé API en sécurité ?
Gardez la clé dans un fichier .env, ajoutez-le à .gitignore et ne la poussez jamais sur votre dépôt. Si la clé fuit par accident, révoquez-la immédiatement depuis la console et créez-en une nouvelle.
Vous voulez un bot propulsé par l'IA pour votre communauté Discord ? Qu'il s'agisse d'une construction de zéro ou d'ajouter Claude à votre bot existant, planifions-le ensemble. Contactez-moi et donnons vie à votre projet.