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

Créer un bot musique Discord avec discord.js et Lavalink

Écrire un bot musique Discord paraît simple au premier abord — « rejoins un salon, joue un morceau » — mais cela devient sérieux dès qu'on ajoute une gestion de file d'attente solide, un flux audio sans coupure et une architecture capable de tourner sur de nombreux serveurs à la fois. Dans ce guide, nous construisons un bot moderne en deux couches : discord.js pour la logique du bot, et un serveur audio distinct, Lavalink, pour le décodage et le streaming. Nous évoquons aussi brièvement l'approche directe avec @discordjs/voice pour les petits bots.

Pourquoi Lavalink ? La différence avec @discordjs/voice

@discordjs/voice est la bibliothèque officielle qui permet à votre bot de rejoindre un salon vocal et d'envoyer un flux PCM/Opus brut. Seule, elle suffit pour jouer de la musique : vous récupérez une source de flux (par exemple ytdl-core ou play-dl), la transformez en ressource avec createAudioResource et la lisez via un AudioPlayer. Le problème de cette approche, c'est la montée en charge : le décodage et le transcodage de l'audio sollicitent fortement le même processus Node qui fait tourner votre bot.

Lavalink est un nœud audio autonome, écrit en Java, qui prend en charge ce travail lourd. Votre bot dit à Lavalink « joue ce morceau dans ce salon » via un WebSocket, et Lavalink s'occupe de tout le décodage et du streaming. Les avantages :

  • La charge CPU est déportée du bot ; un seul nœud peut servir des centaines de serveurs.
  • Prise en charge native, via des plugins, de YouTube, SoundCloud, Bandcamp, Twitch et des sources HTTP.
  • Continuité de session et reconnexion robuste même si le bot redémarre.

Pour un petit bot loisir mono-serveur, @discordjs/voice est largement suffisant. Si vous prévoyez de jouer en continu sur de nombreux serveurs, Lavalink devient quasi indispensable.

Mettre en place le projet et enregistrer le bot

Initialisez d'abord un projet Node.js (Node 18+ recommandé) et installez les paquets nécessaires :

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

Ici, shoukaku est une bibliothèque cliente mature qui fait le lien entre discord.js et Lavalink (alternatives : lavalink-client, activement maintenu à la place d'erela.js). Créez une application sur le Discord Developer Portal, récupérez un token de bot et placez-le dans un fichier .env. Lors de l'invitation du bot, accordez les portées bot et applications.commands ainsi que les permissions vocales Connect et Speak.

Lancer le nœud Lavalink

Lavalink est distribué sous forme de JAR exécutable et requiert Java 17+. Téléchargez la version officielle et placez un fichier application.yml à côté :

server:
  port: 2333
lavalink:
  server:
    password: "un-mot-de-passe-fort"

Démarrez-le ensuite avec java -jar Lavalink.jar. Sur les versions actuelles, il peut être nécessaire de configurer un plugin distinct (comme youtube-source) pour la source YouTube ; vérifiez les logs de démarrage pour voir quelles sources se sont chargées. En production, rendez ce processus persistant avec systemd ou Docker.

Connecter le bot à Lavalink

Avec Shoukaku, la connexion au nœud et un client de base se mettent en place ainsi :

const { Client, GatewayIntentBits } = require('discord.js');
const { Shoukaku, Connectors } = require('shoukaku');
require('dotenv').config();

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

const nodes = [{
  name: 'main',
  url: 'localhost:2333',
  auth: process.env.LAVALINK_PASSWORD,
}];

const shoukaku = new Shoukaku(new Connectors.DiscordJS(client), nodes);
shoukaku.on('error', (_, err) => console.error(err));

client.login(process.env.DISCORD_TOKEN);

Attention : l'intent GuildVoiceStates est indispensable pour suivre les états vocaux. Sans lui, le bot ne peut pas savoir dans quel salon se trouve un utilisateur.

Construire la file de lecture

La véritable expérience musicale est définie par la « file d'attente » : mettre en file les demandes simultanées, passer automatiquement au morceau suivant et quitter quand le salon se vide. Gardez une file distincte par serveur. Un flux play simple :

async function play(interaction, query) {
  const node = shoukaku.options.nodeResolver(shoukaku.nodes);
  const result = await node.rest.resolve(`ytsearch:${query}`);
  if (!result || !result.data.length) {
    return interaction.reply('Aucun résultat trouvé.');
  }
  const track = result.data[0];

  const player = await shoukaku.joinVoiceChannel({
    guildId: interaction.guildId,
    channelId: interaction.member.voice.channelId,
    shardId: 0,
  });

  player.playTrack({ track: { encoded: track.encoded } });
  return interaction.reply(`Lecture : **${track.info.title}**`);
}

Dans un vrai bot, vous enveloppez cela dans une classe de file : sur l'événement player.on('end', ...), vous tirez le morceau suivant du tableau et le jouez, et quand le tableau est vide, vous quittez avec shoukaku.leaveVoiceChannel après un délai de grâce. Conserver la file en mémoire sous forme de Map<guildId, Queue> suffit à la plupart des bots.

Ajouter les commandes slash

Les bots Discord modernes utilisent des commandes slash au lieu de déclencheurs textuels. Enregistrez les commandes une fois via REST et traitez-les dans l'événement interactionCreate :

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

const commands = [
  new SlashCommandBuilder()
    .setName('play')
    .setDescription('Jouer un morceau')
    .addStringOption(o =>
      o.setName('query').setDescription('Nom du morceau ou URL').setRequired(true)),
].map(c => c.toJSON());

const rest = new REST().setToken(process.env.DISCORD_TOKEN);
await rest.put(
  Routes.applicationCommands(process.env.CLIENT_ID),
  { body: commands },
);

Ajoutez skip, queue, pause, stop et volume de la même façon. Toutes les commandes autres que play lisent et mettent à jour l'état de la file ; centraliser votre gestionnaire de file dans un seul module rend donc le code bien plus facile à maintenir.

Erreurs courantes

  • Le bot rejoint le salon mais il n'y a pas de son : le nœud Lavalink n'arrive généralement pas à résoudre la source. Vérifiez les logs du nœud et le chargement du plugin de source.
  • « Used disallowed intents » : vous avez oublié d'activer les intents concernés dans le developer portal.
  • Bot invité mais les commandes n'apparaissent pas : les commandes globales mettent du temps à se propager ; en développement, l'enregistrement sur un serveur précis est instantané.

Questions fréquentes

Lavalink est-il obligatoire, ou discord.js seul suffit-il ?

Pour un seul serveur avec une lecture occasionnelle, @discordjs/voice plus une source comme play-dl suffit. Si vous jouez en continu sur de nombreux serveurs, Lavalink offre une expérience bien plus stable car il déporte la charge CPU hors du bot.

Y a-t-il quelque chose à surveiller côté droits d'auteur ?

Les sources audio et les conditions d'utilisation des plateformes évoluent avec le temps. Pour un projet commercial ou à grande échelle, assurez-vous que le contenu joué respecte les conditions de la plateforme concernée et privilégiez les API sous licence quand c'est possible.

Où héberger le bot ?

Pour une faible latence, faites tourner le bot et le nœud Lavalink sur un VPS de la même région. Les plateformes gratuites qui « se mettent en veille » ne conviennent pas aux bots musique ; il faut un serveur qui tourne en continu.

Vous voulez votre propre bot musique ? Pour un bot sur mesure construit de bout en bout avec gestion de file, commandes slash et infrastructure Lavalink, contactez-moi.

Devamı için