Bot de modération Telegram
Un bot pensé au départ comme un funnel d'acceptation par cooptation — chaque utilisateur doit être recommandé par un membre existant pour rejoindre un groupe — puis enrichi d'une modération classique (mots-clés, liens, forwards) à la demande des clients qui l'utilisent. Hébergé sur un VPS que je gère de bout en bout, avec un environnement de test séparé de la production et un déploiement entièrement automatisé.
Pourquoi ce projet
À l'origine, ce n'est pas un filtre anti-spam classique : c'est un système de cooptation. Le bot est déployé dans tous les groupes de la communauté, et chaque nouvel utilisateur doit être recommandé par un membre déjà présent pour être accepté — sans parrain, pas d'entrée. Ce funnel d'acceptation limite drastiquement les faux comptes et les arrivées en masse avant même qu'un message ne soit envoyé.
Par la suite, les clients qui utilisent ce bot ont demandé une couche de modération plus classique : filtrage de mots-clés, de liens et de messages transférés (forwards) suspects. L'objectif reste le même — garder chaque groupe aussi sûr et sans spam que possible — en combinant vérification à l'entrée et surveillance continue une fois dans la communauté.
Modérer une communauté aussi active en direct sur la production n'était pas une option viable : la moindre régression pouvait impacter 20 000 personnes en même temps. D'où le choix de séparer strictement un environnement de test d'un environnement de production, chacun avec son propre bot Telegram et sa propre base de données.
Comment c'est construit
Le bot tourne sur un VPS Linux que j'administre moi-même, en deux instances distinctes gérées par systemd : une pour les tests, une pour la production. Chacune a son propre processus, sa propre base SQLite et son propre token Telegram, ce qui isole complètement les deux environnements — une régression en test ne touche jamais les 20 000 membres de la communauté réelle.
Les actions de modération (bannissements, suppressions, sanctions)
passent par une file d'attente asynchrone que j'ai développée
moi-même en Python (asyncio), pour sérialiser les
appels à l'API Telegram, éviter le rate-limiting et garder des
écritures cohérentes sur SQLite.
Côté supervision, chaque service écrit ses logs via
journalctl. En complément, un second bot Telegram
dédié à la supervision envoie des alertes en temps réel, et une
automatisation Slack notifie automatiquement dès qu'un service
tombe ou que le code casse — sans avoir besoin de surveiller les
logs en permanence.
GitHub Actions déploie sur le VPS via SSH. Les deux bots (test/prod) tournent en services systemd isolés, chacun avec sa base SQLite, et passent par une file d'attente asynchrone commune avant d'appeler l'API Telegram.
Ce que ça fait concrètement
- Système de cooptation à l'entrée : chaque nouvel utilisateur doit être recommandé par un membre existant pour être accepté dans un groupe, dans tous les groupes où le bot est déployé
- Modération classique ajoutée à la demande des clients : filtrage de mots-clés, de liens et de messages transférés (forwards) suspects
- Deux environnements totalement isolés (test et production), chacun avec son propre processus systemd, sa propre base SQLite et son propre bot Telegram — un bug en test ne peut jamais atteindre la communauté réelle
- Redémarrage automatique du service en cas de crash grâce à systemd (
Restart=on-failure), sans intervention manuelle - File d'attente asynchrone maison qui sérialise les actions de modération (bannissement, suppression de message, sanction) pour respecter les limites de débit de l'API Telegram et éviter les écritures concurrentes sur SQLite
- Pipeline GitHub Actions qui lance les tests automatiquement à chaque push, puis déploie sur le VPS via SSH et redémarre le service concerné au merge sur la branche principale
- Logs consultables via
journalctlpour chaque service, pour diagnostiquer rapidement un incident - Supervision active : un second bot Telegram dédié envoie des alertes en temps réel, complété par une automatisation Slack qui notifie automatiquement dès qu'un service tombe ou que le code casse (crash, erreur non gérée, échec de déploiement)