Document de référence pour les scripts d'automatisation du projet tibetain.cebtg.ch.
Dernière mise à jour : 5 octobre 2026 — Script 3 (titres en français, vidéos masquées) et Script 4 (nouveau style des résumés, points-clés, anonymisation des participants, option --depuis, modèle Sonnet 5.5). Précédemment : ajout du Script 6 (14 septembre 2026).
🧭 Vue d'ensemble
Table de référence rapide. Pour le détail de chaque ligne, voir la section correspondante plus bas sur la page.
Script / intégration | Rôle | Déclenchement | Automatisé ? |
Script 1 — sync_local_ftp_notion.py | PDFs kDrive → FTP + Ressources Pédagogiques | Manuel, après dépôt de PDF | ❌ Mac local uniquement (accès disque) |
Script 2 — sync_caldav_notion.py | Calendrier kCalendar → base Cours à venir | Hebdomadaire + manuel | ✅ GitHub Actions, chaque lundi 5h00 UTC (6h/7h locale selon saison) |
Script 3 — sync_youtube_notion.py | Playlists YouTube → base Replays YouTube | Manuel, après replay publié | ✅ Mac, ou GitHub Actions à la demande (workflow youtube.yml, lancement manuel) |
Script 4 — sync_youtube_summaries.py | Sous-titres → résumé IA (Claude) dans Replays | Manuel, après Script 3 | ✅ Mac, ou GitHub Actions à la demande (workflow youtube.yml, lancement manuel) |
Script 5 — populate_sujet_relation.py | Relie Ressources ↔ Sujets (rollup Nombre de leçons) | Manuel, après nouveau sujet/leçons | ❌ |
Script 6 — sync_newsletter.py | Email hebdomadaire des dates de cours (Tally → Notion → SMTP) | Hebdomadaire + manuel | ✅ GitHub Actions, chaque lundi 6h15 heure de Genève (fixe, 15 min après Script 2) |
Make.com — segments Bullet | Paiement Stripe → accès Bullet | Automatique (webhook) | ✅ Actif en production depuis avril 2026 |
bullet-webhook.php | Nouveau membre Bullet → fiche Contacts JM | Automatique (webhook) | ✅ |
🏗️ Infrastructure & environnement d'exécution
Infrastructure générale
- Notion — CMS et bases de données
- kDrive Infomaniak — stockage des fichiers PDF
- kCalendar Infomaniak — calendrier des cours (CalDAV)
- Bullet.so — publication web (tibetain.cebtg.ch)
- Tally Pro — formulaires d'inscription
- YouTube — replays des cours (chaîne @falcolito)
- Anthropic API — génération des résumés automatiques (Claude)
- Webshare — proxy résidentiel rotatif (contournement blocage YouTube)
Environnement d'exécution
Tous les scripts tournent sur le Mac local de Jean-Marc, lancés manuellement selon les besoins.
Activation de l'environnement virtuel (obligatoire avant tout script) :
source ~/venv-cebtg/bin/activate
Dossier des scripts :
~/Documents/MesScripts/kDrive - Notion/
Dépendances Python (installées une seule fois) :
pip install yt-dlp requests anthropic youtube-transcript-api
Fichier de configuration :
config.json dans le même dossier.Structure du config.json :
{ "notion": { "token": "secret_...", "db_replays_youtube": "740058cf0fa1470cb93e4de1c43d0efb", "db_ressources": "90340df9fcbb480f80d86b7b7c473dc3" }, "anthropic": { "api_key": "sk-ant-...", "model": "claude-sonnet-5-5" }, "options": { "dry_run": true, "log_file": "sync_local_ftp_notion.log", "log_file_youtube": "sync_youtube_notion.log", "log_file_summaries": "sync_youtube_summaries.log", "miniature_largeur_px": 400, "caldav_horizon_jours": 90 } }
⚠️ Depuis le 5 octobre 2026,
config.json accepte aussi un bloc webshare (user et password, ou pass) pour le proxy du Script 4, et anthropic.model choisit le modèle Claude (par défaut claude-sonnet-5-5). Sur GitHub Actions, ces valeurs viennent des secrets WEBSHARE_USER et WEBSHARE_PASS. Aucun identifiant ne figure plus dans le code du script.⚠️ Depuis le Script 6 (newsletter),
config.json contient aussi un bloc smtp (host, port, user, password, expediteur_nom) et, dans le bloc notion, la clé db_abonnes_newsletter. Voir la section Script 6 plus bas pour le détail.📚 Bases de données Notion
Base | ID | Usage |
Contacts JM | afac5f30dd154106969fff73bc2feab5 | Étudiants inscrits |
Ressources Pédagogiques | 90340df9fcbb480f80d86b7b7c473dc3 | Supports PDF des cours |
Cours à venir | 84b33cbc7c7e49deb63967674c81eed4 | Calendrier des séances |
Replays YouTube | 740058cf0fa1470cb93e4de1c43d0efb | Vidéos des cours |
Abonnés newsletter tib dates des cours | 439211102f1a43dd87ba89166976ccc8 | Liste des abonnés à la newsletter hebdomadaire |
⚠️ Propriété
Type de contenu (Ressources Pédagogiques) — options au 5 septembre 2026 : Grammaire, Vocabulaire, Texte philosophique, Exercices, Leçon, Replay, Annexe (nouveau). Voir Script 1 ci-dessous pour la logique de détection automatique.📜 Scripts Python
Script 1 — sync_local_ftp_notion.py
Rôle : Synchronise les PDFs depuis kDrive local vers le serveur FTP Infomaniak et crée les entrées dans Ressources Pédagogiques avec miniatures. Détecte automatiquement s'il s'agit d'une leçon ou d'une annexe de leçon.
Quand le lancer : Après chaque dépôt de nouveau PDF dans kDrive.
⚠️ Toujours enchaîner avec Script 5 (
populate_sujet_relation.py) juste après — Script 1 crée la fiche dans Ressources Pédagogiques mais ne remplit jamais la relation Sujet lui-même. Sans Script 5, la fiche reste orpheline. Voir la section Script 5 plus bas, ou directement le workflow Après chaque PDF en fin de page.Commandes :
cd ~/Documents/MesScripts/kDrive\ -\ Notion source ~/venv-cebtg/bin/activate # ✅ CAS HABITUEL — ajout de nouveaux PDFs (ignore ceux déjà dans Notion) python3 sync_local_ftp_notion.py --sync --new-only # ✅ CAS HABITUEL — un seul PDF précis python3 sync_local_ftp_notion.py --sync --file Tib1/2025-2026/sujet/lecon-06.pdf python3 sync_local_ftp_notion.py --sync --file Tib2/2026-2027/sutra-pousse-de-riz-4/lecon-82.pdf # Simulation préalable (sans --sync) — voir ce qui serait traité python3 sync_local_ftp_notion.py --new-only # Sync complète (tous les PDFs — MET À JOUR les existants aussi — lent, ~20-30 min) python3 sync_local_ftp_notion.py --sync # Test de connexion FTP uniquement python3 sync_local_ftp_notion.py --ftp-test
⚠️ Fonctionnement du mode simulation et règle des deux options :
dry_run: truedans config.json → le script simule sans rien modifier (recommandé par défaut)- L'option
--syncest toujours nécessaire pour une exécution réelle - L'option
--new-onlyest indépendante : elle filtre les PDFs déjà présents dans Notion, quelle que soit la présence de--sync - ⚠️ Erreur fréquente :
--new-onlyseul (sans--sync) = simulation uniquement des nouveaux. Il faut toujours combiner--sync --new-onlypour le workflow quotidien.
Commande | Effet |
(aucun argument) | Simulation complète (tous les PDFs) |
--new-only | Simulation, nouveaux uniquement |
--sync | Exécution réelle, tous les PDFs (met à jour les existants) |
--sync --new-only | ✅ Exécution réelle, nouveaux uniquement — commande du quotidien |
--sync --file Tib1/…/lecon.pdf | Exécution réelle, un seul fichier précis |
Ce que fait le script :
- Lit les PDFs dans
/Users/jm/kDrive/Cours de tibétain/Tibétain/ - Détecte le type de contenu depuis le nom du fichier (Leçon ou Annexe — voir ci-dessous)
- Les uploade sur le FTP Infomaniak (
579j3l.ftp.infomaniak.com, user579j3l_cebtg_jm) verssites/cebtg.ch/cours/ - Génère une miniature PNG de la première page via PyMuPDF
- Crée ou met à jour la fiche dans Ressources Pédagogiques (pivot : kDrive Path)
- URL publique des PDFs :
https://cebtg.ch/cours/TibX/AAAA-AAAA/sujet/lecon-NN.pdf
Arborescence de référence (kDrive local) — mise à jour au 5 septembre 2026 d'après capture d'écran du Finder :
Tibétain/ Bonus/ (hors périmètre Script 1) Grammaire/ (hors périmètre Script 1) Miniatures/ (généré par Script 1, pas une source) Tib1/ 2021-2022/ tchenrezi-1/ 2022-2023/ tchenrezi-2/ 2024-2025/ dorje-tchang-thungma/ 2025-2026/ bodhicaryavatara/ dakayeshe/ 2026-2027/ bodhicaryavatara-2/ Tib2/ 2022-2023/ sutra-du-coeur/ 2023-2024/ sutra-pousse-de-riz-1/ 2024-2025/ sutra-pousse-de-riz-2/ 2025-2026/ sutra-pousse-de-riz-3/ 2026-2027/ sutra-pousse-de-riz-4/ Tib3/ 2023-2024/ 37-pratiques-des-bodhisattvas-1/ 2024-2025/ 37-pratiques-des-bodhisattvas-2/ sangtcheu-meunlam-1/ 2025-2026/ sangtcheu-meunlam-2/ 2026-2027/ sangtcheu-meunlam-3/
✅ Arborescence entièrement vérifiée d'après capture d'écran du Finder (5 septembre 2026).
⚠️ Convention de nommage des dossiers : minuscules, tirets à la place des espaces (ex.
nouveau-sujet). Le script convertit automatiquement en texte lisible (Nouveau sujet) pour le champ Chapitre/Section dans Notion.Convention de nommage des fichiers PDF — Leçon vs Annexe (mise à jour 5 septembre 2026 — plusieurs annexes par leçon)
Nom de fichier | Type de contenu | Titre généré |
lecon-80.pdf | Leçon | Leçon 80 — Sutra pousse de riz 3 |
annexe-1-lecon-80.pdf | Annexe | Annexe 1 — Leçon 80 — Sutra pousse de riz 3 |
annexe-2-lecon-80.pdf | Annexe | Annexe 2 — Leçon 80 — Sutra pousse de riz 3 |
annexe-lecon-01.pdf (ancien format) | Annexe | Annexe — Leçon 1 — … |
- Tout fichier dont le nom commence par
annexe-(insensible à la casse) est reconnu comme une annexe. - Format actuel — plusieurs annexes par leçon :
annexe-N-lecon-NN.pdf, oùNest le numéro de l'annexe (1, 2, 3…) etNNle numéro de la leçon à laquelle elle se rattache. Chaque annexe reçoit un titre distinct (Annexe 1 — …,Annexe 2 — …) tout en partageant le mêmeOrdreque la leçon, pour rester groupées dans les tris Notion. - Ancien format, toujours reconnu :
annexe-lecon-NN.pdf(une seule annexe pour la leçon, sans numéro d'annexe). - À défaut de correspondance avec l'un de ces deux motifs, le script retombe sur le premier nombre trouvé dans le nom de fichier.
- Aucune autre modification n'est nécessaire pour ajouter des annexes à un sujet existant : il suffit de déposer les fichiers
annexe-N-lecon-NN.pdfdans le même dossier que les leçons, puis de lancer la synchro habituelle.
Affichage séparé sur les pages Espace : pour qu'un niveau/année distingue visuellement les annexes des leçons, créer une seconde vue Galerie sur la base Ressources Pédagogiques intégrée à la page Espace concernée, avec le même filtre Niveau + Année scolaire active que la vue existante, plus
Type de contenu = Annexe ; et ajouter Type de contenu ≠ Annexe à la vue des leçons pour éviter les doublons. Déjà en place sur Espace Tib 2 — 2026-2027 (onglets « Leçons 2026-2027 » et « Annexes 2026-2027 »). À répliquer manuellement sur les autres pages Espace si des annexes y sont ajoutées.Ajouter un nouveau sujet de cours :
Aucune modification du script n'est nécessaire. Il suffit de :
- Créer le dossier sur le Mac :
Tibétain/TibX/AAAA-AAAA/nom-du-sujet/ - Attendre la synchronisation kDrive
- Déposer les PDFs dans ce dossier (
lecon-NN.pdfet, le cas échéant,annexe-lecon-NN.pdf) - Lancer
python3 sync_local_ftp_notion.py --sync --new-only
Le script créera automatiquement les fiches Notion, uploadera les PDFs sur le FTP et générera les miniatures, sans retraiter les leçons déjà synchronisées. Le champ
Chapitre/Section sera déduit du nom du dossier.Script 2 — sync_caldav_notion.py
Rôle : Synchronise le calendrier kCalendar Infomaniak vers la base "Cours à venir" dans Notion.
⚡ Automatisé via GitHub Actions depuis le 11 mai 2026.
Dépôt GitHub :
falco36/cebtg-scripts (privé)Déclenchement automatique : cron
0 5 * * 1 (5h00 UTC, fixe) — soit 6h00 heure de Zurich en hiver (CET, UTC+1) ou 7h00 en été (CEST, UTC+2). Aucune action requise.Déclenchement manuel (depuis iPhone ou navigateur) :
- Aller sur github.com/falco36/cebtg-scripts
- Onglet Actions → Sync CalDAV Notion
- Bouton Run workflow → Run workflow (vert)
Commandes manuelles Mac (backup) :
cd ~/Documents/MesScripts/kDrive\ -\ Notion source ~/venv-cebtg/bin/activate python3 sync_caldav_notion.py --dry-run # simulation python3 sync_caldav_notion.py # sync réelle
Secrets GitHub configurés (Settings → Secrets → Actions) :
ICS_URL— URL export ICS kCalendar InfomaniakNOTION_TOKEN— token API NotionNOTION_DB_COURS_A_VENIR— ID base Cours à venirFTP_HOST/FTP_USER/FTP_PASS/FTP_REMOTE_BASE— accès FTP Infomaniak
Ce que fait le script :
- Télécharge le calendrier ICS depuis Infomaniak
- Détecte les cours dans les 90 prochains jours
- Crée ou met à jour les fiches dans "Cours à venir" (pivot : CalDAV UID)
- Archive les fiches des cours disparus du calendrier
- Génère et uploade
agenda.htmlsur le FTP Infomaniak
Script 3 — sync_youtube_notion.py
Rôle : Synchronise les playlists YouTube vers la base "Replays YouTube" et insère la vidéo embarquée dans chaque fiche.
Quand le lancer : Après chaque nouveau replay publié sur YouTube.
Commandes :
cd ~/Documents/MesScripts/kDrive\ -\ Notion source ~/venv-cebtg/bin/activate # ✅ CAS HABITUEL — une seule nouvelle vidéo (quelques secondes) python3 sync_youtube_notion.py --video VIDEO_ID # Nouvelles vidéos uniquement — ignore les existantes (rapide) python3 sync_youtube_notion.py --new-only # Simulation sans écriture python3 sync_youtube_notion.py --dry-run # Sync complète de toutes les playlists (rare — ~15-20 min) python3 sync_youtube_notion.py
Durée approximative : ~15-20 minutes pour une sync complète. Pour le workflow habituel, utiliser
--video VIDEO_ID.Intelligence intégrée :
- Si une fiche a déjà un bloc vidéo embarquée → le corps n'est pas réécrit
- Utilise Video ID comme pivot (pas de doublons)
- Parse la date depuis le titre YouTube ("le 08.04.26")
- Déduit l'année scolaire depuis la date
Mises à jour du 5 octobre 2026 :
- Titres en français : yt-dlp demande désormais la langue française (
lang=fret en-têteAccept-Language). Cela évite les titres traduits automatiquement en anglais, avec des dates au format américain. Si un titre arrive malgré tout en anglais (« April 8, 2026 », « 4/8/26 »), la date est quand même lue correctement. Une synchronisation complète a remis en français les titres de 361 fiches. - Vidéos masquées, privées ou supprimées : elles sont ignorées avec un avertissement dans le log. Avant, une seule vidéo de ce type faisait planter le script (
expected string or bytes-like object, got 'NoneType') et plus aucune nouvelle vidéo ne se synchronisait. Deux sont concernées à ce jour :HpUVJcKBMb0etEvToMDrBdks. 361 vidéos sont maintenant extraites, au lieu de 308. --video IDaffiche une erreur claire si l'identifiant ne figure dans aucune playlist.- La version de yt-dlp est écrite dans le log (2026.08.19). Si l'extraction se comporte de façon bizarre :
pip install -U yt-dlp. - Vidéo qui manquait :
k4Vo5pVNyx0(Sangtcheu Meunlam 68, 02.10.26), maintenant synchronisée. - Le Sujet vient de la playlist (liste
PLAYLISTSdu script), pas de la base Sujets. Deux playlists peuvent donc donner deux Sujets différents pour un même texte (ex. « Prière de la conduite excellente » et « Sangtcheu meunlam 3 »). C'est voulu. - Titre YouTube : garder le format
Tib X - Cours de tibétain … leçon N, le JJ.MM.AA. L'année scolaire est déduite de la date du titre, donc une date fausse donne une mauvaise année scolaire.
Playlists synchronisées (9) :
Playlist ID | Niveau | Sujet |
PLuXH8SCX5XpSC1fxvAmr5h8QE6X27LLmK | Tib 1 | Bodhicaryāvatāra ch.3 |
PLuXH8SCX5XpQNZduN8rJymkyo2bku0CEy | Tib 1 | Dakayéshé |
PLuXH8SCX5XpR4V36sWdPjnvH1dkb6oWib | Tib 3 | Prière de la conduite excellente |
PLuXH8SCX5XpR6OAwEqUXQZvQOv-DGvB65 | Tib 1 | Dorjé Tchang Thungma |
PLuXH8SCX5XpRhFVtVvmWpO2lbqDSCNYo- | Tib 2 | Śālistamba Sūtra |
PLuXH8SCX5XpSWMsUVsoIh2WRi1cbvqyEs | Tib 3 | 37 pratiques |
PLuXH8SCX5XpTvL0gFePNqDUBE5wew0Use | Tib 1 | Groupe lecture |
PLuXH8SCX5XpTaynaLPw13B7MOAQjB4MqC | Tib 2 | Groupe Tchenrezi |
PLV2WaEBEzFWc | Tib 1 | Bodhicaryavatara 2 |
Pour ajouter une nouvelle playlist (procédure complète) :
- Dans YouTube Studio, copier l'ID de la playlist (ce qui suit
list=dans l'URL) - Ouvrir
sync_youtube_notion.py, dans la listePLAYLISTS(ligne ~37), ajouter une ligne :("ID_PLAYLIST", "Tib X", "Nom du Sujet", "AAAA-AAAA") - Tester :
python3 sync_youtube_notion.py --dry-run— vérifier que la nouvelle playlist apparaît avec le bon nombre de vidéos - Exécuter réellement :
python3 sync_youtube_notion.py - Committer sur GitHub (via GitHub Desktop) pour que la prochaine sync via GitHub Actions connaisse aussi cette playlist
- Ouvrir l'app GitHub Desktop — le dépôt courant doit être
cebtg-scripts, branchemain - Une fois le fichier copié (étape ci-dessus), l'onglet Changes affiche
sync_youtube_notion.pyavec 1 fichier modifié — cliquer dessus pour voir le diff (les lignes ajoutées apparaissent en vert) - En bas à gauche, remplir le champ Summary (required), ex. :
Ajout playlist NOM_DU_SUJET (AAAA-AAAA) - Cliquer sur Commit to main
- Une fois le commit fait, un bouton Push origin apparaît en haut — cliquer dessus pour envoyer la modification sur GitHub
- Si les vidéos doivent aussi compter comme leçons d'un Sujet (compteur "Nombre de leçons") : vérifier que le PDF correspondant existe dans Ressources Pédagogiques avec le bon
Chapitre/Section, puis relancer Script 5 (voir plus bas)
⚠️
"Nom du Sujet" doit être identique, caractère pour caractère, au titre du Sujet dans la base Sujets — sinon Script 5 ne pourra pas faire la relation⚠️ Piège fréquent : le dossier de travail quotidien (
~/Documents/MesScripts/kDrive - Notion/) et le dépôt surveillé par GitHub Desktop (~/Documents/GitHub/cebtg-scripts/) sont deux copies distinctes sur le disque. Avant de committer, copier le fichier modifié :cp ~/Documents/MesScripts/kDrive\ -\ Notion/sync_youtube_notion.py \ ~/Documents/GitHub/cebtg-scripts/sync_youtube_notion.py
Sinon GitHub Desktop affiche "0 changed files" — rien à committer.
Marche à suivre dans GitHub Desktop :
✅ Une fois poussé, un lancement futur du Script 3 depuis GitHub Actions (iPhone ou navigateur) connaîtra cette nouvelle playlist.
Script 4 — sync_youtube_summaries.py
Rôle : Extrait les sous-titres YouTube, génère un résumé pédagogique via Claude AI (Anthropic) et l'insère dans le corps de chaque fiche replay.
Quand le lancer : Après le Script 3, pour les nouvelles fiches. Ne pas relancer plus d'une fois par jour.
Commandes :
cd ~/Documents/MesScripts/kDrive\ -\ Notion source ~/venv-cebtg/bin/activate python3 sync_youtube_summaries.py # toutes les vidéos récentes (6 mois) python3 sync_youtube_summaries.py --dry-run # simulation sans écriture python3 sync_youtube_summaries.py --force # réécrire les résumés existants python3 sync_youtube_summaries.py --video VIDEO_ID # une seule vidéo python3 sync_youtube_summaries.py --force --depuis 2026-09-01 # réécrire tous les résumés depuis une date (AAAA-MM-JJ) python3 sync_youtube_summaries.py --dry-run --force --video VIDEO_ID # voir le résumé complet sans écrire dans Notion
Ce que fait le script :
- Filtre les fiches Notion des 6 derniers mois sans résumé
- Extrait les sous-titres automatiques YouTube via
youtube-transcript-api - Utilise le proxy Webshare résidentiel rotatif pour contourner les blocages YouTube
- Envoie le transcript (~7000 mots) à l'API Claude Anthropic avec un prompt pédagogique
- Insère le résumé dans la fiche Notion sous forme de callout (brun)
Format du résumé généré :
Bonjour,
Aujourd'hui, nous… (8 à 12 lignes, ouverture variable)
Les points-clés (sous-titre) puis 4 à 8 puces
Bon replay et bonne étude !
Si vous souhaitez recevoir les supports PDF de cette leçon, merci de vous inscrire. [lien vers /inscription/]
Mises à jour du 5 octobre 2026 :
- Modèle :
claude-sonnet-5-5(réglable dansconfig.json→anthropic.model). Ce modèle renvoie un bloc de réflexion avant le texte : le script ne garde que les blocs de texte (erreur'ThinkingBlock' object has no attribute 'text'corrigée) etmax_tokensest à 4000. - Style des résumés : plus proche et moins formel. L'enseignant s'exprime en « nous » et en « je », jamais « le professeur ». Le lecteur est tutoyé, de façon chaleureuse mais pas familière. Les ouvertures et fermetures varient d'une leçon à l'autre (plus de « Dans cette leçon… » systématique). Seule la signature « Bon replay et bonne étude ! » est fixe. Le prompt contient un exemple de style (
PROMPT_SYSTEME). - Les points-clés : après le résumé, 4 à 8 puces affichées dans Notion sous un sous-titre « Les points-clés ». Le modèle sépare le résumé et les puces avec la ligne
###POINTS-CLES###, et le script la lit avant d'écrire les blocs Notion. Avec--force, l'ancien encadré, l'ancien sous-titre et les anciennes puces sont supprimés avant réécriture (le lien YouTube et la vidéo ne sont pas touchés). - Discrétion : les prénoms des participants ne sont jamais cités. Le texte dit « un participant » ou « une participante » selon le genre du prénom, ou « une personne du groupe » en cas de doute. Les noms des maîtres et des personnages des textes restent cités. Limite : les sous-titres automatiques déforment souvent les prénoms, le genre peut donc être mal deviné.
- Option
--depuis AAAA-MM-JJ: ne traite que les vidéos à partir de cette date. À combiner avec--forcepour réécrire des résumés existants. Sans option, la limite reste de 6 mois. - Signature : inchangée (« Si vous souhaitez recevoir les supports PDF de cette leçon, merci de vous inscrire. », avec le lien vers /inscription/). Le « vous » est gardé volontairement.
- Dry-run : le résumé complet et les points-clés s'affichent dans le terminal. En exécution réelle, le log ne montre que les 120 premiers caractères.
- Réécriture faite le 5 octobre 2026 : les 13 leçons depuis le 1er septembre 2026 ont été réécrites dans le nouveau style (13 traités, 0 erreur). Les résumés d'avant septembre gardent l'ancien style.
- Proxy : le mot de passe Webshare a été changé début octobre 2026 et ne figure plus dans le code.
Proxy Webshare (anti-blocage YouTube) :
- Host :
p.webshare.io, Port :80 - Rotation automatique parmi 10 proxies résidentiels
- Identifiants : voir
config.json(blocwebshare) ou les secrets GitHubWEBSHARE_USERetWEBSHARE_PASS - En cas de blocage persistant : attendre quelques heures et relancer
Prérequis :
- Clé API Anthropic dans
config.json→ champanthropic.api_key - Crédit API Anthropic approvisionné (console.anthropic.com)
Script 5 — populate_sujet_relation.py
Rôle : Peuple la propriété relation
Sujet dans la base Ressources Pédagogiques en faisant correspondre le champ Chapitre/Section (Ressources) avec le champ Clé Chapitre/Section (Sujets). Une fois la relation remplie, le rollup Nombre de leçons dans la base Sujets se calcule automatiquement.Quand le lancer :
- Après la création d'un nouveau sujet dans la base Sujets (renseigner sa
Clé Chapitre/Sectiond'abord) - Après l'ajout de nouvelles leçons via Script 1 pour un sujet existant
- Après correction d'un champ
Chapitre/Section(utiliser--force)
Commandes :
cd ~/Documents/MesScripts/kDrive\ -\ Notion source ~/venv-cebtg/bin/activate python populate_sujet_relation.py --dry-run # simulation — affiche ce qui sera fait python populate_sujet_relation.py # exécution réelle python populate_sujet_relation.py --force # écrase les relations déjà renseignées
Ce que fait le script :
- Compare
Chapitre/Section(Ressources) avecClé Chapitre/Section(Sujets) - Remplit la relation
Sujetdans chaque fiche Ressource correspondante - Le rollup
Nombre de leçonsse met à jour automatiquement dans Notion - Ne touche pas aux fiches déjà reliées sauf si
--force
Script 6 — sync_newsletter.py
Rôle : Envoie chaque semaine un email récapitulatif des cours de tibétain (dates et horaires, convertis en heure de Genève) à la liste des abonnés inscrits via un formulaire Tally public.
⚡ Automatisé via GitHub Actions depuis le 14 septembre 2026.
Dépôt GitHub :
falco36/cebtg-scripts (privé)Déclenchement automatique : cron
15 6 * * 1 avec timezone: "Europe/Zurich" — chaque lundi à 6h15, heure de Genève, toute l'année (GitHub Actions gère le passage heure d'été/hiver automatiquement depuis le support des fuseaux horaires IANA ajouté en mars 2026). Toujours 15 minutes après le Script 2. Aucune action requise.Déclenchement manuel (depuis iPhone ou navigateur) :
- github.com/falco36/cebtg-scripts → onglet Actions → Sync Newsletter
- Bouton Run workflow → remplir
test_email(optionnel, pour tester sans toucher aux vrais abonnés) et/oudry_run→ Run workflow (vert)
Commandes manuelles Mac (backup) :
cd ~/Documents/MesScripts/kDrive\ -\ Notion source ~/venv-cebtg/bin/activate python3 sync_newsletter.py --dry-run # simulation python3 sync_newsletter.py --test-email adresse@ex.ch # envoi à une seule adresse de test python3 sync_newsletter.py # envoi réel à tous les abonnés actifs
Secrets GitHub configurés (Settings → Secrets → Actions) :
NOTION_TOKEN,NOTION_DB_COURS_A_VENIR— réutilisés du Script 2NOTION_DB_ABONNES_NEWSLETTER— ID de la base Abonnés newsletterSMTP_HOST,SMTP_PORT,SMTP_USER,SMTP_PASSWORD,SMTP_EXPEDITEUR_NOM— envoi via SMTP Infomaniak (SMTP_PASSWORDest un mot de passe d'appareil dédié, généré depuis Manager Infomaniak → Service Mail → adresse concernée → onglet Appareils → Ajouter un appareil → Configurer moi-même)
Ce que fait le script :
- Interroge la base "Cours à venir" (Notion) pour les cours de la semaine en cours (lundi → dimanche)
- Convertit les horaires (stockés en UTC dans Notion) vers l'heure de Genève via
zoneinfo(Europe/Zurich) - Interroge la base "Abonnés newsletter tib dates des cours" (filtre
Actif = coché) - Envoie un email personnalisé (prénom) à chaque abonné individuellement via SMTP — pas de BCC groupé
- N'envoie rien si aucun cours cette semaine, sauf option
--force
Inscription des abonnés — formulaire Tally :
- Lien public du formulaire :
https://tally.so/r/68gp5N - 3 champs collectés : Prénom, Nom de famille, Email — plus une case à cocher obligatoire ("Je souhaite recevoir le rappel hebdomadaire des dates de cours") qui fait office de consentement explicite
- Intégration native Tally → Notion (pas de Make.com ici) : chaque soumission crée une ligne dans la base "Abonnés newsletter tib dates des cours", la case cochée étant mappée directement sur la propriété
Actif - ⚠️ Le mode Preview de l'éditeur Tally ne déclenche pas l'intégration Notion — seul un envoi depuis le lien public réel crée une ligne
- Désinscription : pas encore automatisée. Les abonnés sont invités à répondre à l'email pour se désinscrire ; décocher
Actifmanuellement dans Notion en attendant un vrai lien de désinscription - Propriété
Abonné(titre de la base) : reste vide, sans impact — le script ne la lit jamais
🔗 Intégrations & webhooks
Make.com — Automatisation segments Bullet
Rôle : Attribue automatiquement les accès Bullet dès qu'un paiement Stripe est confirmé. Aucune action manuelle.
Flux : Stripe
checkout.session.completed → webhook Make → filtre metadata.segment → API Bullet (création membre + ajout segment)Statut : Actif en production depuis avril 2026 — 12 branches (un segment par sujet payant)
Documentation complète : voir la page ⚙️ Make.com — Automatisation segments Bullet dans Simplicity
Webhook Make :
https://hook.eu2.make.com/9g5lhui4lebgncwy9wjh4rm2k11ic66kMétadonnée Stripe requise sur chaque Payment Link : clé
segment, valeur = nom exact du segment BulletTest sans paiement réel (Terminal, pas besoin du venv) :
curl -X POST https://hook.eu2.make.com/9g5lhui4lebgncwy9wjh4rm2k11ic66k \ -H "Content-Type: application/json" \ -d '{"type":"checkout.session.completed","data":{"object":{"metadata":{"segment":"NOM_DU_SEGMENT"},"customer_details":{"email":"EMAIL_DE_TEST"}}}}'
Webhook — bullet-webhook.php
Rôle : Reçoit les événements "User Created" de Bullet Membership et crée/met à jour la fiche dans Contacts JM.
URL déployée :
https://cebtg.ch/webhooks/bullet-webhook.phpConfiguration dans Bullet : Site Settings → Membership → Webhooks → Add endpoint → cocher "User Created".
Ce que fait le script :
- Détecte les payloads de vérification Bullet (name = "testURL") → répond 200 OK sans toucher Notion
- Pour un vrai événement : cherche le contact par email dans Contacts JM
- Si trouvé : met à jour Tib niveau, Cours/Stages, Soutien, Dernière interaction
- Si nouveau contact : crée la fiche complète
Correspondance segments Bullet → Notion :
Segment Bullet | Tib niveau Notion |
Tib1 | Tib 1 |
Tib2 | Tib 2 |
Tib3 | Tib 3 |
🚀 GitHub Actions — Pistes pour la suite
Dépôt :
falco36/cebtg-scripts (privé) — base déjà en place.Script 2 (CalDAV → Notion) ✅ automatisé — chaque lundi à 6h.
Script 6 (Newsletter) ✅ automatisé — chaque lundi à 5h15 UTC (15 min après le Script 2).
Scripts 3 et 4 ✅ disponibles à la demande via le workflow
youtube.yml (Actions → Sync YouTube → Notion → Run workflow, avec VIDEO_ID, choix du script et dry-run). Pas de déclenchement automatique : ils se lancent après chaque replay publié. Penser à surveiller la consommation de l'API Anthropic (Script 4).Candidats pour une automatisation future :
- Scripts 3 et 4 : ajouter un déclenchement hebdomadaire (cron) au workflow
youtube.yml, si tu veux que les nouveaux replays soient synchronisés sans intervention. - Script 1
sync_local_ftp_notion.py— lit les fichiers locaux kDrive → restera sur Mac (GitHub Actions n'a pas accès au disque local).
Pour ajouter un script : copier le fichier dans le dépôt, créer un fichier
.yml dans .github/workflows/, ajouter les secrets nécessaires dans Settings → Secrets → Actions.✅ Workflows courants
Après chaque séance
- YouTube publie la vidéo
python3 sync_youtube_notion.py→ sync la nouvelle fiche (30 sec)python3 sync_youtube_summaries.py→ génère le résumé automatique (30 sec)- Publish dans Bullet → la fiche apparaît sur le site avec vidéo + résumé
Après chaque PDF (leçon ou annexe)
- Déposer le PDF dans kDrive (
/Tibétain/TibX/AAAA-AAAA/sujet/lecon-NN.pdfouannexe-lecon-NN.pdf) python3 sync_local_ftp_notion.py --sync --new-only→ upload FTP + création fiche Notion (ignore les PDFs déjà synchronisés)python populate_sujet_relation.py→ relie la nouvelle fiche à son Sujet (champSujet) et met à jour le rollupNombre de leçons- Publish dans Bullet
⚠️ Étape à ne jamais sauter : sans elle, la ressource existe dans Notion mais reste orpheline (aucun Sujet lié), et n'apparaîtra pas correctement sur le site même si elle est publiée.