@Olivier's

Construire un proxy RSS pour Telegram avec MTProto et GitHub Spec Kit

Je teste depuis plusieurs mois les approches de développement « Spec Driven », qui me semblent promises à un bel avenir grâce à l’essor des IA génératives. Ici, on ne se contente pas de « prompter » un besoin pour voir son code généré : on adopte un nouveau paradigme où la spécification (re)devient la pierre angulaire du projet. On utilise ensuite l’IA pour produire les User Stories, les tâches et, enfin, le code.

L’objectif de ce projet est double : mettre en œuvre l’approche Spec Driven Development sur un cas concret — une méthode que j’ai déjà testée et qui me plaît beaucoup — et expérimenter l’utilisation de MTProto. Il s’agit de l’API utilisateur de Telegram qui, contrairement à l’API bot historique, permet de créer un client alternatif, à l’instar du client officiel.

C’est particulièrement utile car le client officiel permet de parcourir un canal auquel on n’est pas abonné, ce qui m’arrive parfois lors de ma veille techno, alors que l’API Bot ne le permet pas. L’idée est de pouvoir être notifié de l’apparition d’une news ou d’un mot-clé sur un canal identifié, sans avoir à s’y abonner ni à interagir.

Le projet consiste donc à transformer n’importe quel canal Telegram public en flux RSS 2.0, sans abonnement, via une API FastAPI asynchrone. La librairie Telethon, qui implémente MTProto, sera utilisée à cet effet.

Le code source du projet avec son historique est disponible sur mon repository GitHub.

Cadre GitHub Spec Kit

Il faut d’abord initialiser un nouveau projet avec GitHub Spec Kit. Pour cela, une fois l’outil installé, il suffit d’exécuter la commande specify init telegram-rss. Un prompt vous demande alors deux choses :

Le résumé Spec Kit suite à init

Le dossier ainsi créé peut ensuite être ouvert dans votre éditeur favori (VSCode pour ma part). La première étape consiste à définir les contraintes de constitution du projet. Le fichier constitution.md servira, lors de toutes les commandes ultérieures, à rappeler à l’IA les contraintes et le contexte devant guider ses décisions. La commande :

/speckit.constitution Le programme doit être disponible sous forme d'une image docker, pas besoin de Kubernetes. Pas de base de données externe, si besoin un SQLite peut suffire dans un volume qui sera éventuellement exporté, au même endroit que les paramètres Telegram éventuels. La librairie d'accès à Telegram doit obligatoirement être Telethon (https://docs.telethon.dev/)

permet de générer ce fichier. Elle intègre les invariants et les choix techniques sur lesquels on souhaite impérativement s’appuyer.

Spécifications

C’est ici que l’on pérennise le projet. Au lieu de demander directement à une IA de créer le code, on génère d’abord une spécification, un plan et des tâches qui serviront de pivot à tous les développements futurs. Le framework propose des « slash commandes », des prompts augmentés ciblant les modèles les plus performants pour la tâche en cours.

/speckit.specify Cette application est un serveur exposant un flux RSS pour chaque channel telegram demandé, sans que le compte utilisateur Telegram s'y abonne, en utilisant le protocole MTProto de https://docs.telethon.dev/. Le serveur récupère les flux à chaque requête, avec le schéma d'url suivant : http://serveur:port/rss/channel, où channel est remplacé par le nom du channel telegram demandé.

Cette commande décrit notre usage. À partir de là, le fichier spec.md est généré. Il doit être attentivement complété par l’humain, car c’est lui qui fixe le cadre de l’implémentation.

À noter : chaque nouvelle spécification est isolée dans un dossier distinct afin de bien séparer les intentions de leur implémentation. C’est propre, clair, et l’intention initiale est parfaitement conservée pour la relecture.

L’arborescence du projet terminé et le fichier de specification

Planification et création des tâches

Les commandes suivantes nécessitent potentiellement moins de prompting, car le besoin est déjà bien défini. Elles doivent permettre de décrire le projet avec assez de précision pour que l’implémentation ne laisse plus de place au doute.

/speckit.plan L'application doit être autonome, en python, et utiliser MTProto de https://docs.telethon.dev/

La planification apporte le détail technique. Ici, rien de sorcier : nous avons déjà fourni nos contraintes. J’enfonce le clou, même si c’est probablement superflu.

Maintenant il reste à produire la liste des tâches unitaires nécessaires à l’implémentation, avec la commande /speckit.tasks. Cette liste sera stockée dans tasks.md. Le résultat est assez bluffant : l’IA découpe le projet en tâches unitaires précises (T001, T002…). C’est votre feuille de route. Vous pouvez l’amender, mais globalement, il ne vous reste plus qu’à piloter l’implémentation, étape par étape.

Implémentation

La commande /speckit.implement, utilisée de manière itérative, permet de dialoguer avec le LLM pour préciser certains points et générer le code. Elle coche automatiquement les tâches complétées dans tasks.md, vous permettant de suivre l’avancement, tests et déploiements inclus.

Pendant l’implémentation, tous les tests sont déroulés. À ce stade, je recommande l’acceptation automatique de certaines commandes dans l’IDE, tant les interactions sont nombreuses. Il faut trouver le juste équilibre entre contrôle humain et rapidité d’exécution.

Pour cette application, les tâches ont été réparties ainsi :

  1. Setup (T001-T003) : Dépendances (FastAPI, Telethon, feedgen, pytest), Dockerfile unique, arborescence src/app et tests/.
  2. Fondations (T004-T010) :
    • Logging JSON structuré.
    • Config loader avec fail-fast sur les clés API et les limites.
    • Validation des noms de canaux (regex) et modèles.
    • Wrapper Telethon (gestion de session, timeout, récupération des messages).
    • Générateur RSS (UTF-8, no-store).
    • App factory FastAPI et documentation OpenAPI.
  3. US1 (T011-T013) : Endpoint GET /rss/{channel}, tests unitaires et intégration.
  4. US2 (T014-T015) : Gestion des erreurs 400/403/404 (invalide, privé ou manquant).
  5. US3 (T016-T017) : Gestion des timeouts (504) et rate-limits (429).
  6. Polish (T018-T021) : Quickstart, contrat de test, CI (lint/format) et README complet.

Remarques sur le déroulé avec GitHub Spec Kit

On peut relancer n’importe quelle commande à tout moment. Attention toutefois : cela peut invalider certaines tâches déjà effectuées (ou non), et il faudra parfois rectifier le tir manuellement. Il est primordial de rester attentif aux actions du LLM. Cela représente une vraie charge mentale et nécessite une expertise réelle pour éviter que l’IA ne s’égare.

Erreurs rencontrées et corrections

Voici les quelques accrocs rencontrés lors de la génération automatique. J’ai pu guider l’IA pour les corriger ; les solutions proposées étaient pertinentes, même si cela demande de rester vigilant :

Résultat final

En seulement 2 heures, j’ai obtenu une première application fonctionnelle répondant à mes attentes. Elle est simple et remplit parfaitement son objectif.

Côté qualité : les tests Ruff/Black sont au vert, 9 tests (unitaires, intégration, contrat) passent avec succès et l’OpenAPI est conforme. Côté Ops, la génération automatique a bien intégré les essentiels (README, Compose, Quickstart). Le volume /data pour la session Telegram est opérationnel et les erreurs HTTP sont correctement mappées. J’ai même ajouté quelques tests de sécurité en CI, configurés pour tourner quotidiennement. Un code généré qui n’évolue plus accumule vite de la dette.

Verdict

Au-delà des spécifications, je remarque que je deviens moins strict sur la « beauté » pure du code. J’exige un contrôle total sur les tests et les garde-fous, mais tant que le code fonctionne, son élégance m’importe moins. C’est une tendance qui devrait s’accentuer : le craftsmanship va évoluer vers la maintenabilité des spécifications plutôt que celle du code lui-même, tant ce dernier peut être réécrit rapidement.

Attention toutefois à la charge mentale : on effectue une code review permanente sur un outil auquel on accorde, par définition, une confiance limitée. C’est un exercice qui demande une concentration soutenue.