Files
nas-runbooks/hermes-tt/sharepoint-delta-sync.md
T

131 lines
6.9 KiB
Markdown

# SharePoint delta-sync (hermes-mail-browser -> archive locale) -- mise en place complete
**Instance auteur** : hermes-tt
**Date** : 2026-08-06
**Tags** : hermes-tt, sharepoint, sync, hermes-mail-browser, n8n, onedrive
**Statut** : valide
---
## Probleme
Objectif : ingestion automatique et sans intervention manuelle des fichiers OneDrive/SharePoint (TT)
dans le RAG nyora-notes-tt. Pipeline en deux moities :
1) Archive locale -> RAG (catalog+process+embed) : deja actif (workflow n8n Q6ZAXgd8HYoQbk9K).
2) SharePoint cloud -> archive locale : endpoint POST /sharepoint-sync ecrit sur hermes-mail-browser,
code jamais teste en conditions reelles avant cette session.
Reprise de session : verifier le rebuild hermes-mail-browser (montage RW de l'archive ajoute),
puis valider tout le mecanisme (listing + filtre + telechargement + placement fichier).
---
## Contexte et contraintes
- hermes-mail-browser (port 3110->8000, VNC 8810->6080), Edge reel via CDP (`--remote-debugging-port=9222`),
profil persistant `--user-data-dir=/data/profile` (monte sur `./data:/data` cote hote, donc SURVIT
aux restart/recreate/rebuild -- confirme par la session SSO OWA qui a tenu apres un rebuild complet).
- Endpoint `POST /sharepoint-sync?lookback_hours=N` : un seul appel `_api/web/GetList(...)/items` par site,
22 sites definis dans `SHAREPOINT_SITES` (main.py), filtre OData `Modified ge datetime'<cutoff>'`.
- Montage RW `/volume1/docker/nyora-onedrive-archive:/data/onedrive-archive` partage avec nyora-notes-tt
(qui scanne le meme dossier en lecture seule) -- tout fichier depose est repris automatiquement par
le pipeline partie 1 sans chainage explicite necessaire.
---
## Ce qui NE fonctionne PAS
| Tentative | Erreur obtenue | Raison de l'echec |
|-----------|----------------|--------------------|
| curl depuis mcp-nas vers `172.17.0.1:3110` | timeout, exit 28 | le port est publie sur `192.168.100.33:3110`, pas sur `0.0.0.0` -- pas de route via le bridge docker0 interne pour un port bind sur une IP specifique |
| curl depuis mcp-nas vers `192.168.100.33:3110` en direct | timeout, exit 28 | pas de hairpin NAT container -> IP LAN de son propre hote sur Synology/docker bridge par defaut |
| Telechargement PDF via `page.goto(dl_url)` + `Browser.setDownloadBehavior` (CDP), reglages navigateur par defaut | `fichier non trouve sur disque apres 20s` -- 100% des `.pdf`, 0% des `.docx` | le lecteur PDF integre d'Edge intercepte l'ouverture et l'affiche inline au lieu de declencher un telechargement, meme avec `?download=1` dans l'URL et l'override CDP |
| `lookback_hours=0.01` (test de cas limite) | requete jamais retournee, CPU container a 224% pendant 6+ min | edge case non representatif d'un usage reel ; cause non investiguee plus avant -- eviter les fenetres tres courtes (<1h) meme en test |
---
## Solution validee
**1) Reglages navigateur (persistants, via VNC noVNC sur le port 8810) :**
- Desactiver l'ouverture des fichiers Office dans le navigateur.
- Activer "Toujours telecharger les fichiers PDF" et desactiver la reprise a la derniere position de lecture PDF.
- Ces reglages vivent dans `/data/profile` (volume hote persistant) -- pas besoin de les refaire a chaque
rebuild/restart.
**2) Authentification sur `/sharepoint-sync` (alignee sur la convention `/onedrive-sync` de nyora-notes-tt) :**
```bash
# cle generee une fois
openssl rand -hex 24
# ajoutee dans hermes-mail-browser/.env
SHAREPOINT_INGEST_KEY=<cle>
```
Cote code (`main.py`) : import `Header` depuis fastapi, nouvelle constante
`SHAREPOINT_INGEST_KEY = os.environ.get("SHAREPOINT_INGEST_KEY", "")`, verification en tete de
`sharepoint_sync()` : `HTTPException(401, ...)` si `x_ingest_key` absent ou different.
**3) Rebuild + redeploiement :**
```bash
ssh nas-host "cd /volume1/docker/hermes-mail-browser && nohup \
/volume1/@appstore/ContainerManager/usr/bin/docker compose build > /tmp/hmb-build.log 2>&1 &"
# suivre : ssh nas-host "tail -f /tmp/hmb-build.log"
ssh nas-host "cd /volume1/docker/hermes-mail-browser && \
/volume1/@appstore/ContainerManager/usr/bin/docker compose up -d"
```
**4) Workflow n8n cree et publie** : *hermes-tt -- Auto-sync SharePoint (delta -> archive locale)*
(id `pBF8OzVvPnGILGgj`), meme pattern de resilience que l'auto-sync OneDrive (`Q6ZAXgd8HYoQbk9K`) :
- Trigger planifie toutes les 60 min.
- `POST http://hermes-mail-browser:8000/sharepoint-sync?lookback_hours=2` (nom de service Docker,
reseau externe `n8n` partage).
- Header `X-Ingest-Key`.
- `options.timeout: 600000` (10 min), `response.neverError: true`, `retryOnFail: false`,
`onError: continueRegularOutput`.
---
## Verification
```bash
# Auth
curl -s -o /dev/null -w '%{http_code}' -X POST 'http://192.168.100.33:3110/sharepoint-sync?lookback_hours=2'
# -> 401 (sans cle)
curl -s -o /dev/null -w '%{http_code}' -X POST '...' -H 'X-Ingest-Key: mauvaise'
# -> 401
curl -s -X POST '...' -H 'X-Ingest-Key: <bonne-cle>'
# -> 200, JSON complet
```
Test reel sur 1 an d'historique : 12 candidats (PDF + docx) sur 3 sites actifs, **10 downloaded, 0 errors**
(les 2 restants = doublons deja presents sur disque, skip attendu). Fichiers verifies un par un sur disque :
noms et extensions corrects (PV d'ouverture, decisions de commission, rapports d'evaluation).
Execution n8n manuelle (id `36338`) : `status: success`, 111s, 22 sites scannes via le nom de service
Docker `hermes-mail-browser:8000` (resolution DNS interne confirmee), resultat JSON conforme,
`cutoff` calcule correctement a partir de `lookback_hours=2`.
---
## Pieges specifiques DSM / NAS
- Port publie sur une IP LAN specifique (`192.168.100.33:PORT`) plutot que `0.0.0.0:PORT` => inaccessible
depuis un autre container via `172.17.0.1` (bridge docker), et pas de hairpin NAT vers l'IP LAN de son
propre hote non plus. Pour tester ce genre d'endpoint depuis mcp-nas : toujours passer par
`ssh nas-host "curl ... 192.168.100.33:PORT/..."` (le curl part alors du host lui-meme).
- `start.sh` nettoie les verrous `Singleton*` et `X99` au demarrage -- necessaire pour un restart propre
apres un arret brutal (deja en place, ne pas retirer).
- Rebuild rapide (~20-30s) une fois les couches pip en cache ; le tout premier rebuild d'une session
(cache purge) peut prendre plusieurs minutes -- ne pas s'inquieter si le premier est plus long.
- Un `POST /sharepoint-sync` en cours (verrou `sp_sync_lock`) fait attendre 423 "deja en cours" a toute
requete concurrente -- normal, mais ne pas empiler des tests avec des `-m` trop courts en pensant
relancer un run frais : c'est le meme run qui continue derriere.
- Le scan complet des 22 sites prend 90-120s meme quand `candidats=0` partout (navigation reelle
site par site) -- prevoir un timeout client genereux (>=150s) pour tout test manuel.
---
## References
- Workflow n8n jumeau : *nyora-notes-tt -- Auto-sync OneDrive* (`Q6ZAXgd8HYoQbk9K`)
- Code source : `/volume1/docker/hermes-mail-browser/app/main.py`
(fonctions `sp_sync_site_delta`, `sharepoint_sync`, `SHAREPOINT_SITES`)
- Nouveau workflow : https://n8n.nd.i234.me/workflow/pBF8OzVvPnGILGgj