Automatiser une newsletter de chaîne YouTube avec RSS et une seule API

L'automatisation d'une newsletter de chaîne YouTube ne demande que trois éléments : le flux RSS que YouTube publie discrètement pour chaque chaîne, une API de transcription et une tâche cron. Mon digest du lundi matin — six chaînes de ma niche, résumées avec de la vraie substance plutôt que des titres à vignette — tourne sans intervention depuis quatre mois sur environ 40 lignes de Python. Voici la construction.
Le flux RSS que YouTube ne met pas en avant
Chaque chaîne a un flux à l'adresse :
https://www.youtube.com/feeds/videos.xml?channel_id=CHANNEL_ID
Pour trouver l'ID d'une chaîne, ouvrez la page de la chaîne, affichez le code source et cherchez channelId. Le flux renvoie les mises en ligne les plus récentes (environ les 15 dernières) avec les dates de publication — pas de clé API, pas d'OAuth, pas de quota YouTube Data API. C'est le déclencheur de tout le pipeline.
Le script
Interroger les flux, garder les 7 derniers jours, transcrire, résumer :
import feedparser, requests
from datetime import datetime, timedelta, timezone
CHANNELS = ["UC_channel_id_1", "UC_channel_id_2"]
API_KEY = "yt_your_key"
cutoff = datetime.now(timezone.utc) - timedelta(days=7)
videos = []
for cid in CHANNELS:
feed = feedparser.parse(
f"https://www.youtube.com/feeds/videos.xml?channel_id={cid}")
for e in feed.entries:
published = datetime(*e.published_parsed[:6], tzinfo=timezone.utc)
if published < cutoff:
continue
r = requests.get("https://youtube2text.org/api/transcribe",
params={"url": e.link, "maxChars": 60000},
headers={"x-api-key": API_KEY}, timeout=60).json()
if "result" in r:
videos.append(r["result"])
Chaque result contient title, pubDate et jusqu'à 60k caractères de content — environ 45 minutes de parole, largement assez pour un résumé de digest. Envoyez chacun à votre LLM préféré avec un prompt volontairement sobre :
Summarize this video transcript for a newsletter digest.
Three sentences, no hype, end with one concrete takeaway
a reader can act on. Video: {title}
{content}
Concaténez les résumés, ajoutez les liens, envoyez le tout vers votre outil d'e-mailing (j'utilise un simple appel SMTP), et planifiez : 0 7 1 python3 /home/you/digest.py.
Le calcul du quota
Six chaînes publiant en moyenne deux vidéos par semaine, cela fait environ 48 à 50 transcriptions par mois — les 50 vidéos de la formule basique à 5,99 $ couvrent tout juste, ce qui est soit satisfaisant soit angoissant selon votre tempérament. Si vos chaînes sont prolifiques, la formule pro à 9,99 $ pour 500 supprime le suspense. Les 5 par mois du niveau gratuit suffisent pour un digest mono-chaîne, par exemple envoyer à vos propres abonnés un récapitulatif de vos vidéos de la semaine.
Les deux modes de défaillance
Ce sont deux problèmes de timing, et les deux méritent d'être traités honnêtement. Premièrement, une vidéo publiée une heure avant le déclenchement de votre cron peut ne pas encore avoir de sous-titres traités, donc l'API renvoie TRANSCRIPT_UNAVAILABLE. Je consigne ces identifiants et je les retente à l'exécution suivante plutôt que de les abandonner — décaler le digest d'un jour par rapport à la coupure hebdomadaire fonctionne aussi. Deuxièmement, le flux RSS ne liste que les mises en ligne récentes, donc une cadence mensuelle sur une chaîne qui publie chaque jour ratera des vidéos en silence. Une interrogation hebdomadaire est sûre pour toutes les chaînes que j'ai testées ; si une source publie plus de deux fois par jour, interrogez deux fois par semaine.
Si vous préférez ne pas maintenir de script
Le même pipeline se construit dans des outils no-code avec un nœud de déclenchement RSS : la version n8n et la version Make l'expliquent toutes deux pas à pas. Et si vous voulez des comptes rendus par vidéo plus riches qu'un digest de trois phrases, le prompt de notes d'épisode s'insère directement dans cette boucle.
Une connexion Google sur youtube2text.org/app/keys vous donne une clé en moins d'une minute — sans carte, sans téléphone — et votre boîte de réception du lundi commence à mériter sa place.