Changelogs
Historique des évolutions LB'XMB.FR (site, bot Discord, forum, boutique, intégrations). Cette page est synchronisée avec le document interne de récapitulatif.
- Vers 06:32 UTC (08:32 locale), un grand nombre de fichiers sources du projet ont été supprimés du disque : bot-public/src/, bot-site/src/, .env/package.json/ecosystem.config.cjs des deux bots, plusieurs fichiers web (web/src/app/layout.tsx, web/src/app/globals.css, web/next.config.ts, ~30 dossiers vidés sous web/src/app), ainsi que ce journal.
- node_modules/, package-lock.json, les builds .next/.next-staging et data/ ont survécu → la prod et les bots tournaient encore depuis la mémoire, mais un redémarrage les aurait fait planter.
- Cause non identifiée (pas un dépôt git, aucun cron suspect). Coïncide avec le début d'une session agent.
- Recréation intégrale de bot-public et bot-site à partir de l'historique de conversation.
- Le web n'a PAS été modifié (contenu des fichiers supprimés non disponible côté agent).
- Bots opérationnels à nouveau ; web à restaurer séparément depuis une sauvegarde.
- bot-public/, bot-site/ (recréés), docs/RECAP-TRAVAIL-COMMUNAUTE-2026-04.md (recréé).
- Message bienvenue/départ configuré en « embed » mais envoyé en message simple : la carte image court-circuitait l'embed.
- Couleur d'accent de la carte non configurable ; pas de titre/sous-titre personnalisables ; import d'image impossible sans URL.
- Blockquote > à fiabiliser dans l'embed /config.
- Demande d'un POC Components V2 (Container).
- welcomeSender.buildEntryPayload : la carte est désormais intégrée dans l'embed (embed.setImage(attachment://carte.png)) quand type=embed + carte activée ; sinon image en pièce jointe (type simple) ; sinon embed/texte normal.
- messagePayload.js : ajout de buildEmbed() + parseColor() réutilisables.
- Carte (welcomeCard.renderWelcomeCard) : accent, titre et sous-titre paramétrables (placeholders appliqués, dont {server}, {count.member}), fond via URL ou fichier local importé.
- /config : nouveau sous-panneau Carte (activer/désactiver, éditer texte & couleur, importer une image en pièce jointe via collector 60 s, stockage local dans data/cards/<guild>/<id>.<ext>).
- L'utilisateur souhaite remplacer les menus déroulants de /config2 par des lignes Section Components V2 : texte à gauche, bouton d'action à droite (style DraftBot).
- panelsV2.js : refonte avec SectionBuilder + TextDisplayBuilder + setButtonAccessory pour la liste des fonctions (arrivée, départ, MP, réguliers), la liste des configurations, le détail entrée/carte et la suppression.
- /config2 ouvre directement le panneau Messages automatique (4 sections avec bouton « Configurer »).
- routerV2.js : retrait des handlers StringSelectMenu ; suppression directe via cfg2:remove:one:<section>:<id> ; seul menu conservé = sélection de salon à l'ajout (ChannelSelect).
- Redémarrage bot-public.
- UI /config2 alignée sur le modèle texte/bouton horizontal ; plus de menus déroulants pour naviguer entre les options.
- bot-public/src/handlers/config/panelsV2.js, routerV2.js
- bot-public/src/commands/owner/config2.js
- L'utilisateur souhaite remplacer les modales de configuration des messages (bienvenue, etc.) par une interface Container V2 propre : boutons par paramètre (titre, description, couleur, carte…).
- Nouvel éditeur unifié (buildEditorContainerPayload) : sections texte à gauche / bouton à droite pour chaque paramètre (état, format embed/simple, titre, description, couleur embed, carte on/off, titre/sous-titre/accent/fond carte, salon, intervalle périodique).
- Plus de modale sur /config2 : textes modifiés en envoyant un message dans le salon (collector 60 s) ; couleurs via palette de boutons + option hex custom ; toggles instantanés.
- Ajout d'une config : création avec valeurs par défaut puis ouverture directe de l'éditeur (salon via ChannelSelect conservé uniquement pour ça).
- Fichiers : fieldEditV2.js, editFlowV2.js, refonte panelsV2.js + routerV2.js.
- Configuration des messages entièrement dans les Containers V2, navigation cohérente, visuel type « panneau de réglages ».
- bot-public/src/handlers/config/{fieldEditV2,editFlowV2,panelsV2,routerV2}.js
- Fusionner /config et /config2 (Containers V2 uniquement sur /config).
- Erreur « ❌ Une erreur est survenue » à l'ouverture de l'éditeur / à l'ajout : limite Discord 40 composants dépassée (éditeur monolithique ~48).
- Renommer « Gérer » → « Modifier » ; bouton Retour toujours seul sur sa ligne.
- /config utilise désormais Components V2 (auto panel) ; commande /config2 supprimée.
- Préfixe interactions unifié cfg: ; router V1 embed supprimé, router unique dans router.js.
- Éditeur scindé en hub + sous-pages (Message / Carte / Régulier) pour rester sous la limite de 40 composants.
- Helper addBackRow() : Retour/Annuler jamais mélangé aux autres boutons.
- Déploiement slash commands (1 commande) ; redémarrage PM2.
- /config fonctionnel sans erreur ; navigation par sous-panneaux ; UX cohérente.
- bot-public/src/commands/owner/config.js (suppression config2.js)
- /config ouvrait directement « Messages automatique » au lieu de l'accueil fonctionnalités.
- Titre/description : demande de modales (titre vide autorisé) au lieu du chat.
- Nouvelle fonctionnalité Rôles automatiques : permanents (restauration au retour), temporaires (durée), par action (badge, âge compte, connexion), sélecteurs (boutons/menu).
- /config → buildHomeContainerPayload (Messages + Rôles automatiques).
- Modales textFieldModals.js pour titre (optionnel) et description ; router modal submit.
- Schéma auto_roles dans config serveur ; roleConfig, roleRestoreStore, tempRoleStore.
- Moteur autoRoleEngine (join/leave), tempRoleScheduler, conditions, roleSelector (publish + toggle).
- UI panelsRoles.js + routerRoles.js ; accueil rôles → 4 sections configurables.
- Connexions OAuth : lecture data/connections/<userId>.json (sync bot-site).
- Configuration unifiée ; rôles auto à l'arrivée ; panels réaction/boutons/menu publiables.
1. Choix du salon du sélecteur de rôles sans effet (routing ChannelSelect intercepté par le router messages).
2. Impossible de sélectionner plusieurs rôles d'un coup (permanent, temporaire, sélecteur).
3. Conditions « rôle par action » via modale — demande de menus déroulants.
4. Boutons « Configurer » pas tous bleus ; accueil /config avec liste dupliquée.
- router.js : délégation cfg:roles:selchanset:* vers handleRolesInteraction.
- panelsRoles.js : RoleSelectMenu intégré à l'éditeur (maxValues: 25) ; fusion des IDs sélectionnés.
- Panneaux conditions (buildConditionsPanelPayload / buildConditionValuePanelPayload) avec StringSelectMenu ; presets dans conditions.js.
- Options sélecteur : choix du rôle via RoleSelectMenu (plus de modale option).
- Accueil /config simplifié (« Système automatique » + sections + Configurer bleu) ; tous les Configurer en Primary.
1. Rôles par action : manque condition sur texte du statut personnalisé.
2. Âge du compte : rôles pour comptes au-delà de X jours, sans presets (saisie libre).
3. Sélecteur publié : description du container configurable ; boutons/menu dans le container V2.
4. Menu déroulant sélecteur : pouvoir retirer un rôle (décocher).
5. UI /config : séparateur avant les boutons Ajouter / Retour en bas de page.
- Condition custom_status + intent GuildPresences + event presenceUpdate pour réattribuer à la volée.
- Jours (account_age_days_min/max) via modale (nombre libre) ; libellé « créé il y a plus de X jours ».
- publishRoleSelector : message Components V2 (ContainerBuilder) avec titre/description/couleur ; édition si message_id existant.
- StringSelectMenu publié : minValues(0), sync add/remove selon sélection.
- Helpers addFooterActions dans panelsRoles.js et panelsV2.js (séparateur avant footer).
- Nouvelles sections /config : pseudos automatiques, administrateur (commandes/permissions), profil du bot.
- /translate + menu contextuel « Translate this message » via LibreTranslate local (User Install).
- Recréation des commandes modération de base.
- Schéma auto_nicks, admin, bot_profile dans serverConfig.js ; placeholder {web-user}.
- Moteur pseudos (permanent, temporaire, sélecteur V2) + verrouillage manuel (soi / autres).
- Hub /config : séparateur Administrateur + profil bot (apply avatar/bio/nickname).
- Admin : liste commandes activables, permissions (squelette), custom commands (squelette).
- lib/libretranslate.js (port TS) ; /translate + context menu ; /transcript, /pickup User Install.
- 18 commandes modération : ban, kick, mute, warn, lock, clear, backup, etc.
- 23 commandes déployées ; PM2 redémarré.
- Configuration pseudos RP (maisons, formats {display.name}) ; gestion commandes serveur ; modération opérationnelle ; traduction DM/serveurs sans bot.
1. Traduction : crash interaction.member null sur menu contextuel → message générique.
2. Container /config trop long — demande de pages + menu déroulant en bas.
3. /base64 incomplet vs bot Python (chiffrer/déchiffrer + bouton Déchiffrer).
4. Profil bot : import image avatar/bannière (pas d’URL).
- guard.js : commandes publiques (translate, base64…), guildId safe, fetch member si absent.
- /config scindé : Système automatique / Administration + StringSelectMenu navigation.
- /base64 : choix encode/decode → modales ; réponse avec bouton 🔓 Déchiffrer (b64:decrypt).
- Profil bot : boutons Importer (pièce jointe 60s) → data/bot-assets/<guild>/.
- Traduction contextuelle fonctionnelle ; UI config compacte ; base64 identique au bot Python ; avatar/bannière par upload.
- bot-public/src/lib/moderation/guard.js
1. Bouton « Basculer » commandes → échec d'interaction (trop de composants V2).
2. Demande menu multi-sélection visibilité + permissions rôles/utilisateurs par serveur (visibilité Discord).
3. Import avatar/bannière profil bot sans effet (filtre pièce jointe trop strict).
4. Traduction découpée en plusieurs messages + drapeau dans le titre — format rejeté.
- Commandes : StringSelectMenu multi-sélection (cfg:admin:cmdvis) — cocher les commandes à conserver ; sync guild.commands.set() par serveur via lib/commandSync.js.
- Permissions : choix commande → RoleSelectMenu + UserSelectMenu ; persistance admin.permissions ; sync permissions Discord par guild.
- Deploy : commandes modération/config en guild-only ; globales limitées à translate, base64, transcript, pickup + menu contextuel.
- Profil bot : filtre image élargi (extension si contentType absent) + confirmation éphémère après import.
- Traduction : un seul message ; footer -# Traduction 🇺🇸 => 🇫🇷 ; fichier .txt si > 2000 caractères.
1. Import avatar/bannière profil bot toujours inopérant (/config éphémère → collecteur de messages inefficace).
2. Commande masquée encore visible dans Discord ; pas de message clair à l'utilisation.
3. Utilisateurs autorisés dans /config > Autorisations ignorés (/config et hasConfiguredAccess hardcodés propriétaire uniquement).
- Import profil : modale URL (copier le lien Discord) à la place du collecteur de pièces jointes ; saveBotAssetFromUrl.
- guard.js refondu : source unique admin.permissions ; checkCommandAccess centralisé dans interactionCreate.js.
- /config + panneau boutons : accès propriétaire ou utilisateurs/rôles listés dans admin.permissions.config.
- Message explicite si commande masquée : « désactivée sur ce serveur ».
- Sync commandes : rappel éphémère (cache Discord 1–5 min).
- Les 2 utilisateurs autorisés sur /config peuvent l'utiliser ; import image fiable ; commandes masquées bloquées à l'exécution avec message clair.
1. Rôle autorisé pour /config mais commande invisible (default_member_permissions Administrator).
2. /backup = simple export JSON, pas le système Python.
3. Pas de traduction automatique ni threads automatiques dans /config.
4. /clear sans filtre utilisateur.
- Visibilité slash : sync default_member_permissions depuis les bits des rôles autorisés ; resync après changement autorisations.
- /backup : snapshot guild v7 (rôles, salons, bans, membres, config bot) ; sous-commandes creer, liste, restaurer, supprimer ; restauration multi-parties.
- /clear : option utilisateur (filtre auteur, threads supportés).
- Communauté (/config > Système auto) : traduction auto (menu langues sur messages) + Thread automatique (containers, règles texte/URL/PJ, réactions, plusieurs configs/salon).
- Schémas autotranslation, auto_threads ; migration legacy imagethread.
- Modérateurs avec rôle autorisé voient /config si le rôle a les permissions Discord correspondantes ; backup/restauration type bot Python ; nouveaux systèmes communauté configurables.
1. Besoin de réactions automatiques (mot précis ou tous les messages, style MEE6).
2. Restauration des rôles mélangée aux rôles permanents — à isoler dans le hub rôles.
3. /config ne doit jamais être désactivable.
4. Commande /status réservée à l'utilisateur 1139951514694193323.
5. /transcript limité au TXT du salon courant — export HTML + portée serveur demandés.
- Réactions automatiques : schéma auto_reactions, handler messageCreate, UI /config > Système auto (salons, mots, tous messages, emojis).
- Restauration rôles : kind restore dans le hub (à côté permanent/temp/action/sélecteurs) ; retrait du toggle sur les permanents ; migration restore_on_rejoin → règles restore.
- /config protégée : forcée visible+enabled (cmdvis, guard, withDefaults) ; note UI « toujours active ».
- /status : commande globale owner-only, panneau présence (online/idle/dnd/invisible), type activité, modales texte/emoji/URL stream ; persistance data/bot-status.json ; appliquée au démarrage.
1. Page Système auto : emojis doublons, section Communauté regroupait traduction + threads.
2. /backup en sous-commandes au lieu du panneau unique bot Python.
3. Réactions auto : mode salons confus, modale mots en échec.
4. Traduction auto : ajout/retrait salon un par un.
5. Threads : pas de config des emojis de réaction par règle.
- Hub auto épuré : titre simple, 6 entrées distinctes sans emoji redondant.
- /backup unifié : panneau Créer / Appliquer / Supprimer + sélecteur + modal SUPPRIMER.
- Réactions : mode tous salons vs salons choisis ; modales corrigées (update).
- Traduction : multi-sélection salons (décocher = retirer).
- Threads : bouton Réactions + modale emojis par config.
- Navigation /config plus claire ; backup en une commande ; config fiable.
- bot-public/src/handlers/{config/panelsV2.js,config/panelsCommunity.js,config/panelsReactions.js,config/routerCommunity.js,config/routerReactions.js,config/communityModals.js,backup/backupHandler.js}
1. Hub config : remettre emojis à gauche + libellés en gras (pas sur les boutons) ; idem Administration.
2. Threads : remplacer « Exiger » par « Autoriser » (texte seul, URL, médias, légende).
3. Traduction auto : « Aucun texte à traduire » malgré message avec contenu ; pas de drapeaux dans le menu.
4. Profil bot : échec interaction sur Appliquer ; import uniquement par URL.
- Hub auto + admin : format emoji Nom à gauche, boutons sans emoji.
- Threads : règles allow_* + formats médias (png, webp, mp3, mp4, mkv, aac/acc, avi, jpeg, jpg, dds) ; migration legacy require_*.
- Traduction : cache texte à la réception + résolution fiable ; drapeaux sur chaque langue du menu.
- Profil bot : deferUpdate + followUp pour Appliquer ; boutons Importer fichier (PJ dans un salon, 2 min) + URL conservée.
- UI cohérente ; threads configurables en mode « autorisé » ; traduction auto fonctionnelle ; import avatar/bannière simplifié.
1. Le profil bot modifiait l'avatar/nom global du bot au lieu du seul pseudo serveur.
2. Demande d'une commande /rpc (User Install) pour simuler une Rich Presence via container.
3. Threads auto : messages supprimés même avec tout autorisé (config legacy require_* interprétée en mode restrictif).
- Profil bot : applyBotProfile() ne fait plus que member.setNickname() ; UI /config limitée au pseudo serveur + avertissement Discord.
- /rpc : commande globale User Install + panneau Container V2 (type, chrono, modales texte/images) ; stockage data/user-rpc/<userId>.json ; handlers boutons/modales urpc:*.
- Threads auto : migration legacy require_* → allow_* au chargement ; détection pièces jointes élargie ; config serveur 1494082227674288168 migrée sur disque.
- Plus de modification globale du bot via /config profil ; pseudo serveur uniquement.
- /rpc disponible en installation utilisateur (preview simulée, pas de vrai RPC Discord).
- Les messages texte, image seule ou avec légende ne sont plus supprimés si les types sont autorisés.
1. Traduction auto : « Aucun texte à traduire » (intent Message Content absent + résolution message fragile).
2. Profil bot trop limité vs bot Python (PATCH /guilds/.../members/@me).
3. Question RPC / scope activities.write.
4. Threads auto : config OK mais création de fils inactive.
- Traduction : intent MessageContent ; cache disque data/translation-cache.json ; résolution via référence du reply (comme Python) ; menu seulement si texte ≥ 3 caractères.
- Profil bot : guild.members.editMe() (nick, avatar, bannière, bio serveur) ; UI import URL/fichier restaurée.
- Threads : logique portée depuis imagethread_handler.py (autoThreadMedia.js) ; permissions complètes incl. SendMessagesInThreads + ManageMessages ; logs création.
- RPC : message explicite sur limite activities.write (bot ≠ OAuth client RPC).
- Traduction fonctionnelle si Message Content activé dans le portail Discord.
- Personnalisation bot par serveur comme le bot Python, sans toucher au profil global.
1. Profil bot : trop de messages publics lors des imports/applications.
2. Demande d’importer le système Vocal temporaire du bot Python dans Système automatique (UI Container).
3. Nouvelle commande /record : rejoindre un vocal, enregistrer en MP3, historique + téléchargement.
- Profil bot : import fichier → réaction ✅/❌ (plus de reply public) ; Appliquer → deferUpdate silencieux ; messages d’import en éphémère uniquement.
- Vocaux temporaires : portage join-to-create (tempVoiceHandler.js), config multi-entrées compatible Python, panneau contrôle Container (renommer/limite/supprimer), hub /config → Système automatique.
- /record : @discordjs/voice + ffmpeg → MP3 VBR ; container Démarrer/Arrêter + select téléchargement ; stockage data/recordings/<userId>/.
- Configuration profil bot sans spam salon.
- Vocaux temporaires configurables comme sur le bot Python (sans MySQL).
- Enregistrement vocal utilisable (ffmpeg requis, déjà présent sur le serveur).
1. /record : téléchargement MP3 impossible depuis le select ; dates non Paris ; pas de limite 25 avec rotation.
2. Vocaux temporaires : panneau simplifié sans embed permissions/autorisations du bot Python.
3. /status : un seul statut ; pas de rotation dynamique entre presets.
- /record : fix téléchargement (deferUpdate + followUp avec fichier) ; dates Europe/Paris ; max 25 enregistrements par utilisateur (suppression des plus anciens).
- Vocaux temporaires : embed complet (permissions @everyone, langue, limite) ; menus permissions/langue ; panneau Autorisation (ajouter/expulser/réinitialiser via MentionableSelect).
- /status : presets multiples (ajout/suppression/sélection) ; mode dynamique avec intervalle configurable ; rotation au démarrage (startStatusRotation).
- Téléchargement des enregistrements depuis l’historique ; horodatage Paris (heure d’été incluse).
- Panneau vocal identique au bot Python (embed + permissions + utilisateurs/rôles autorisés/interdits).
- Statut du bot rotatif entre plusieurs presets configurés.
1. Panneau vocal : repasser en Container V2 avec toggles permissions ; corriger bouton Autorisation ; sections users/rôles.
2. Commandes mod : pas de MP utilisateur ni contestation.
3. /status : presets bio rotatifs manquants.
4. Traduction auto : select langue fixe au lieu de la locale client.
- Vocaux temporaires : Container V2 avec toggles Autorisé/Interdit ; fix bouton Autorisation ; panneau éphémère UserSelect/RoleSelect.
- Modération : MP auto + bouton Contester + /contestation ; stores sanctions/contestations.
- /status : presets bio + rotation dynamique (applyBotBio).
- Traduction auto : bouton Traduire (locale client) ; helper translateForInteraction.js.
- Autorisations vocales fonctionnelles ; utilisateurs sanctionnés informés ; bio rotative ; traduction selon langue client.
- bot-public/src/{handlers/tempVoice/controlPanel.js,handlers/moderation/contestationHandler.js,handlers/autotranslation/autoTranslationHandler.js,commands/moderation/*,commands/owner/status.js,lib/botStatus.js,lib/moderation/*,events/*}
1. Autorisations vocaux : menu utilisateurs avec cocher/décocher.
2. Placeholders bienvenue : {username.server}, {id.user}, {web.user} manquants.
3. Menu langue panneau vocal inutile — locale client puis serveur.
- Auth vocaux : un UserSelectMenu multi (min 0) avec utilisateurs pré-cochés ; décocher retire l'accès.
- Placeholders : {username.server}, {id.user}, {web.user} dans placeholders.js.
- Locale : plus de select langue ; panneau = langue serveur ; éphémères = langue client → fallback serveur.
- bot-public/src/{handlers/tempVoice/controlPanel.js,lib/placeholders.js,lib/discordLocale.js}
- docs/RECAP-TRAVAIL-COMMUNAUTE-2026-04.md
1. Template vocal {display.name} affiché littéralement au lieu du nom d'affichage.
2. Sélecteur de rôles : pas de personnalisation nom/description/emoji par option ; multi-sélection peu claire.
- Vocal temporaire : templateName() utilise applyPlaceholders() ({display.name}, {username.server}, {user}, etc.).
- Sélecteur rôles : flux option = choisir rôle → modale nom/description/emoji ; description publiée dans le menu ; type par défaut select (multi-rôles cochables) ; suppression d'option.
- bot-public/src/{handlers/tempVoice/tempVoiceHandler.js,handlers/config/{panelsRoles.js,routerRoles.js,roleModals.js,routerCommunity.js,panelsCommunity.js},handlers/roles/roleSelector.js,lib/roleConfig.js}
- docs/RECAP-TRAVAIL-COMMUNAUTE-2026-04.md
1. Commande /role éphémère pour attribuer/retirer des rôles en masse (membres ou tout le serveur).
2. Page /config Sécurité & protection : anti-spam (anti-raid) + vérification (portage bot Python).
- /role : container éphémère V2 (UserSelect, RoleSelect, « Tous les membres », Ajouter/Retirer, Appliquer) ; respect hiérarchie des rôles.
- Config Sécurité : 3e catégorie dans /config ; anti-spam (multi-salons + même salon, sanctions configurables) ; vérification (web / réaction / bouton, salon, rôles, sync panneau).
- Anti-spam runtime : suppression messages dupliqués ; après N suppressions → sanction (timeout 10 min par défaut, ban/kick/warn/none).
- Vérification runtime : panneau bouton/réaction/web ; queue commands.json ; sync legacy bot/data/servers/ pour lbxmb.fr.
- Modération rôles en masse via /role.
- Anti-spam actif si anti-raid + anti-spam activés dans /config > Sécurité.
- Vérification web/bouton/réaction alignée sur le bot Python.
1. Création d'un vocal : le texte « Permissions @everyone » dans le panneau pingait tout le serveur.
2. Souhait de ping le rôle « cherche du monde vocal » (1520182284198744184) à la place.
3. Permission Historique des messages absente pour @everyone sur les vocaux créés.
- Libellé panneau : « Permissions du salon » (plus de @everyone dans le texte).
- À la création : message <@&1520182284198744184> avec allowedMentions ciblé ; panneau sans mentions parsées.
- Overwrites @everyone à la création : inclut ReadMessageHistory (+ messages, pièces jointes, commandes).
- Toggle Historique des messages ajouté au panneau de permissions.
- Plus de ping @everyone à la création ; seuls les membres avec le rôle vocal sont notifiés.
- Chat du vocal : historique des messages lisible pour tout le monde.
- bot-public/src/handlers/tempVoice/{controlPanel.js,tempVoiceHandler.js}
1. Boutons du panneau vocal sur une seule ligne — souhait de 2 lignes (Renommer | Autorisation / Limite | Supprimer).
2. Mention du rôle vocal dans un message séparé — tout doit être dans le container avec « Alerte @vocal » uniquement.
- Boutons répartis sur 2 lignes dans le Container V2.
- Ligne Alerte <@&rôle> en tête du container ; suppression du message texte séparé.
- Ping du rôle 1520182284198744184 uniquement à la création du vocal (pingRole: true).
- Panneau plus lisible ; une seule message container ; notification ciblée au rôle vocal à l'ouverture.
- bot-public/src/handlers/tempVoice/{controlPanel.js,tempVoiceHandler.js}
- docs/RECAP-TRAVAIL-COMMUNAUTE-2026-04.md
1. /role : afficher la progression membre par membre (Pseudo 22/183).
2. Config sécurité : anti-spam doit être une option dans anti-raid.
3. Vérification : vider les rôles, panneau Discord refait, option compte lbxmb.fr.
4. Page lbxmb.fr/verify/[id] : serveur introuvable, OAuth refusé, pas de nom/logo.
- /role : progression Pseudo \22/183\`` pendant l’attribution en masse.
- Anti-raid : hub Config > Sécurité > Anti-raid > Anti-spam (seuil, fenêtres, sanctions dont suppression seule).
- Vérification Discord : Container V2 (Me vérifier + À savoir éphémère) ; vider rôles ; toggle compte lbxmb.fr.
- Site verify : config fusionnée bot-public + legacy ; métadonnées Discord API ; handler server.js pour prod sans rebuild ; secret OAuth Discord corrigé (invalid_client).
- Progression visible sur attributions massives ; hiérarchie anti-raid cohérente.
- Panneau vérification professionnel avec explication RGPD via « À savoir ».
Lors de la mise à jour d'un container (vérif, vocal temporaire, sélecteurs, /config, /role), le bot tentait un edit sur un message supprimé — échec silencieux, panneau perdu.
- Nouveau module panelMessage.js : editOrResendChannelMessage (fetch forcé → edit, sinon renvoi + MAJ ID) et safeInteractionUpdate / safeInteractionEditReply (fallback followUp si message d'origine introuvable).
- Appliqué à : vérif, vocal temporaire, sélecteurs rôles/pseudo, /role, tous les routeurs /config.
- Suppression manuelle d'un panneau → resync le recrée automatiquement.
- Interaction sur un message supprimé → nouveau message éphémère au lieu d'une erreur muette.
- bot-public/src/lib/panelMessage.js
- bot-public/src/handlers/{verification/verificationPanel.js,tempVoice/controlPanel.js,roles/roleSelector.js,nicks/nickSelector.js,role/roleCommandHandler.js,config/{router.js,routerSecurity.js,routerRoles.js,routerNicks.js,routerCommunity.js,routerReactions.js,routerAdmin.js,editFlowV2.js,securityModals.js}}
- docs/RECAP-TRAVAIL-COMMUNAUTE-2026-04.md
### 1. Container de vérification refait
Le panneau de vérification manquait de clarté sur l'intérêt de la vérification et les données récoltées.
### 2. « Publier panneau » : nouveau container si le salon a changé
Republier le panneau de vérif après avoir changé de salon laissait l'ancien panneau orphelin dans l'ancien salon.
### 3. Anti-spam corrigé
L'anti-spam ne se déclenchait pas (spam répété sans effet).
### 4. Connexion inter-salon (bridge multi-serveurs)
Synchroniser un même salon (ex. « entraide ») entre plusieurs serveurs où le bot est présent.
- buildVerificationPanelPayload : nouvel embed « Vérification requise » qui explique qu'il faut se vérifier pour accéder au serveur, avec 2 boutons.
- Bouton Me vérifier : lien direct vers l'URL de vérification du serveur (lbxmb.fr/verify/<id>) en méthode web ; bouton custom en méthode bouton ; masqué en méthode réaction.
### 1. Vérification web : « échange du code Discord refusé »
Après connexion Discord, retour sur le site en erreur « échange du code Discord refusé ».
### 2. Bouton « En savoir plus » en bleu + non-accès admin aux IP
### 3. Connexion inter-salon : modèle par serveur + invitations
Les configs inter-salon devaient être individuelles (aucun serveur ne modifie la config d'un autre) avec un système d'invitation : on invite un serveur par ID, il accepte et choisit son propre salon.
- Paire client_id/client_secret validée OK (grant client_credentials → 200) : ce n'est pas un invalid_client.
- Cause : la route /api/verify/oauth/callback appelait handleVerifyOAuthCallback(request, {}) → redirect_uri du token calculé avec le chemin par défaut (/api/verify/discord/callback), différent du chemin réellement appelé → invalid_grant.
- verify-oauth-callback-logic.ts : le redirect_uri du token est désormais reconstruit depuis le chemin réel de la requête entrante (new URL(request.url).pathname) → correspond toujours à celui utilisé à l'autorisation, quelle que soit la route de callback.
### 1. Import manquant cassant TOUS les handlers de messages
Le bot ne relayait aucun message inter-salon, et plus largement l'anti-spam / threads / réactions / traduction ne se déclenchaient pas.
messageCreate.js appelait tryPendingBotImport(message) sans l'importer → ReferenceError à chaque message → tout le code suivant (handleAutoReactions, handleAntiSpamMessage, handleCrossChannelMessage, traduction, threads) ne s'exécutait jamais (rejet silencieux capté par unhandledRejection).
### 2. Modale d'invitation : erreur visible bien que l'action réussisse
La soumission de la modale faisait interaction.update() puis interaction.followUp() systématiquement → l'enchaînement provoquait une erreur côté client alors que l'invitation était bien enregistrée.
- Ajout de l'import tryPendingBotImport depuis lib/botProfileImport.js.
- Le relais inter-salon, l'anti-spam et les autres traitements de messages fonctionnent à nouveau (redémarrage du bot requis).
- bot-public/src/events/message/messageCreate.js
### 1. Fix : messages de bienvenue/départ « échec de l'interaction » au clic « Configurer »
Impossible de configurer les sections de messages automatiques (bienvenue, départ, etc.) : le clic sur « Configurer » renvoyait « échec de l'interaction ».
Collision de préfixe de customId. Les sections de messages auto utilisaient cfg:sec:open:<section> (« sec » = section) alors que le module Sécurité capte tout parts[1] === "sec" (isSecurityButton). Le bouton était donc routé vers la sécurité, qui ne connaît pas l'action open → aucune réponse → interaction échouée.
### 2. Inter-salon : synchronisation réactions (ajout), épingles, sondages
### 3. Commande /bl — blacklist globale (réservée aux propriétaires)
### 4. /statut → /bot (gestion complète du bot)
### 5. Commande /signaler — signalement d'utilisateur (guild + user install)
### Contexte / problème
Suite de la session : (1) consulter les signalements sans DM, (2) restreindre l'usage de commandes à certains salons, (3) lecteur musique YouTube en vocal, (4) panneau /bot trop chargé, (5) /contestation était une erreur (un bouton est attendu, pas une commande), (6) commande d'aide listant les commandes publiques et cliquables.
### 1. /signalement — consultation des signalements (propriétaires)
### 2. Restriction des commandes par salon (/config > Autorisations)
### 3. /music — lecture YouTube en vocal
### 4. /bot — panneau séparé en pages
### 5. Contestation par bouton (suppression de /contestation)
### 6. /help — aide paginée et cliquable
### Déploiement
### Contexte / problème
Retour utilisateur : (1) erreur serveur introuvable à la vérification + besoin d'un message clair quand la vérif est désactivée ; (2) signalement via menu contextuel utilisateur (modale) ; (3) sélecteur de rôles en mode boutons : les boutons n'ont pas de description → choisir une couleur ; (4) réintroduire /voctime (système du bot Python) ; (5) /backup en container avec menu déroulant et boutons contextuels.
### 1. Vérification web
### 2. Menu contextuel « Signaler » (utilisateur)
### 3. Sélecteur de rôles — couleur des boutons
### 4. /voctime (temps vocal)
### 5. /backup — container + boutons contextuels
### Déploiement
### Fichiers touchés
### Contexte / problème
### Changements appliqués
1. Streaming musique → yt-dlp + ffmpeg (approche fiable 2026)
2. /music = commande unique + container
3. Fix vérif « échange du code Discord refusé »
### Impact
### Fichiers touchés
- /music était une commande à sous-commandes (play/skip/stop/...) ; demande : une seule commande avec un container et les actions en boutons.
- Lecture cassée : le bot rejoignait le vocal, trouvait le morceau, puis quittait immédiatement. Cause : play-dl@1.9.7 ne parvient plus à streamer YouTube (lib obsolète, flux vide → player Idle).
- Vérification web : erreur récurrente « échange du code Discord refusé ».
- Installé le binaire yt-dlp (/usr/local/bin/yt-dlp, v2026.06.09). Testé OK depuis le serveur (recherche + extraction flux).
### Contexte / problème
### Changements appliqués
1. Fix vocal — bibliothèque de chiffrement manquante
2. Refonte container /music
3. Fix vérif « serveur introuvable »
### Impact
### Fichiers touchés
- Musique : « ❌ Connexion au salon vocal impossible » — le bot rejoignait le vocal mais ne jouait rien et repartait.
- /music devait envoyer directement un container (pas de choix obligatoire) avec menu déroulant des morceaux + boutons complets.
- Vérification web : « serveur introuvable » lors de la vérif.
- @discordjs/voice@0.19.2 exige une lib de chiffrement (modes AEAD imposés par Discord) ; aucune n'était installée → la connexion ne passait jamais Ready → déconnexion immédiate.
### Contexte / problème
### Changements appliqués
1. redirect_uri du callback (prod)
2. Audio vocal — libsodium-wrappers cassé sous ESM
### Impact
### Fichiers touchés
- Vérif : échange du code Discord refusé (Invalid "redirect_uri" in request).
- Musique : le bot reconnaît le morceau mais ne joue rien en vocal (connexion OK, son absent).
- Le build figé d'authorize utilise /api/verify/oauth/callback, alors que le .cjs envoyait en dur /api/verify/discord/callback → mismatch.
- verify-oauth-callback.cjs réutilise désormais le chemin entrant réel (= le redirect_uri validé par Discord). Testé live : les deux chemins renvoient « Invalid code » (et non plus « Invalid redirect_uri ») → le redirect_uri correspond, un vrai code aboutit.
- Diagnostic : sous ESM, après await ready, libsodium-wrappers n'expose ses méthodes que sur .default, pas sur le namespace ; or @discordjs/voice appelle lib.crypto_aead_xchacha20poly1305_ietf_encrypt sur le namespace → undefined → chiffrement des paquets vocaux échoue → connexion « Ready » mais silence.
### Contexte / problème
### Investigation (preuves)
### Conclusion
### Changements appliqués
### Impact
### Fichiers touchés
- Le bot rejoint le vocal, trouve le morceau, puis quitte immédiatement ("je viens de lancer mon morceau et le bot à quitter le vocal").
- generateDependencyReport() : toutes les deps vocales présentes (sodium-native 5.1.0, @discordjs/opus 0.10.0, ffmpeg, DAVE). → pas un souci de lib.
- Repro via script de diag (bot rejoint un vocal vide et joue) : la connexion reste bloquée en connecting puis timeout 20 s → destroy(connect-failed).
- Debug @discordjs/voice (debug: true) : le WebSocket vocal fonctionne (op 2 reçu avec ip/port du serveur média Discord, modes aead_aes256_gcm_rtpsize/aead_xchacha20_poly1305_rtpsize). Le blocage est à l'étape suivante : la découverte d'IP UDP n'aboutit jamais.
### Contexte / problème
### Investigation (preuves définitives)
### Conclusion
### Fichiers touchés
- Question : « tu as accès à la machine, tu peux activer l'UDP pour le port ? »
- Firewall local : OUTPUT = ACCEPT, UDP NEW accepté, retours conntrack RELATED/ESTABLISHED autorisés → rien à activer localement, c'est déjà ouvert.
- STUN Google (UDP port haut 19302) : 10/10 OK → l'UDP haut-port sortant/retour fonctionne en général.
- Sonde maison : envoi de 15 vrais paquets de découverte d'IP Discord vers le serveur voix live (104.29.144.78:19301, ssrc réel) → 0 réponse. Idem sur plusieurs sessions (104.29.151.x, 104.29.144.x).
- Ping ICMP vers l'IP voix → Time to live exceeded (boucle de routage) ; TCP/443 vers ces IP → OK ; traceroute UDP s'arrête au hop 5 (37.49.238.59, transit hébergeur).
### Contexte / problème
1. /bot : containers trop chargés (trop de boutons).
2. /bot → page serveur : l'icône du serveur ne s'affiche pas.
3. Présence & statuts : remplacer les multiples boutons par un design épuré.
4. Permissions commande par salon : autoriser les salons vocaux + « échec de l'interaction » après le choix du salon.
5. Vérification : conserver l'IP (très important) + tout l'historique ; si l'utilisateur quitte puis re-vérifie avec une IP différente, garder l'ancienne et ajouter la nouvelle.
### Changements appliqués
### Impact
### Fichiers touchés
- Point 4 (bug interaction) : dans config/router.js, le channel-select admin (cfg:admin:permchannels:…) était intercepté par le handler générique handleChannelSelect (qui ne l'acquittait jamais) → « échec de l'interaction ». Dispatch déplacé avant le handler générique ; ancien test mort supprimé. Les salons vocaux étaient déjà autorisés (ChannelType.GuildVoice dans le select) et le guard utilise interaction.channelId (fonctionne pour les vocaux).
### Contexte / problème
### Changements appliqués
### Impact visible / technique
### Fichiers touchés
- Besoin d'une commande /sondage avec un panneau de configuration éphémère (question, description, choix, boutons de vote).
- En production : tout utilisateur qui se vérifie sur un serveur doit automatiquement obtenir un compte sur le site.
- Nouvelle commande guild /sondage : ouvre un container éphémère (Components V2) pour construire le sondage.
- Boutons : « Question / description » (modal), « Ajouter un choix » (modal label + emoji, max 10), bascule mode unique/multiple, « Publier ».
- Menu déroulant pour retirer un choix.
- Publication : message public avec barre de progression %, compteur de votes, un bouton par choix + bouton « Clôturer » (auteur ou modérateur ManageMessages).
- Vote par bouton : bascule du vote, gestion unique vs multiple, mise à jour en direct.
### Contexte / problème
### Diagnostic
### Changements appliqués
### Impact visible / technique
### Fichiers touchés
- Impossible de se connecter sur ptb.lbxmb.fr et dev.lbxmb.fr.
- Log dev : ERROR [Better Auth]: { error: 'invalid_client', status: 401 } lors de l'échange du code Discord.
- Les 3 sites partagent le même DISCORD_CLIENT_ID (1431308308505039069) donc doivent partager le même DISCORD_CLIENT_SECRET.
- Empreintes des secrets : prod 931d3ed6 (correct), ptb & dev b66b652d (périmé). Process live ptb : secret vide.
- Les endpoints sign-in/social généraient pourtant les bons redirect_uri (ptb/dev), tables Better Auth présentes → seul le secret était en cause.
- ptb-web/.env.local et dev-web/.env.local : DISCORD_CLIENT_SECRET réaligné sur la valeur de prod.
- pm2 restart web-ptb web-dev --update-env avec le secret exporté dans le shell (dotenv n'écrase pas une variable déjà présente ; en mode cluster pm2 passe l'env par IPC).
### Contexte / problème
### Changements appliqués
### Impact visible / technique
### Fichiers touchés
- La base de ptb (lbxmb_ptb) n'était pas la même que la prod ; demande explicite : ptb doit utiliser la même base que la prod.
- ptb-web/.env.local : DB_USER, DB_PASSWORD, DB_NAME (+ host/port) réalignés sur la prod → DB_NAME=lbxmb, DB_USER=lbxmb.
- pm2 restart web-ptb --update-env avec les variables DB de prod exportées (pm2/dotenv ne réécrasent pas une variable déjà chargée).
- ptb lit/écrit désormais la base de production live (lbxmb). Sessions Better Auth partagées avec la prod ; get-session = 200 ; utilisateur résolu dans les logs.
- ⚠️ Les actions effectuées sur ptb impactent directement les données de production (choix assumé).
- ptb-web/.env.local
### Contexte / problème
### Changements appliqués
### Impact visible / technique
### Fichiers touchés
- Demande (sur ptb) : messagerie unifiée (Tickets > Vente > Privé), pouvoir prendre en charge / fermer / transférer un ticket en respectant les règles de rôle (un support ne peut pas recevoir un ticket de modérateur), et corriger l'alignement du composer.
- Blocage découvert : les sources de ptb-web étaient partiellement vidées (MessageBell.tsx, Header.tsx, permission-roles.ts, etc. absents) → build impossible.
- Remise en état de ptb-web : script ptb-web/scripts/recover-src-from-maps.cjs qui récupère les fichiers source manquants depuis les source maps de .next-staging (n'écrase jamais l'existant, filtre les artefacts Next). 22 fichiers restaurés (dont MessageBell.tsx, Header.tsx, permission-roles.ts). SiteWelcomeModal.tsx (absent du build) copié depuis web. → arbre de nouveau buildable (next build OK).
### Contexte / problème
### Changements appliqués
### Impact visible / technique
### Fichiers touchés
- Après migration dev → prod, le chat n'était pas aligné : version « propre » (liste unifiée, actions ticket, composer corrigé) sur dev/ptb, mais prod servait encore l'ancien build avec onglets Conversations/Tickets.
- Cause racine : les arbres web et ptb-web avaient divergé ; la prod tournait sur un .next-staging figé sans rebuild des changements messagerie. Les sources web étaient aussi incomplètes (~36 fichiers manquants vs ptb).
- Port ptb → web : MessageBell.tsx, ComposeTextarea.tsx (liste unifiée Tickets > Vente > Privé, prise en charge / fermer / transférer, composer aligné).
- API prod alignées : vérif du niveau d'accès de la cible sur transfert ticket ; permission exposée dans /api/admin/support-staff.
- Remise en état sources web : copie des 36 fichiers manquants depuis ptb + récupération depuis source maps du build prod + stub SiteIntroduction.tsx + globals.css.
### Contexte / problème
### Changements appliqués
### Impact visible / technique
### Fichiers touchés
- Erreur critique affichée sur le site : o.map is not a function (boundary Next.js).
- Cause : dans MessageBell et use-app-queries, res.data.permissions était traité comme tableau via .length alors qu'une chaîne CSV ("fondateur,admin") a aussi une .length → appel de .map sur une string.
- Demande : rebuild et déploiement des 3 environnements (dev, ptb, prod).
- Parsing permissions sécurisé via permissionsFromUserRecord() dans MessageBell.tsx et useTicketRedirectAuth (use-app-queries.ts).
- Garde Array.isArray sur res.data.conversations dans fetchVendorConvs.
- Rebuild + déploiement :
- prod (web) → BUILD_ID Ky1Jly3LI4UbvM0Lzg2La, pm2 restart web-prod
- ptb → BUILD_ID H_s_YgDbcjbIeAZw0kE3y, pm2 restart web-ptb
### Contexte / problème
### Changements appliqués
### Impact visible / technique
### Fichiers touchés
- Production affichait à nouveau « Erreur critique » : o.map is not a function.
- Cause racine : messages/fr.json et messages/en.json absents de web/ alors que la locale par défaut est fr. loadMessagesForLocale échouait → messages i18n vides → t.raw("reviews") dans Testimonials renvoyait une chaîne (clé manquante) → .map() sur une string.
- Restauration de messages/fr.json et messages/en.json depuis ptb-web (web + dev).
- load-messages.ts : si le fichier base messages/<locale>.json est absent, on continue quand même (merge faq/discordBot) au lieu de tout faire échouer.
- Garde-fous Array.isArray dans Testimonials.tsx et FAQ.tsx.
- Rebuild + déploiement des 3 env : prod f8UWlF8yGCTbG6Fpw7OJp, ptb et dev également.
### Contexte / problème
### Changements appliqués
### Impact visible / technique
### Fichiers touchés
- Panier visible dans la navbar au lieu du menu utilisateur.
- Actions ticket mal placées ; staff ne pouvait pas répondre après prise en charge (currentUserId = user_id Discord au lieu de users.id interne).
- Page /panier masquée sous le header fixe.
- Sur mobile en messagerie : navbar haute gênante ; bottom nav doit rester visible.
- Cards boutique affichaient les images en bannière pleine largeur au lieu d’icônes carrées.
- Retrait de CartButton du header ; entrée Mon panier dans le menu profil (sheet mobile + dropdown desktop) avec traduction profileMenu.myCart.
- Actions ticket staff déplacées en haut de la conversation (Prendre en charge / Fermer / Transférer) ; correction currentUserId via u.id (ID interne DB).
- /panier : padding top pt-24 sm:pt-28 sous le header fixe.
### Contexte / problème
1. Vérification bot : redirect_uri OAuth2 non valide (URI /api/verify/discord/callback non enregistrée sur le portail Discord ; la bonne URI est /api/verify/oauth/callback).
2. Boutique desktop : layout horizontal type Amazon au lieu d’icône carrée au-dessus du titre.
3. Connexion ptb/dev redirige vers prod (Better Auth sans BETTER_AUTH_URL ni origines ptb/dev).
4. Menu utilisateur partiellement masqué par la bottom nav.
5. Messagerie : besoin d’une barre de recherche en haut + bouton nouvelle conversation à droite.
### Changements appliqués
### Impact visible / technique
### Fichiers touchés
- VERIFY_OAUTH_CALLBACK_PATH → /api/verify/oauth/callback (authorize + callback + .cjs live).
### Contexte / problème
### Changements appliqués
### Impact visible / technique
### Fichiers touchés
- bun run deploy ne fonctionnait plus : script npm deploy absent ; deploy:prod pointait vers /root/lbxmb.fr/deploy.sh supprimé.
- Recréation de deploy.sh (build → swap .next-staging → pm2 restart web-prod --update-env).
- Ajout de "deploy": "bash ../deploy.sh" dans web/package.json.
- Depuis web/ : bun run deploy ou bun run deploy:prod refonctionnent pour la prod.
- deploy.sh
- web/package.json
### 1. Autorisation vocal temporaire — interdire / réautoriser
#### Contexte / problème
#### Changements appliqués
#### Impact visible / technique
#### Fichiers touchés
### 2. /voctime — parité bot Python
#### Contexte / problème
#### Changements appliqués
#### Impact visible / technique
#### Fichiers touchés
### 3. /to et /unto — timeout Discord (sans salon)
#### Contexte / problème
#### Changements appliqués
#### Impact visible / technique
#### Fichiers touchés
### 1. Panier hors navbar → menu utilisateur
#### Contexte / problème
#### Changements appliqués
#### Fichiers touchés
### 2. Messagerie tickets — actions + réponse après prise en charge
#### Contexte / problème
#### Changements appliqués
#### Fichiers touchés
### 3. Page panier — contenu sous la navbar
#### Changements
#### Fichiers touchés
### 4. Boutique — icône carrée (pas bandeau)
#### Changements
#### Fichiers touchés
#### Déploiement
- Le panier ne doit pas apparaître dans la barre de navigation principale.
- Entrée Mon panier conservée dans le menu profil (desktop dropdown + ProfileMenuSheet mobile).
### 1. bot-site — pseudo + drapeau pays → Discord
#### Changements
#### Fichiers touchés
### 2. Site — majuscules dans le pseudo
#### Changements
#### Fichiers touchés
### 3. bot-public — /stats (ex-/voctime) + /config
#### Changements
#### Fichiers touchés
#### Déploiement
- Route POST /sync-profile : construit le nick 🇫🇷 Pseudo (max 32 car.) et appelle l'API Discord.
- Client web discord-bot-site.ts : appelle bot-site au lieu de commands.json (orphelin).
- Branchement sur changement profil (/api/profil), OAuth (auth.ts, auth-helpers.ts).
- Variables BOT_SITE_URL + INTERNAL_API_KEY dans web/.env.local.
### 1. bot-public — /config > Commandes & permissions (échec interaction)
#### Contexte
#### Changements
#### Fichiers touchés
### 2. bot-public — /sondage accessible à tous par défaut
#### Changements
#### Fichiers touchés
### 3. bot-public + web — DM vérification + persistance compte/IP
#### Changements
#### Fichiers touchés
### 4. bot-public — refonte /stats (menu + canvas)
#### Changements
#### Fichiers touchés
#### Déploiement
- DEFAULT_COMMANDS compte 28 entrées ; Discord limite les StringSelectMenu à 25 options → interaction en échec.
- Pagination des menus commandes (cmdvis) et permissions (permpick) par blocs de 25.
### 1. bot-public — commandes publiques gérables dans /config
#### Contexte
#### Changements
#### Fichiers touchés
### 2. bot-public — refonte /transcript
#### Changements
#### Fichiers touchés
### 3. bot-public — redesign canvas /stats
#### Changements
#### Fichiers touchés
#### Déploiement
- transcript, pickup, base64 étaient déployées globalement → absentes de la sync par serveur : impossible de les désactiver ou de leur assigner des rôles (ex. sondage).
- GLOBAL_COMMAND_NAMES réduit à : translate, help, music, rpc, signaler.
- transcript, pickup, base64, sondage, stats passent par la sync par serveur (syncGuildCommands).
- Permissions publiques sans restriction custom → default_member_permissions: null.
### 1. bot-public — canvas /stats (messages 24h/7j/28j + histogramme)
#### Contexte
#### Changements
#### Fichiers touchés
### 2. bot-public — /config > Notifications
#### Contexte
#### Changements
#### Fichiers touchés
### 3. web + nginx — IP client réelle (plus de 127.0.0.1 partout)
#### Contexte
#### Changements
#### Fichiers touchés
#### Déploiement
### 4. web + nginx + Anubis — fix IP réelle (v2, cause Anubis)
#### Contexte
#### Changements
#### Fichiers touchés
#### Déploiement
### 1. IP vérification — parsing headers renforcé
#### Contexte
#### Changements
#### Impact
#### Fichiers touchés
### 2. Blacklist → ban tous les serveurs du bot
#### Changements
#### Fichiers touchés
### 3. Nouveau logo lbxmb.png
#### Changements
### 4. dev.lbxmb.fr redirect prod
#### Cause
#### Changement
#### Fichiers touchés
### 5. Navbar transparente en haut
#### Changement
#### Fichiers touchés
### 6. Domaines : footer, retrait navbar
#### Changements
#### Fichiers touchés
### 7. Menus Applications / mobile
### Contexte
### Changements
### Impact
### Fichiers touchés
### Déploiement
- Question : le bot utilise-t-il un port ? Les options bot ne marcheraient pas sans.
- bot-public (Discord /config, modération, etc.) : jusqu'ici aucun port HTTP — uniquement WebSocket Discord + file commands.json.
- bot-site (sync pseudo/rôles site ↔ Discord) : déjà actif sur 8787 (/health OK).
- Nouveau serveur HTTP local bot-public/src/lib/internalHttpServer.js sur 127.0.0.1:25591.
- Routes : GET /health (public), GET /status + POST /internal/flush-verification (header x-api-key = BOT_INTERNAL_SECRET).
- flushWebVerificationQueue() exporté pour traiter la vérif web sans attendre le poll 5 s.
- Variables .env : BOT_PUBLIC_HTTP_PORT, BOT_PUBLIC_HTTP_HOST, BOT_INTERNAL_SECRET, LIBRETRANSLATE_URL.
- ecosystem.config.js : entrées bot-public et bot-site documentées.
### 1. Rôles temporaires — durées flexibles
#### Contexte
#### Changements
#### Impact
#### Fichiers touchés
### 2. Messages de bienvenue — variables invite
#### Contexte
#### Changements
#### Fichiers touchés
### 3. Blacklist — ban serveurs + MP détaillé
#### Contexte
#### Changements
#### Fichiers touchés
### 4. Commande /radio
#### Changements
#### Fichiers touchés
#### Déploiement
- La config n'acceptait que des minutes entières.
- Parser partagé durationParse.js : 30s, 15m, 2h, 7j, 2sem, 1mo, 1an (nombre seul = minutes).
### Contexte
### Changements
### Impact
### Fichiers touchés
### Déploiement
- /radio invisible : absente de GLOBAL_COMMAND_NAMES (non déployée globalement).
- Demande : station en liste déroulante (NRJ, Skyrock…) + commandes /play, /skip, /queue, etc.
- /radio station: avec choix fixes (12 stations + « Arrêter la radio »).
- Ajout à GLOBAL_COMMAND_NAMES : radio, play, skip, queue, pause, resume, stop, volume, playlist.
- Nouvelles commandes musique :
- /play morceau: — lance ou remplace le morceau en cours
- /skip, /pause, /resume, /stop
- /queue — file d'attente
- /volume niveau: — 0–200 % (sans option = affiche le volume actuel)
- /playlist ajouter lien: — playlist YouTube (max 50 morceaux)
- /playlist file — voir la file
### Contexte
### Changements
### Impact
### Fichiers touchés
### Déploiement
- /radio invisible : absente de GLOBAL_COMMAND_NAMES (non déployée globalement).
- Demande : station en liste déroulante (NRJ, Skyrock…) + commandes /play, /skip, /queue, etc.
- /radio station: avec choix fixes (12 stations + « Arrêter la radio »).
- Ajout à GLOBAL_COMMAND_NAMES : radio, play, skip, queue, pause, resume, stop, volume, playlist.
- Nouvelles commandes musique :
- /play morceau: — lance ou remplace le morceau en cours
- /skip, /pause, /resume, /stop
- /queue — file d'attente
- /volume niveau: — 0–200 % (sans option = affiche le volume actuel)
- /playlist ajouter lien: — playlist YouTube (max 50 morceaux)
- /playlist file — voir la file
### Contexte
### Changements
### Fichiers touchés
### Déploiement
- Le bot arrivait en vocal à 100 % de volume, trop fort pour les utilisateurs.
- DEFAULT_VOLUME = 0.25 (25 %) appliqué à la musique et à la radio à la connexion vocale.
- Affichages panneau /music et /queue alignés sur cette valeur par défaut.
- bot-public/src/lib/music/musicManager.js
- bot-public/src/lib/music/radioManager.js
- bot-public/src/lib/music/musicSlashHelpers.js
- bot-public/src/commands/util/music.js
- pm2 restart bot-public --update-env
### Contexte
### Changements
### Fichiers touchés
### Déploiement
- NRJ, Nostalgie, Fun Radio, Virgin ne fonctionnaient pas (URLs obsolètes 404).
- Changer de station faisait quitter/rejoindre le vocal (visible sur Play/Xbox).
- URLs mises à jour après tests ffmpeg (nrjaudio, infomaniak, icecast, bfmtv…).
- switchStation() : change le flux ffmpeg sans connection.destroy().
- Réutilisation de getVoiceConnection() si déjà dans le même salon.
- User-Agent ffmpeg pour les diffuseurs exigeants.
- bot-public/src/lib/music/radioStations.js
- bot-public/src/lib/music/radioManager.js
- bot-public/src/commands/util/radio.js
- pm2 restart bot-public --update-env
### 1. Placeholders vocaux cross-serveur
### 2. Bienvenue / départ — bots
### 3. Rôles auto permanent/temporaire — cible bots
### 4. Vocal temporaire — rôle alerté
### 5. Vocal temporaire — rôles autorisés/interdits
### 6. Aide variables {} contextuelle
### Fichiers touchés
### Déploiement
- Préférences propriétaire vocal scopées par {guildId}/{userId} (plus de nom figé d'un autre serveur).
- {display.name}, {username.server}, {user.id} appliqués depuis le template du serveur courant.
- Cible par entrée : utilisateurs / bots / tous (/config → bouton Changer).
- Placeholders {bot.mention}, {bot.name}, {bot.id}, {bot.add} (audit log).
- Champ target sur les règles + filtre dans autoRoleEngine.
- alert_role_id configurable par config (remplace le rôle hardcodé LB'XMB).
### Changements
### Fichiers touchés
- {bot.add.mention} et {bot.add.name} (nom d'affichage de l'ajouteur).
- Retrait de {invite.link} de l'aide ; seul {invite.code} documenté.
- {invite.display} = nom d'affichage de l'inviteur sur le serveur (plus le nom du salon).
- {invite.display.name} conservé en alias rétrocompat.
- Inviteurs bots ignorés pour {invite.display} / compteur.
- bot-public/src/lib/placeholders.js
- bot-public/src/handlers/invites/inviteTracker.js
- bot-public/src/events/guild/guildMemberAdd.js
- bot-public/src/handlers/welcome/welcomeSender.js
### 1. Suppression /rpc
### 2. Notifications hors « Système automatique »
### 3. Statistiques serveur (nouveau module)
### 4. Fix sélecteur de rôles (6+ options)
### Déploiement
- Contexte : commande user-installed peu concluante.
- Changements : suppression rpc.js, userRpc.js, handlers interaction, entrée commandSync, aide /help.
- Impact : la commande disparaît après redeploy (18 commandes globales).
- Fichiers : commands/util/rpc.js (suppr.), lib/userRpc.js (suppr.), interactionCreate.js, commandSync.js, help.js
- Contexte : doublon avec la page dédiée via la nav /config.
- Changements : retrait de l'entrée Notifications du hub Système automatique (nav principale inchangée).
- Fichiers : panelsV2.js
- Contexte : afficher membres, bots, rôle… dans nom salon / sujet / nom serveur / surnom bot.
### Contexte
### Changements
### Impact visible
### Fichiers touchés
- Connexion Bedrock impossible : port 19132/UDP non exposé (UFW + aucune allocation Pterodactyl).
- Plugin Geyser-Spigot configuré sur le port 25565 et incompatible avec Paper 26.2 (crash au démarrage).
- UFW : ouverture 19132/udp, 25565/tcp+udp, 25575/tcp+udp (Minecraft).
- Pterodactyl : allocation 19132 testée puis retirée du conteneur MC (Geyser standalone sur l'hôte).
- Geyser standalone : conteneur Docker geyser-bedrock (/opt/geyser-standalone/), écoute UDP 19132, pont vers Java 151.240.100.62:25565, auth floodgate.
- Config Geyser plugin (serveur MC) : port Bedrock passé à 19132 (plugin toujours inactif tant que Paper 26.2 incompatible).
- Bedrock : 151.240.100.62:19132
- Java : 151.240.100.62:25565
- data/firewall_config.json
### 1. Bot — changement de salon messages auto (bienvenue)
### 2. SwipePicker — boucle langue / pays
### 3–5. Navbar mobile (dev)
### 6. Connexion Discord sur dev
### 7. Photos fondateurs accueil
### 8. Staff mobile — recherche utilisateur
### Déploiement
- Contexte : erreur lors du changement de salon sur une config (ex. welcome_dm).
- Cause : customId découpé par : → section welcome_dm lue comme welcome + id dm.
- Changement : parsing cfg:chan:set / cfg:add:chan avec slice + join(":") pour les clés de section.
- Fichiers : bot-public/src/handlers/config/router.js
- Contexte : après la dernière option, plus de défilement (Fr → En → Es puis stop).
- Changement : loop: true Swiper + realIndex pour langues et pays dans les paramètres profil.
- Fichiers : dev-web/src/components/ui/SwipePicker.tsx
### 1. Messages auto — changement de salon (bouton « Changer »)
### 2. Vocal temporaire — traduction panneau post-création
### 3. Sélecteur de rôles — emojis + >25 options
### 4. Traduction automatique — mentions / URLs / emojis
### 5. Attrape-scam (nouveau)
### 6. Anti-raid — modules basic
### 7. Sélecteur de rôles — images embed
### Déploiement
- Contexte : erreur ❌ Une erreur est survenue en modifiant le salon d'envoi (arrivée/départ).
- Cause : cfg:field:chan:<section>:<id> mal parsé (chan pris pour action).
- Changement : branche dédiée b === "chan" avant le parsing générique des champs.
- Fichiers : bot-public/src/handlers/config/router.js
- Contexte : boutons et textes en dur (« Autorisé », modales, reset…).
### 1. Attrape-scam — activation
### 2. Anti-URL — http/https et domaines
### 3. UI anti-raid unifiée
### 4. Bot secondaire vocal
### 5. Sélecteur de rôles — Modifier
### Déploiement
- Cause : if (a === "scam") interceptait aussi scam:toggle et scam:delmsg.
- Changement : route scam:cfg pour la page ; toggle fonctionnel ; actif avec salons configurés même sans anti-raid global.
- Fichiers : routerSecurity.js, securityConfig.js
- Changement : listes autorisés + interdits ; option bloquer HTTP ; matching sous-domaines.
- Fichiers : antiRaidModules.js, antiRaidRuntime.js, panelsSecurity.js, routerSecurity.js, securityModals.js
- Changement : 3 pages dans Anti-raid (Général / Membres / Admin), boutons Configurer, pagination.
### 1. Musique — files indépendantes par bot + radio
### 2. /config — navigation directe
### 3. /pickup — User Install
### 4. /userinfo et /serverinfo
### Déploiement
- Contexte : deux bots vocaux jouaient la même file ; /radio devait suivre la même logique de délégation.
- Changements : clé file ${voiceGroup}:${guildId} ; panneau lecteur sans bouton Play ; /play envoie le lecteur dans le chat du salon vocal ; /lecteur pour le réafficher ; playlists YouTube dans /play ; /music supprimée.
- Fichiers : musicManager.js, musicPanel.js, musicSlashHelpers.js, radioManager.js, radio.js, secondaryBot.js, lecteur.js, commandes musique (play, skip, pause, …), interactionCreate.js, commandSync.js
- Changement : option section (auto, admin, sécurité, notifications, rôles, pseudos, messages, réactions).
- Fichiers : commands/owner/config.js
### 1. /signalement — bouton Ignorer
### 2. /lecteur — aucune musique en cours
### 3. /serverinfo — bot absent du serveur
### 4. Sélecteur de rôles — 2ᵉ configuration
### 5. Sélecteur — mode réactions
### 6. Sélecteur — container vs message simple
### Déploiement
- Changement : le signalement est supprimé de reports.json au lieu d'être marqué ignoré.
- Fichiers : reportsStore.js, reportHandler.js
- Changement : message explicite si rien ne joue ; invite à rejoindre un vocal et utiliser /play morceau:….
- Fichiers : musicSlashHelpers.js
- Cause : guild.members.fetch() sur un guild où le bot n'est pas membre.
- Changement : garde-fous ; infos limitées (nom, ID, icône, badges) + mention si le bot n'est pas installé.
### Contexte
### Changements
### Liens
### Fichiers
- Demande d'un lien d'installation User Install avec permissions maximales pour tester l'app sur le compte utilisateur.
- Configuration API Discord integration_types_config : User Install (applications.commands), Guild Install (bot + admin).
- Script bot-public/scripts/print-install-links.js (liens serveur, compte, OAuth étendu).
- Doc bot-public/docs/USER_INSTALL.md.
- Page web/src/app/discord/bot : boutons Installer sur mon compte et Install + OAuth ; i18n FR/EN.
- User Install : integration_type=1&scope=applications.commands
- OAuth étendu : identify, email, guilds, guilds.members.read, connections, applications.commands
- bot-public/scripts/print-install-links.js, bot-public/docs/USER_INSTALL.md
- web/src/app/discord/bot/page.tsx, web/messages/discordBot/fr.json, web/messages/discordBot/en.json
### Contexte
### Changements
### Fichiers
- Demande d'inclure tous les scopes OAuth possibles (guilds.join, gdm.join, rpc, voice, etc.), même partenaires/inutiles.
- ALL_OAUTH_SCOPES (27 scopes) dans print-install-links.js.
- Lien User Install étendu et lien serveur « nucléaire » mis à jour.
- Page /discord/bot + doc USER_INSTALL.md.
- bot-public/scripts/print-install-links.js, bot-public/docs/USER_INSTALL.md
- web/src/app/discord/bot/page.tsx, web/messages/discordBot/fr.json, web/messages/discordBot/en.json
### Cause
### Correction
### Fichiers
- integration_type=1 n'accepte que applications.commands (pas identify/guilds/gdm.join dans la même URL).
- Mélange 27 scopes + User Install → erreur Discord.
- 2 liens : User Install (étape 1) + OAuth compte sans integration_type (étape 2).
- bot-public/scripts/print-install-links.js, bot-public/docs/USER_INSTALL.md
- web/src/app/discord/bot/page.tsx, web/messages/discordBot/fr.json, web/messages/discordBot/en.json
### Lien unique
https://discord.com/oauth2/authorize?client_id=1431308308505039069&integration_type=1&scope=applications.commands
### Fichiers
- bot-public/scripts/print-install-links.js, bot-public/docs/USER_INSTALL.md
- web/src/app/discord/bot/page.tsx, web/messages/discordBot/fr.json, web/messages/discordBot/en.json
### Contexte
### Changements
### Impact
### Fichiers
- Demande de recréer /rpc après suppression (2026-07-04) pour personnaliser l'activité Discord : nom, description, image, boutons (label + URL).
- OAuth RPC déjà associé au compte (scopes rpc.activities.write, activities.write, presences.write).
- /rpc : commande globale User Install + panneau Container V2 (type, texte, image URL, 2 boutons, chrono).
- Stockage data/user-rpc/<userId>.json + file data/user-rpc-queue/<userId>.json.
- Handlers urpc:* (boutons, modales, sélecteur type).
- rpcPresence.js : construction payload SET_ACTIVITY + tentative IPC local (discord-rpc).
- scripts/rpc-local-bridge.js : pont à lancer sur le PC avec Discord ouvert (poll API interne).
- API interne : GET /internal/rpc/queue/:userId, POST /internal/rpc/ack/:userId.
### Contexte
### Changements
### Impact
### Fichiers
- Clic « Appliquer » : config sauvegardée en file mais panneau ne se mettait pas à jour (utilisateur voit « rien »).
- OAuth seul ne pousse pas la présence sur le profil sans pont RPC local.
- rpc.js : interaction.update() à la place de deferUpdate + editReply (Containers V2) ; modales mettent à jour le panneau existant.
- Message explicite après Appliquer avec commande pont PC + secret.
- userRpc.js : bridge_secret par utilisateur.
- web/src/app/api/rpc/bridge/route.ts : API HTTPS GET/POST pour le script pont local.
- rpc-local-bridge.js : support BOT_BRIDGE_URL + RPC_BRIDGE_SECRET.
- Timeout 2,5 s sur tentative RPC IPC serveur.
- Le panneau réagit au clic Appliquer avec instructions claires.
- L'activité profil Discord nécessite Discord Desktop + script pont sur le PC de l'utilisateur.
### Contexte
### Changements
### Impact
### Fichiers
- Demande d’une commande communautaire fournissant le lien d’invitation du bot avec 0 permission (pas admin), en User Install, avec container propre.
- /invite-bot : commande globale User Install + Guild Install ; panneau Container V2 (avatar, lien, boutons Link).
- Lien serveur : permissions=0, scope bot + applications.commands.
- Bouton secondaire User Install (applications.commands seul).
- lib/botInvite.js : helpers URL ; print-install-links.js : lien 0 permission documenté.
- N’importe qui peut récupérer le lien d’invitation minimal du bot via /invite-bot (DM, serveur, app installée).
- bot-public/src/commands/util/invite-bot.js
- bot-public/src/lib/botInvite.js
- bot-public/src/lib/{commandSync.js,moderation/guard.js}
### Contexte
### Cause
### Changements
### Impact
### Fichiers
- Après User Install + invitation serveur 0 permission : commandes peu visibles sur mobile, traduction/signalement/blacklist inaccessibles ou cassés.
- User Install ≠ bot sur serveur : deux installations distinctes.
- Mobile : commandes dans onglet Applications, pas « Bots du serveur ».
- Bot serveur 0 permission : ne peut pas lire les messages → /translate et menus contextuels inopérants.
- /bl et /signalement réservés aux propriétaires du bot.
- deploy-commands.js : déploiement global toujours (plus de remplacement si DISCORD_GUILD_ID).
- invite-bot : lien serveur recommandé (permissions minimales) + aide mobile + avertissement 0 perm.
- botInvite.js : buildGuildInviteRecommendedUrl() (voir salon, lire, répondre).
### Contexte
### Cause
### Changements
### Impact
### Fichiers
- User Install actif mais bot retiré du serveur : plus de commandes visibles sur mobile.
- Normal : le bot absent du serveur ≠ app désinstallée du compte.
- 10 commandes musique (guild-only) polluaient le déploiement global User Install.
- Réinstallation User Install souvent nécessaire après retrait du bot.
- Global réduit à 14 commandes User Install (translate, help, install, etc.) ; musique déplacée en GUILD_ONLY_COMMAND_NAMES (sync par serveur).
- Nouvelle commande /install : panneau réinstallation compte + lien DM bot + aide mobile.
- Doc USER_INSTALL.md mise à jour (DM, Apps, bot hors serveur OK).
- Liste User Install plus claire sur mobile.
- Lien DM : https://discord.com/users/1431308308505039069
### /blacklist (remplace /bl)
### Commandes personnalisées (soft)
### Ressources site → salons forum Discord (bot-site)
### Open Graph ressources
- Contexte : fusion des sous-commandes /bl add|remove|list en une seule commande avec choix d'action.
- Changements : nouvelle commande /blacklist avec options action (Ajouter / Retirer / Liste), utilisateur ou identifiant obligatoire pour add/remove, temps et raison pour l'ajout. Suppression de bl.js.
- Impact : propriétaires du bot utilisent /blacklist (global User Install). Déploiement global mis à jour (14 commandes).
- Fichiers : bot-public/src/commands/owner/blacklist.js, deploy-commands.js, interactionCreate.js, help.js, invite-bot.js
- Contexte : bouton « Ajouter (bientôt) » inactif dans /config > Administration.
- Changements : modal création (nom, message, visibilité public/ephemeral), stockage admin.custom_commands, sync guild des slash custom, exécution dans interactionCreate.
### Contexte
### Cause
### Changements
### Fichiers
- Le bot ne se connectait plus à Discord après les changements forum ressources.
- Import incorrect dans siteResourceForum.js : ../../lib/logger.js → chemin bot-public/lib/logger.js (inexistant).
- Correction import → ./logger.js.
- Redémarrage bot-public : connexion OK (LB'XMB.FR#3591, 4 serveurs).
- bot-public/src/lib/siteResourceForum.js
- docs/RECAP-TRAVAIL-COMMUNAUTE-2026-04.md
### Contexte
### Cause
### Changements
### Impact
### Fichiers
- Connexion via Discord impossible sur https://lbxmb.fr (Better Auth invalid_client).
- PM2 conservait un ancien DISCORD_CLIENT_SECRET (e4DuS8…) qui écrasait la valeur correcte de web/.env.local (oG8LO…).
- server.js : relecture forcée des clés OAuth depuis .env.local au démarrage.
- Redémarrage web-prod avec --update-env après sourcing .env.local.
- OAuth Discord fonctionnel en production (secret client valide côté Discord API).
- web/server.js
- docs/RECAP-TRAVAIL-COMMUNAUTE-2026-04.md
### 1. Base jeux partagée (sans IGDB)
### 2–4. Fiche produit boutique (garanties + options + prix)
### 5. Accueil — profil Default.xex
### 6. Connexions OAuth (scope + dernière connexion)
### 7. Navbar notifications + mobile
### 8. Boutique mobile — liste
### 9. Ticket partenariat — formulaire dédié
### Impact / déploiement
- Contexte : même UX « nouveau jeu » (nom + icône) pour ressources, guides et boutique.
- Changements : table shared_games, API GET/POST /api/shared-games, composant SharedGamePicker (recherche + création).
- Intégration : formulaires ressources (ajouter), guides (ajouter), boutique (BoutiqueProductForm).
- Fichiers : web/src/lib/shared-games.ts, web/src/app/api/shared-games/route.ts, web/src/components/shared/SharedGamePicker.tsx, web/src/app/ressources/ajouter/page.tsx, web/src/app/guides/ajouter/page.tsx, web/src/components/boutique/BoutiqueProductForm.tsx
### Contexte
### Cause
### Changements
### Fichiers
### Impact
- Sur un serveur, /userinfo → Cannot read properties of null (reading 'members') ; /serverinfo → « Impossible de charger ce serveur ».
- Commandes User Install : interaction.inGuild() vrai mais interaction.guild souvent null (seul guildId est fourni). Accès direct à interaction.guild.members.
- Helper resolveInteractionGuild : fetch via client.guilds.fetch(guildId) si interaction.guild absent.
- /serverinfo et /userinfo utilisent ce helper ; garde-fous sur guild.members / guild.channels.
- Try/catch sur /userinfo.
- bot-public/src/lib/resolveInteractionGuild.js
- bot-public/src/commands/util/serverinfo.js
- bot-public/src/commands/util/userinfo.js
### Contexte
### Changements
### Fichiers
### Impact
- Besoin d'un lien OAuth unique (identify, applications.commands, guilds.join, relationships.write) pour login, liaison, vérification et User Install.
- Lors d'une blacklist bot : bloquer l'utilisateur pour tous les comptes Discord ayant autorisé l'application ; prévenir la personne avec la raison et comment se débloquer dans les paramètres Discord.
- Module central discord-oauth.ts : scopes + builders d'URL (login, liaison, vérification, User Install).
- Better Auth Discord, prepare-link, /api/verify/discord/authorize, page bot : scopes étendus + integration_type=1 où pertinent.
- Module discord-relationships.ts : blocage/déblocage via API Discord relationships.write (refresh token, parcours table account).
- API interne POST /api/internal/discord/blacklist-relationships (bot → site).
- Commande /blacklist : appelle la propagation relations à l'ajout/retrait ; MP mis à jour (raison + déblocage via Paramètres utilisateur → Bloqués).
### Contexte
### Changements
### Fichiers
### Impact
- Quand 1139951514694193323 rejoint ou change de salon vocal, alerter 1398073346175926272 en MP avec le lien du vocal — uniquement si les deux sont sur le même serveur.
- Module voiceJoinAlert.js : détection voiceStateUpdate, vérif membre commun via guild.members.fetch, lien https://discord.com/channels/{guild}/{channel}, cooldown 45 s par salon.
- bot-public/src/lib/voiceJoinAlert.js
- bot-public/src/events/guild/voiceStateUpdate.js
- docs/RECAP-TRAVAIL-COMMUNAUTE-2026-04.md
- bot-public à redémarrer.
### 1. Commandes personnalisées
### 2. /invite-bot
### 3. /signaler
### 4. Ajout bot sur serveur
### 5. Contestations ban/blacklist
### 6. /base64
### 7. /help
### 7b. /help — menu déroulant par catégorie
### Fichiers
- Création : nom uniquement → bouton Configurer (message + rôles/utilisateurs).
- Suppression du choix public/éphémère ; autorisations dans la config ; scope serveur inchangé.
- Réponse visible (non éphémère) ; boutons Ajouter au serveur + Ajouter à mon compte ; container features.
- Raison Autre → modale obligatoire pour préciser.
- MP container au propriétaire (merci, /help, /config, features).
- Une contestation par sanction ; owner serveur reçoit DM + bouton Débannir ; user prévenu avec lien d'invitation si accepté.
### Contexte
### Règles
### Changements
### Fichiers
### Impact
- Expulser (kick, pas ban) les membres totalement inactifs sur le serveur LB'XMB, avec MP avant expulsion et lien de réinvitation.
- 30 jours : aucun message, vocal, sondage et connexion (online/idle/dnd) → expulsion.
- 90 jours : aucun message, vocal ni sondage (statut en ligne ignoré) → expulsion.
- Grâce 14 jours après l'arrivée sur le serveur ; bots et owners bot exemptés ; rôles exemptés via REGULARIZATION_EXEMPT_ROLES.
- bot-public : index d'activité partagé data/member_activity/<guildId>.json (messages, vocal, sondages /sondage, présence en ligne).
- bot-site : évaluation quotidienne (~03:15 Paris), MP d'expulsion puis kick, log data/regularization/kicks.json, route manuelle POST /regularization/run (auth x-api-key).
- bot-public/src/lib/memberActivity.js
- bot-public/src/events/message/messageCreate.js
### Contexte
### Changements
### Fichiers
### Impact
- Les commandes /translate, menu « Translate this message » et bouton auto-traduction renvoyaient du texte brut, même pour les messages en embed ou container Components V2.
- Module translateMessageLayout.js : détecte embed/container, traduit chaque bloc de texte (titres, sections, boutons, champs embed…), reconstruit le layout Discord traduit avec le footer de traduction intégré.
- Branchement dans translate.js et autoTranslationHandler.js ; repli sur texte simple si pas de structure.
- bot-public/src/lib/translateMessageLayout.js
- bot-public/src/commands/util/translate.js
- bot-public/src/handlers/autotranslation/autoTranslationHandler.js
- docs/RECAP-TRAVAIL-COMMUNAUTE-2026-04.md
- Traduction visuelle fidèle pour containers (help, invite, panels…) et embeds classiques.
- Redémarrer bot-public.
### 1. Compteur ressources PS3 (45 vs 42)
### 2. Boutique profil
### 3. OAuth Google / GitHub
### 4. Chat staff — messages vocaux
### 5. Logs Discord staff
### 6. Page /cloud
### 7. Accueil — créateurs
### 8. GitHub repo (ajout ressource)
### Fichiers
- Cause : sidebar comptait les ressources multi-catégories plusieurs fois.
- Fix : décompte distinct resource_id par plateforme dans /api/resources/structure.
- Composant partagé ProductCard (taille profile, grille plus dense).
- Liaison unifiée via link-social (profil + paramètres).
- Finalisation POST /oauth-providers/link au retour Google/GitHub.
- Sync photo OAuth à chaque session.
- Ressource « Xb Homebrew Vault » (Xbox One + Series) : étiquette console n’affichait que Xbox One ; bouton « Visiter » grisé au lieu de « Télécharger ».
- Cause : catégorie « Site » ajoutée par erreur (basculage URL / GitHub) alors que les fichiers sont hébergés localement ; isSiteResource traitait Tools+Site comme ressource site.
- Données corrigées (resource_id 218) : retrait de « Site » dans categories_by_console_json + structure.json.
- isSiteResource : ignore la catégorie Site si des téléchargements locaux existent ; helper stripSiteCategoryUnlessUrlOnly à l’ajout.
- Fiche détail : fusion consoles déclarées + téléchargements ; libellés getPlatformDisplayName (Xbox One · Xbox Series X/S).
- Liste ressources : consoles multiples affichées avec noms lisibles.
- Formulaire ajout : mode Fichier retire la catégorie Site ; sync GitHub ne force plus le mode URL.
- Xb Homebrew Vault téléchargeable via modale ; Xbox One et Series visibles sur la fiche et dans les listes filtrées.
- Changelogs : entrées récentes en bas de page (scroll long).
- Fiche ressource : colonne droite (télécharger / actions) ne restait pas visible au scroll.
- Connexion Discord : flux guild install (ajout bot serveur) au lieu de user install.
- Login : emoji main CDN (waving-hand) affiché en texte.
- Modal téléchargement : regroupement auto exe→Windows, etc.
- Accueil : interverti absent à côté de Default.xex (featured-home filtrait user_id avec des IDs Discord).
- /changelogs : tri par date décroissante (plus récent en haut).
- ResourceDetailClient : aside droite lg:sticky lg:top-24.
- OAuth login Discord → /api/auth/discord/user-install (integration_type=1).
- Login : emoji Unicode 👋 (plus de dépendance CDN Apple emojis).
- Passage automatique bot-site a expulsé ~600 membres avec l'ancienne logique (30 j « full » ou 90 j partiel en OU).
- Règles attendues : expulsion uniquement si toutes les conditions sont remplies après 3 mois ; exception 6 mois en ligne sans activité ; compteur hors ligne reset à la reconnexion ; guilde 1232966743241130005 seule.
- evaluateMemberInactivity v2 : AND (hors ligne 90 j + jamais message + jamais réaction + jamais bouton/menu) OU exception en ligne 180 j sans activité.
- memberActivity.js (bot-public) : offline_since, pending_*_since, tracking_started_at ; présence reset offline ; réactions + interactions composants trackées.
- Guilde forcée REGULARIZATION_GUILD_ID=1232966743241130005 ; membres sans tracking_started_at ignorés (pas de rétroactif).
- Config : REGULARIZATION_STANDARD_DAYS=90, REGULARIZATION_ONLINE_IDLE_DAYS=180.
- Plus d'expulsion en masse sur critères trop larges ; compteurs repartent au prochain événement présence/activité par membre.
- Clarification : sondages, réactions, messages, vocal, rôles d'accueil et commandes bot doivent compter comme participation.
- recordParticipationFromInteraction : slash, menus contextuels, boutons, selects, modales.
- Vocal (bumpMemberVoice) : annule aussi le compteur « jamais interagi » + règle 6 mois.
- Rôles d'accueil : réactions + boutons/select cfg:rolepick déjà couverts.
- Un membre actif sur le serveur (même sans message) n'est plus considéré inactif sur le critère interaction s'il passe en vocal ou utilise une commande.
- bot-public/src/lib/memberActivity.js
- bot-public/src/events/interaction/interactionCreate.js
- docs/RECAP-TRAVAIL-COMMUNAUTE-2026-04.md
### Attrape-scam : DM avant ban
### Connexion Discord cassée
### Mobile : drawers ressources/forum + menu hamburger
### Ressources : tri + import GitHub
### Discord : login vs User Install
### Service Worker
### Traductions
### Flux login → User Install automatique
- Après connexion Discord BetterAuth, redirection vers /auth/discord-complete puis /api/auth/discord/user-install (lien applications.commands + integration_type=1, redirect /discord/bot).
- Cookie lbxmb_user_install_return + retour accueil après callback OAuth User Install.
- Login API prod : scopes identify+guilds.join+relationships.write (sans applications.commands).
### Session site cassée par enchaînement OAuth trop rapide
- Login Discord : callbackURL = / (session créée d'abord).
- Flag lbxmb_post_login_user_install + composant PostLoginDiscordUserInstall : attend getSession() puis redirige vers User Install.
- User Install : prompt=consent pour afficher « créer des commandes » (applications.commands).
- /auth/discord-complete : simple redirect / (rétrocompat).
### Connexion site + applications.commands en un seul OAuth
- Plugin BetterAuth discordUserInstallLoginPlugin : force integration_type=1, scopes identify+relationships.write+applications.commands+guilds.join, prompt=consent, URL discord.com/oauth2/authorize.
- Suppression enchaînement post-login (PostLoginDiscordUserInstall).
### OAuth Discord rejeté par l'API (invalid_scope)
- Login User Install : scopes identify + applications.commands uniquement (integration_type=1).
- errorCallbackURL → /login?error=oauth + affichage error_description.
### Changelogs ressources : markdown Discord
### Mobile : z-index panneaux vs header
### Navbar : texte LB'XMB.FR mobile
### Paramètres : pays / langue en boucle
### Messagerie mobile : composer, menus, bottom nav
- FloatingMessagePanel : bottom: 0 en conversation, 4rem en liste.
- MessageComposerBar : padding réduit en mode embedded mobile.
- Menu contextuel mobile : z-[10060]/[10061].
- openMobilePanel() : un seul panneau (messagerie / notifs / profil / recherche).
- Bottom nav masquée en conversation (onInConversationChange).
### Cheat Code sur toutes les consoles
### Tools : sous-catégorie Store
### Bot Discord : /stop + doublons vocal
### Stripe : moyens de paiement Dashboard
### Photo de profil invisible après upload
### Forum : scroll sidebar sujets
### Messagerie PC plein écran
- resolveVoiceBot : réutilise le bot déjà dans le salon ; secondaire uniquement si enregistrement actif.
- /stop : arrêt musique + radio sur les deux groupes (stopAnyMusic + stopAnyRadio).
- musicManager.connect : réutilise getVoiceConnection existante.
### Stripe Checkout : automatic_payment_methods rejeté
### Traduction manquante forum.catAnnounce
### Annonces forum → Discord (#annonces)
### Forum : menu tags (mobile Dialog)
### bot-public /config : dropdown Notifications
- bot-site : POST /forum/announcement-post — webhook nom/avatar auteur, embed contenu, réactions 👍❤️👎, thread « Commentaire », menu traduction.
- Mapping forum_sync_mapping.json mis à jour.
- Web : appel direct bot-site au lieu de commands.json.
- bot-public : handler forum_web_tr:* pour traduction éphémère (LibreTranslate).
### bot-public : crash au démarrage (import LibreTranslate)
### /sondage : boutons alignés sur les choix
### /config Administration : sondages + giveaways
### Statistiques serveur (gstats) : options simplifiées
- Section Sondages : rôles/utilisateurs autorisés à lancer et clôturer ; rôle ping à la publication.
- Section Giveaways : permissions création / participation (prête pour /giveaway).
- Schéma serveur : poll, giveaway dans serverConfig.
- /sondage respecte les permissions config (lancer, clôturer, ping rôle).
- Cibles : Nom du serveur ou Nom d'un salon vocal.
- Statistiques : utilisateurs, bots, salons, rôles, membres avec rôle (sélecteur rôle si besoin).
- Compteurs {channel.count} et {role.count} ajoutés au moteur.
### Module tickets absent de /config
- Section 🎫 Tickets ajoutée dans /config → Système automatique.
- Config multi-panneaux : activation, types de tickets, mode threads/catégorie, interface boutons/menu, embed, publication du panneau.
- Runtime : ouverture ticket (thread ou salon), bouton fermer, permissions staff par type.
- Schéma tickets dans serverConfig (compatible structure Python configurations).
### Rôles par action : retrait si statut retiré
### Tickets : staff, menus section, transcript, couleurs boutons
### Commande /giveaway
### Statistiques serveur : renommer + texte affiché
### Photo profil site
### Forum : scroll sujets
- Rôles staff = seuls rôles avec accès (salon catégorie ou thread privé).
- Interface Menus par section (jusqu'à 5 menus × 25 options).
- Transcript HTML à la fermeture.
- Couleur bouton via style=success dans description du type.
### /giveaway sans sous-commandes
### Sync commandes Discord cassée
### Sondage : participants et détail des votes
### Boutons Retour containers
### Tickets : prise en charge + ajouter staff
### Tickets : template nom salon + reset menus
- Bouton Prendre en charge (seul le staff assigné écrit).
- Menu Ajouter un staff après prise en charge.
- Mode staff non assigné : masqué (perd accès) ou lecture seule (configurable).
- Guard messages pour threads/salons.
- Template {ticket.emoji}, {user.id}, {date}, etc. (comme vocaux temp).
- Config via /config → Tickets → Modifier (template nom).
- Menus déroulants du panneau réinitialisés après sélection.
### Tickets : boutons complémentaires activables
### Signaler un message (menu contextuel)
- Prise en charge et Ajouter un staff désactivés par défaut — à activer dans /config → Tickets.
- Toggle séparé pour « Ajouter un staff » (nécessite prise en charge activée).
- Clic droit sur un message → Signaler → modale (contexte obligatoire).
- /signalement affiche : contenu intégral, auteur, signaleur, lien, PJ, explication.
- Loader commandes corrigé pour menus User + Message même nom.
### Crash à la création (reading 'cache')
### Ordre des rôles inversé à la restauration
- Filtre des salons sauvegardables (catégories, texte, vocal, forum… — pas les threads).
- Sérialisation overwrites avec permissionOverwrites?.cache.
- Fetch salons + garde-fous membres / @everyone.
- Création des rôles du plus haut au plus bas (hierarchy_rank desc).
- Réordonnancement via hierarchy_rank relatif (bas → position 1, haut → sous le bot).
### Republication panneau tickets à la restauration
### Statistiques serveur dynamiques (rôles / membres)
### Paramètres communauté dans la backup
### Config /config adaptée au nouveau serveur
- Comptage via role.members.size.
- Remap role_id, channel_id et placeholders {role.member.count:ID} dans les templates.
- Reset last_applied à la restore ; recalcul forcé (force: true).
### Éditeur tickets ne répondait plus
- Boutons compacts (2 rangées) à la place de 7 sections lourdes.
- Sous-page Types / menus pour supprimer des types et gérer les menus section.
### Durée / fin de sondage requise
- Champ Durée obligatoire dans la modale « Question / description » (30m, 2h, 1d…).
- Publication bloquée sans durée valide (min. 1 min, max. 30 jours).
- Affichage de la fin sur le sondage publié + clôture automatique à l'échéance.
- Reprise des timers au redémarrage du bot.
### Mode de fermeture configurable
- Option À la fermeture dans /config → Tickets : supprimer (comportement actuel) ou verrouiller (lecture seule).
- Mode verrouiller : retire l'écriture pour tout le monde, conserve le salon/thread.
- Bouton Fermer devient Réouvrir quand le ticket est verrouillé.
- Guard messages bloque toute écriture sur ticket verrouillé.
- Un ticket verrouillé ne bloque plus l'ouverture d'un nouveau ticket par le même membre.
### Cause : crash bot-public au démarrage
- Fix SyntaxError: Export 'WELCOME_VARIABLE_HELP' is not defined dans panelsV2.js (ré-export sans import).
- Restauration DISCORD_TOKEN vide dans .env racine (cassait aussi bot-python / API Discord site) + sync bot/config.json.
- start_bot.sh : ignore un DISCORD_TOKEN vide pour ne pas masquer config.json.
- pm2 restart bot-public + pm2 save (autostart reboot déjà via pm2-root.service).
- bot-python laissé stopped (même application Discord que bot-public → conflit de session).
### 1. /config — panneau d'accueil unifié
### 2. /signaler + menus contextuels unifiés
### 3. Panneau vocaux temporaires
### 4. Sécurité — pause invitations & MP inconnus
- Accueil = container accent coral (#ff5e5b) + texte « Panneau de Configuration » + select « Configurer une option ».
- 15 options (messages, rôles, pseudos, traduction, threads, tempvoice, tickets, stats, réactions, inter-salon, logs, protection, notifications, commandes, profil bot) avec descriptions corrigées.
- Routing cfg:home:feature vers les panels existants.
- Fix bug c → container sur Giveaways/Logs de la page Admin.
- Modal unique (Labels V2) : select raison + description (obligatoire si « Autre ») + File Upload (jusqu'à 5 fichiers).
- /signaler, App → Signaler (user) et Signaler (message) utilisent le même modal.
- Oui : Discord permet désormais d'importer des pièces jointes dans un modal (FileUpload).
### Retours /config → accueil unifié
### Logs — échec d'interaction
### Légende vocaux temporaires
- Tous les hubs (admin, logs, notifs, profil, rôles, etc.) → cfg:nav:home (nouveau panneau select).
- Suppression page Admin catégorie + menu « Changer de catégorie » + ancien panels.js inutilisé.
- Anciens liens nav:page:* / home:nav redirigés vers l'accueil.
### Légende vocal temporaire — emojis nets
### Logs serveur — structure catégorie / forum
- Schéma logs aligné Python : type text|forum, enabled_types, channels / threads, category_id / forum_id.
- UI : Activer · bascule Mode · Créer la structure · toggles catégories + événements fins.
- sendGuildLog route vers le salon/thread du bucket (join, message, vocal, server, moderation, verification, antiraid) ; fallback legacy channel_id.
### Vocal temporaire — image légende utilisateur
### Logs — UX structure
- Instructions en 4 étapes + bouton dédié « Créer la catégorie + salons » / « Créer le forum + posts ».
- setupLogsStructure active automatiquement les logs si besoin.
- Affiche les salons/posts liés par catégorie une fois créés.
### /config → Connexion API / RCON
### Commandes custom — boutons modal → RCON
- Nouvelle section home « Connexion API/RCON » : activer, éditer hôte/port/mdp, tester, salon journal, joueurs, infos (seed/temps/list), exécuter une commande console.
- Client rcon-client ; sorties optionnellement miroirées dans un salon Discord (pas de stream console live — RCON = requête/réponse).
- Éditeur commande : format simple/container/embed, Liste RCON (rcon_prefetch → {rcon_result}), Ajouter bouton (label, titre modal, 1–2 champs, templates RCON une ligne = une commande).
- Runtime : boutons ccmd:act: ouvrent un modal ; chaque ligne RCON ne s’exécute que si ses {variables} sont remplies (ex. pseudo seul → whitelist add, IP seule → ipwhitelist add).
### Connexion API/RCON — liste de providers
### Commandes dédiées /mcwhitelist et /mc-player
### Salon console bidirectionnel
### Infos + Paramètres serveur
- Sync guild uniquement si RCON Minecraft est prêt (activé + provider + identifiants).
- /mcwhitelist : modal pseudo + IP optionnelle *(plugin ipwhitelist)*.
- /mc-player : liste en ligne → panneau joueur (cœurs, faim, XP, inventaire, kick/ban/clear, gamemode, TP joueur ou coords).
### /config cassé
### Logs — bucket Tickets
- Nouveau bucket tickets + événements : ouverture, prise en charge, staff ajouté, fermeture, verrouillage, réouverture, transcript (fichier HTML joint).
- sendGuildLog accepte des pièces jointes.
- « Créer la structure » crée seulement les salons/posts manquants (ex. salon Tickets) sans tout recréer.
### Connexion cassée / callbacks Discord
- Scopes User Install unifiés (comme le générateur Discord) : identify + applications.commands + messages.read + guilds.join + relationships.write + integration_type=1.
- Login BetterAuth → https://lbxmb.fr/api/auth/callback/discord (redirectURI explicite).
- Vérification → https://lbxmb.fr/api/verify/oauth/callback (authorize + token exchange).
- Erreurs Discord (invalid_scope, etc.) redirigées vers /login?error=oauth avec error_description (évite « State not found » opaque).
- HEAD sur callback auth → 200 (sondes portail Discord).
### Whitelist IP Minecraft (par serveur Discord)
### Miroir console Minecraft → Discord
### Vérification — overwrites salons
### Tickets — séparateur ・
### /friends
1. Redirect erreur utilisait request.url origin → https://0.0.0.0:25581 (hostname d'écoute Next).
2. Scopes User Install (messages.read + integration_type=1 + relationships.write) → invalid_scope.
- Redirects OAuth → toujours BETTER_AUTH_URL / https://lbxmb.fr.
- Login : identify + relationships.write + guilds.join sans integration_type.
- User Install bot : identify + applications.commands + integration_type=1 (séparé).
- Imports corrigés vers ../../lib/....
- /friends ajouté aux PUBLIC_COMMANDS.
- Bot redémarré (API /health OK, 8 guilds).
- Étape 1 login : identify + relationships.write + guilds.join + messages.read (sans integration_type).
- Après session → /auth/discord-complete → User Install applications.commands + integration_type=1 (MP + créer commandes).
- Verify : scopes login (token user), plus User Install seul.
- Flag minecraft.ip_whitelist_enabled (défaut OFF) — toggle dans /config → Minecraft (Whitelist IP : ON/OFF) et /mcwhitelist.
- Autorisation si IP ou pseudo listé ; sinon kick Vous n'êtes pas whitelist discord.gg/lbcs.
- Parse des lignes console (Steve[/ip:port] logged in…) via API /internal/minecraft/console + messages du salon console Discord → kick RCON.
### Fix : config minecraft ignorée au chargement
- Scan RCON list à l'activation + toutes les 20s si whitelist ON → kick les pseudos non autorisés.
- Message console Discord pour chaque kick.
- Templates ipwhitelist / whitelist+{ip} / mcipwhitelist → stockent dans la DB bot (addMcIpWhitelist), sans commande RCON.
- Config serveur mise à jour + entrée .Jessybarden0710 / 88.163.181.14 migrée.
- Placeholder /config custom boutons : mcipwhitelist add {pseudo} {ip}.
- Intervalle scan 2,5 s (premier scan ~0,8 s).
- list + kick sur une seule session RCON.
- Messages Discord non bloquants ; cache des guilds whitelist ON.
- Asset assets/tv-legend.png (et .jpg) remplacé par l’image fournie.
- Boutons Discord réordonnés en grille 4×2 alignée sur la légende (✉️ pour Transférer).
- Cookies Better Auth crossSubDomainCookies domain .lbxmb.fr
- Nginx : www.lbxmb.fr → 301 https://lbxmb.fr
- Proxy Next + composant client : redirection www → apex
- Message login : affiche aussi state_mismatch s’il est dans l’URL
- Grille 2 lignes × 4 boutons (Modifier · Limite · Invité · Expulsé / Accès · Perms · Transférer · Récupérer)
- ➕ Invité = vert (Success), ➖ Expulsé = rouge (Danger), Transférer + Claim = bleu (Primary)
- Sync télécharge les assets puis réécrit variantes via buildVariantesFromGithubAssets (chemins locaux sous releases/{tag}/)
- Noms d’affichage telechargements = nom d’asset courant (plus de nom figé)
- resolveVoiceBot : si le principal est occupé ailleurs (musique/radio/record) → secondaire ; si les deux occupés → busy + message
- connect musique/radio : refuse de réutiliser une connexion d’un autre salon
- /play, /playlist, /radio, lecteur : refus explicite si bots déjà utilisés
- /skip + bouton ⏭️ : vote majoritaire des humains du vocal (skip immédiat si seul)
- Parseur d’URL : hosts arbitraires, suffixe /releases ignoré, page org (1 segment) résolue via API
- Client releases : GitHub + Gitea/Forgejo (/api/v1), User-Agent anti-Anubis
- Sync / autofill / téléchargement d’assets branchés sur ce client
- Libellés UI FR/EN mis à jour ; alerte si dépôt sans assets de release
- Catégorie Online ajoutée pour Nintendo Switch et Switch 2
- Jeu optionnel pour les mods (plus de validation bloquante)
- Sélection multi-jeux (jusqu’à 12) : structure.json.jeux + colonne jeux_json, jeu = premier pour chemins/compat
- Filtres / sidebar / détail tiennent compte de tous les jeux liés
- Login Discord uniquement ; providers Google/GitHub retirés de Better Auth
- Section « Comptes associés » retirée du profil
- Soft-delete de 49 comptes sans discord_id
- Scopes unifiés : identify guilds.join relationships.read applications.commands (messages.read exclu)
- Page /commencer + API : intro → OAuth → consoles/notifs → rôles Discord
- Garde IP : VPN/proxy/hosting/mobile + whitelist Orange/Free/Bouygues/SFR + 1 IP = 1 compte
- Panneau salon 1528633918280962179 (Translate + lien Commencer) via bot-site ; handler Translate dans bot-public
- Groupes UI explicites : Nintendo, PlayStation, Xbox, Autres (liste basée sur RESOURCE_FORM_CONSOLES)
- Ajout d’icônes console via imageId (/api/consoles/images/<imageId>.png)
- Auto-redirection OAuth Discord dès que /api/commencer renvoie authenticated=false (sauf cas error=oauth)
- BetterAuth (login Discord) : ajout de guild_id dans l’URL OAuth générée
- User Install : ajout de guild_id dans les URLs integration_type=1
- Création de la commande /warn-kick (bot-public) : envoie un message avec boutons Je veux rester (vert) + Translate
- Translate (bot-public) : traduit le contenu de l’embed via LibreTranslate selon la locale Discord (bouton non expirant)
- Etat persistant (bot-site) : stockage sur data/warn-kick/state.json des tâches + liste keepers + expiration
- Scheduler (bot-site) : toutes les heures, kick des non-keepers à expiresAt, avec DM explicatif (lien vers le salon de commande)
- Clic Je veux rester : envoi au bot-site pour ajouter l’utilisateur à la liste ; période fermée ensuite
- Scheduler bot-site /warn-kick passe de 1h à 10 min (exécution plus rapide après expiresAt).
- Ajout de warn-kick dans bot-public/src/lib/serverConfig.js (DEFAULT_COMMANDS) pour qu’elle soit synchronisée sur les guilds.
- warn-kick handler Translate : édition du message en conservant components (boutons restent visibles/clickables).
- warn-kick handler Translate : suppression de components dans la réponse traduite (l’embed reste traduit, le message original conserve les vrais boutons).
- Commande /warn-kick et API POST /warn-kick/start : réservées à l’ID 1139951514694193323
- Campagne DM d'avertissement persistante (warnKickDmCampaign.js) : 1 DM / 2 min, pause 20 min tous les 30 DM
- État campagne stocké dans state.json (queue, index, batch) — survit aux redémarrages
- Message DM d'avertissement distinct du message d'expulsion finale
- /warn-kick n'utilise plus modSlash : commande standalone avec contrôle uniquement sur l'ID 1139951514694193323
- warn-kick ajouté à SKIP_GUILD_ACCESS (contourne le garde mod générique)
- Accès autorisé si utilisateur 1139951514694193323 ou rôle 1232966884375265281 (bot-public + bot-site)
- Config serveur LB'XMB : permissions warn-kick avec ce rôle + loupblanke en user
- Défaut BOT_SITE_URL → http://127.0.0.1:8787 dans warn-kick.js et warnKickPanel.js
- Ajout BOT_SITE_URL + INTERNAL_API_KEY dans bot-public/.env ; restart --update-env
- Login Better Auth : integration_type=1 forcé, suppression de guild_id / permissions
- buildDiscordAuthorizeUrl : toujours User Install, jamais de guild_id
- Verify + link : alignés sur le même flux compte
- /login → callback / (plus de double OAuth via discord-complete)
- discord-complete : simple redirect vers next ou / (compat)
- User Install bot : retour /discord/bot?installed=1 via cookie API
- /commencer : inchangé (/commencer?step=prefs après Discord)
- Verify : déjà /verify/{guild}?verified=1 (page succès)
- getPhotoUrl renforcé + isLocalUploadPhoto / buildDiscordAvatarUrl
- OAuth Discord : mapProfileToUser pose name + image CDN ; sync photo sans écraser Profils/ ; sync aussi sur liaison Discord legacy
- /api/auth/me : COALESCE users.photo → Better Auth user.image + heal si vide
- APIs online / featured-home : photos normalisées via getPhotoUrl
- UI chat/forum/projects/vocal/dashboard/donate : plus de /uploads/ brut pour les avatars
- nginx : rewrite /uploads/ → /api/uploads/ (prod + ptb)
- Heal DB : images Better Auth resynchronisées depuis users.photo quand vides
- Deploy web-prod
- Suppression de l’auto-redirection Discord au chargement
- Landing d’accueil avec présentation LB'XMB.FR + bouton Commencer (OAuth au clic)
- Layout élargi (max-w-5xl), plus aéré ; grille consoles 3 colonnes en prefs
- bash deploy.sh : build Next → swap .next-staging → pm2 restart web-prod --update-env
- BUILD_ID GjriZ843iuwRG-rEez0Ih ; 5 workers cluster online
- Landing chaleureuse (fonds verts/ciel, logo, animations douces) + message d’accueil
- Explication claire : intégration simple au serveur + vérification anti-abus
- Suppression de l’UI consoles / notifications / rôles
- Après OAuth Discord : finalisation auto via POST (rôle membre si configuré)
- Écran succès + lien invite Discord réel
- deploy.sh OK — BUILD_ID VYQmMg2D-Z1Oej6ciZegt ; web-prod redémarré
- Stream : proxy_protocol on vers backends nginx (4443/4444/4446)
- Strip PROXY avant coturn (13478/15349)
- listen … proxy_protocol sur les vhosts HTTPS
- Map $real_client_ip : CF-Connecting-IP si présent, sinon $proxy_protocol_addr
- Landing accueillante inchangée → après OAuth : étape prefs (consoles + notifs) → succès
- getClientIps / normalizeIp renforcés (IPv6 brackets, XFF split)
- POST /api/commencer : recordIpVisits sur toutes les IP détectées (is_registration_ip)
- Création compte (auth-helpers) : IP enregistrée en registration
- Nouveau POST /api/ip-beacon + appel auto dès l’étape prefs
- Sur chaque keep : deny ViewChannel utilisateur sur le salon (pas @everyone)
- Sync rétroactive des keepers déjà inscrits (~60)
- API POST /warn-kick/keepers + POST /warn-kick/sync-hide
- Commande Discord /warn-kick-list (staff autorisé)
- Message keep : confirmation + salon masqué
- Locale fr : réponse éphemère « Ce message est déjà en français. » (pas d’appel LibreTranslate)
- Autres locales : message d’erreur clair si traduction KO ; plus de content: null
- Même correctif sur le panneau Commencer
### 1. Blacklist / signalements
### 2. /commencer — accès salons par catégories
### 3. Panneau Commencer Discord
- guildMemberAdd : re-ban immédiat si isBlacklisted
- Signalements : liste filtrée status=open ; bouton Whitelist ferme les reports ouverts
- Blacklist depuis report : deferReply, propagation relations, ferme reports ouverts, meilleurs détails d’erreur ban
- /blacklist remove + contestation acceptée : ferment aussi les reports ouverts
- Log si échec save() blacklist
- Mapping console → category ID (commencer-categories.ts / commencerCategories.js)
- bot-site POST /commencer/channel-access : overwrites membre (View + ReadHistory + Connect) sur catégorie + salons enfants
- API web POST /api/commencer appelle channel-access après assignation rôles
- Flux : landing → Discord → toujours écran onboarding (consoles + notifs) → succès seulement après « Terminer la configuration »
- Plus de skip via onboardingDone en base
- Retry session si cookie OAuth pas prêt (step=prefs)
- Copie onboarding claire (« Choisis tes rôles ») ; succès = « Configuration terminée » + lien modifier
- Fermeture de la campagne invalide (mauvais salon)
- Lien DM forcé vers 1528633918280962179
- File DM reconstruites : 1216 membres (78 keepers exclus)
- Panneau renvoyé avec Translate + Je veux rester (msg 1529227086114459850)
- API POST /warn-kick/panel et POST /warn-kick/resend-dms
- Skip keepers dans la campagne DM + lock anti double-rebuild
- DM envoyés en embed + composants : Translate et Je veux rester
- Relance file pour non-keepers (nouveau format)
1. /to plantait : Cannot access 'contestable' before initialization
2. Besoin d’une option config pour restaurer le pseudo serveur après départ/retour
- sanctionNotify.js : contestable déclaré avant usage
- Pseudos auto : option hub Restaurer le pseudo au retour (restore_nickname_on_rejoin)
- Au GuildMemberRemove : sauvegarde du nickname serveur
- Au retour : restauration prioritaire (sinon règles permanentes/temporaires)
- Plus de save incorrect à l’arrivée après application d’un format
1. saveAutoRolesOnLeave existait mais n’était jamais appelé au GuildMemberRemove
2. Au leave, Discord n’envoie plus nick/rôles si le membre n’est pas en cache → sauvegarde vide
- Wiring saveAutoRolesOnLeave + saveNickOnLeave sur leave
- Store member-snapshots mis à jour à chaque guildMemberUpdate / join
- Warm snapshots au démarrage (guild.members.fetch) si restauration active
- Leave : fallback snapshot si cache vide
- Logs role-restore / nick-restore leave+join
- DM ban/kick/to/warn/mute/blacklist en Components V2 (container + thumbnail serveur, accent #a0000a)
- Bouton Contester (1×) sur ban, warn, blacklist uniquement → owner serveur (ban/warn) ; blacklist = stocké sans MP owners
- /blacklist sans options → panneau : Ajouter / Retirer / Liste / Contestation
- Blacklistés peuvent toujours cliquer Contester malgré le gate global
1. Blacklist sans MP → pas de bouton Contester
2. /signalement : bouton Whitelist à la place d'Ignorer ; besoin Sanctionner / Ignorer
3. /config : section Activité du serveur (régularisation)
4. Anti-raid : boucle leave/rejoin
### 1. Blacklist — DM avant ban
### 2. /signalement — Sanctionner / Ignorer
### 3. /config → Activité du serveur
### 4. Anti leave/rejoin
- Boutons Sanctionner + Ignorer (plus Whitelist)
- Menu : Avertissement (raison) ou Blacklist (durée vide = permanente + raison)
- MP pour warn et blacklist ; ignore = ferme uniquement le signalement
- Hub conditions (offline, messages, réactions, interactions, vocal min), délais, grâce, invite, rôles exemptés
- Garde d'arrivées (plafond + rafale → kick + MP + invite)
- bot-site lit la config guilde ; délai expulsion_delay_days avant kick
