🤖 Bot Discord — Documentation technique
Cette page est destinée aux développeurs travaillant sur le package apps/discord-bot. Pour le guide utilisateur final (comment utiliser /dispos etc.), consultez Bot Discord (Guide utilisateur).
🧭 Vue d'ensemble
Le bot Discord LIPAIX est un service Node.js autonome construit avec Discord.js 14. Il tourne comme un processus séparé de l'application web. Il écoute les commandes slash dans un serveur Discord (guild) et répond avec des données récupérées depuis l'API de l'application web.
🧱 Structure du projet
apps/discord-bot/src/
├── index.ts # Point d'entrée — connexion à Discord, démarrage du serveur HTTP
├── types.ts # Types TypeScript partagés
├── commands/
│ ├── commands.ts # Registre de toutes les commandes
│ ├── disposCommand.ts # Commande /dispos
│ ├── selecsCommand.ts # Commande /selecs
│ └── ticketsCommand.ts # Commande /tickets
├── actions/
│ ├── handleInteractions.ts # Redirige les interactions vers la bonne commande
│ ├── registerCommands.ts # Déploie les commandes auprès du guild Discord
│ └── listCommands.ts # Liste les commandes actuellement enregistrées
├── billetweb/
│ ├── BilletwebEmbedsAdapter.ts # Formate les données Billetweb en embeds Discord
│ └── BilletwebAvailabilityModel.ts # Récupère les données de disponibilité depuis Billetweb
├── selections/
│ ├── SelectionsViewModel.ts # Formate les données de sélection pour Discord
│ ├── SelectionsDiscordAdapter.ts # Adapte les données de sélection en embeds Discord
│ ├── addLineupMessageReactions.ts # Ajoute des réactions emoji aux messages de distribution
│ └── fetchShowPosterAttachment.ts # Récupère l'affiche du spectacle pour la pièce jointe Discord
├── core/
│ └── injection.ts # Injection de dépendances / factory de services
└── http/
├── internalHttpServer.ts # Serveur HTTP interne pour les webhooks
├── registerInternalRoutes.ts # Enregistrement des routes internes
└── routes/
└── selectionsPublishedRoute.ts # Gère le webhook de publication de sélection💬 Les trois commandes
/dispos
Récupère les prochaines disponibilités de l'utilisateur Discord connecté depuis l'API de l'application web (/api/v1/availabilities/single-player). Les formate en embed Discord affichant les dates des spectacles et le statut déclaré de l'utilisateur.
L'utilisateur est identifié par son ID utilisateur Discord, qui est recherché dans la collection Players.
/selecs
Récupère la sélection publiée pour les prochains spectacles (/api/v1/selections/[eventId]). Affiche la distribution (rôle → nom du joueur) sous forme d'embed Discord.
/tickets
Récupère les prochains événements avec billetterie configurée depuis l'API Billetweb. Affiche les détails de l'événement et les liens de réservation directs.
⚙️ Fonctionnement du traitement des commandes
- Un utilisateur tape
/disposdans Discord - Discord envoie un événement
INTERACTION_CREATEau bot handleInteractions.tsidentifie le nom de la commande et redirige vers le bon gestionnaire- Le gestionnaire appelle l'API web, formate le résultat et appelle
interaction.reply() - Discord livre la réponse (éphémère — visible uniquement par l'utilisateur)
📝 Enregistrer les commandes
Les commandes slash doivent être déployées auprès de Discord avant que les utilisateurs puissent les voir. C'est une opération ponctuelle (à répéter quand les commandes changent) :
pnpm discord:commands:registerCela appelle l'API REST de Discord pour enregistrer toutes les commandes de commands.ts pour le guild configuré (DISCORD_GUILD_ID).
Pour lister les commandes actuellement enregistrées :
pnpm discord:commands:listPour supprimer toutes les commandes enregistrées :
pnpm discord:commands:clear🔌 Appeler l'API de l'application web
Le bot authentifie les appels API avec la variable d'environnement LIPAIX_API_TOKEN, passée dans le header Authorization. L'application web valide ce token avant de répondre.
L'URL de base de l'application web est configurée via MYLIPAIX_BASE_URL.
🌐 Serveur HTTP interne
Le bot fait également tourner un petit serveur HTTP interne (Express). Il expose un endpoint webhook que l'application web appelle lorsqu'une sélection est publiée — le bot publie alors le message de distribution sur Discord et ajoute des réactions emoji.
C'est ainsi que fonctionne le bouton "Publier sur Discord" dans MyLipaix : l'application web appelle l'endpoint interne du bot, qui gère la publication sur Discord.
🔐 Variables d'environnement
| Variable | Ce qu'elle fait |
|---|---|
DISCORD_BOT_TOKEN | Le token secret du bot (depuis le portail développeur Discord) |
DISCORD_BOT_APP_ID | L'ID de l'application du bot |
DISCORD_GUILD_ID | L'ID du serveur Discord où le bot opère |
DISCORD_MEMBERS_ROLE_ID | ID du rôle Discord pour les membres LIPAIX |
MYLIPAIX_BASE_URL | URL de l'application web (ex. : https://admin.lipaix.com) |
LIPAIX_DISCORD_ACTION | Secret partagé interne pour l'authentification des webhooks |
BILLETWEB_API_KEY | Clé API Billetweb pour la commande /tickets |
BILLETWEB_USER | Identifiant utilisateur Billetweb |
PORT | Port du serveur HTTP interne (défaut : 3002) |
➕ Ajouter une nouvelle commande
- Créez un nouveau fichier dans
src/commands/(ex. :maCommande.ts) en suivant le modèle des commandes existantes - Exportez un objet commande avec
data(définition de la commande slash) etexecute(fonction gestionnaire) - Enregistrez-le dans
src/commands/commands.ts - Lancez
pnpm discord:commands:registerpour le déployer auprès de Discord
