Skip to content

🤖 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

  1. Un utilisateur tape /dispos dans Discord
  2. Discord envoie un événement INTERACTION_CREATE au bot
  3. handleInteractions.ts identifie le nom de la commande et redirige vers le bon gestionnaire
  4. Le gestionnaire appelle l'API web, formate le résultat et appelle interaction.reply()
  5. 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) :

bash
pnpm discord:commands:register

Cela 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 :

bash
pnpm discord:commands:list

Pour supprimer toutes les commandes enregistrées :

bash
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

VariableCe qu'elle fait
DISCORD_BOT_TOKENLe token secret du bot (depuis le portail développeur Discord)
DISCORD_BOT_APP_IDL'ID de l'application du bot
DISCORD_GUILD_IDL'ID du serveur Discord où le bot opère
DISCORD_MEMBERS_ROLE_IDID du rôle Discord pour les membres LIPAIX
MYLIPAIX_BASE_URLURL de l'application web (ex. : https://admin.lipaix.com)
LIPAIX_DISCORD_ACTIONSecret partagé interne pour l'authentification des webhooks
BILLETWEB_API_KEYClé API Billetweb pour la commande /tickets
BILLETWEB_USERIdentifiant utilisateur Billetweb
PORTPort du serveur HTTP interne (défaut : 3002)

➕ Ajouter une nouvelle commande

  1. Créez un nouveau fichier dans src/commands/ (ex. : maCommande.ts) en suivant le modèle des commandes existantes
  2. Exportez un objet commande avec data (définition de la commande slash) et execute (fonction gestionnaire)
  3. Enregistrez-le dans src/commands/commands.ts
  4. Lancez pnpm discord:commands:register pour le déployer auprès de Discord

Publié sous licence MIT.