Help: dedicated webhooks section with examples, event table, API details
This commit is contained in:
+129
-10
@@ -798,6 +798,7 @@
|
||||
<li><a href="#help-palette" class="help-nav-link">⌨️ Palette</a></li>
|
||||
<li><a href="#help-raccourcis" class="help-nav-link">⌨️ Raccourcis</a></li>
|
||||
<li><a href="#help-partage" class="help-nav-link">🔗 Partage</a></li>
|
||||
<li><a href="#help-webhooks" class="help-nav-link">🪝 Webhooks</a></li>
|
||||
<li><a href="#help-sauvegardes" class="help-nav-link">💾 Sauvegardes</a></li>
|
||||
<li><a href="#help-securite" class="help-nav-link">🛡️ Sécurité</a></li>
|
||||
<li><a href="#help-personnalisation" class="help-nav-link">🎨 Personnalisation</a></li>
|
||||
@@ -1319,18 +1320,136 @@
|
||||
<li><strong>Gestion des liens</strong> : Liste et révocation dans les Configurations</li>
|
||||
<li><strong>Export PDF</strong> : Téléchargement du document partagé en PDF via <code>/s/{token}/pdf</code></li>
|
||||
</ul>
|
||||
|
||||
<h3>Webhooks</h3>
|
||||
<p>Les webhooks notifient des services externes lors des changements de fichiers.</p>
|
||||
<ul>
|
||||
<li><strong>Événements</strong> : Création, modification, suppression, renommage</li>
|
||||
<li><strong>Format</strong> : POST JSON avec détails complets de l'événement</li>
|
||||
<li><strong>Signature HMAC-SHA256</strong> : Optionnelle pour vérifier l'origine</li>
|
||||
<li><strong>Configuration</strong> : Gestion via le modal Configurations</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<!-- 💾 Sauvegardes -->
|
||||
<!-- 🪝 Webhooks -->
|
||||
<section class="help-section" id="help-webhooks">
|
||||
<h2>🪝 Webhooks</h2>
|
||||
<p>Les webhooks permettent à ObsiGate de <strong>notifier automatiquement des services externes</strong> lorsque des fichiers ou dossiers sont modifiés. Chaque événement déclenche un <code>POST</code> HTTP vers l'URL de votre choix, avec un payload JSON détaillé.</p>
|
||||
|
||||
<h3>Cas d'usage</h3>
|
||||
<ul>
|
||||
<li><strong>Automatisation CI/CD</strong> : Déclencher un build quand une note de procédure est mise à jour</li>
|
||||
<li><strong>Synchronisation</strong> : Copier les nouveaux fichiers vers un autre système (SharePoint, Google Drive)</li>
|
||||
<li><strong>Notifications</strong> : Alerter un canal Slack/Discord quand un document est créé</li>
|
||||
<li><strong>Audit externe</strong> : Logger toutes les modifications dans une base de données externe</li>
|
||||
<li><strong>Déploiement</strong> : Publier un article de blog quand un fichier est marqué <code>publish: true</code></li>
|
||||
</ul>
|
||||
|
||||
<h3>Événements supportés</h3>
|
||||
<div style="overflow-x:auto">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:0.85rem;margin:8px 0 16px">
|
||||
<tr style="background:var(--bg-secondary)">
|
||||
<th style="padding:8px 12px;text-align:left;border-bottom:1px solid var(--border)">Événement</th>
|
||||
<th style="padding:8px 12px;text-align:left;border-bottom:1px solid var(--border)">Déclencheur</th>
|
||||
<th style="padding:8px 12px;text-align:left;border-bottom:1px solid var(--border)">Données</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:8px 12px;border-bottom:1px solid var(--border)"><code>file_created</code></td>
|
||||
<td style="padding:8px 12px;border-bottom:1px solid var(--border)">Création via l'API ou la palette</td>
|
||||
<td style="padding:8px 12px;border-bottom:1px solid var(--border)"><code>vault</code>, <code>path</code></td>
|
||||
</tr>
|
||||
<tr style="background:var(--bg-secondary)">
|
||||
<td style="padding:8px 12px;border-bottom:1px solid var(--border)"><code>file_deleted</code></td>
|
||||
<td style="padding:8px 12px;border-bottom:1px solid var(--border)">Suppression via l'API ou l'éditeur</td>
|
||||
<td style="padding:8px 12px;border-bottom:1px solid var(--border)"><code>vault</code>, <code>path</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:8px 12px;border-bottom:1px solid var(--border)"><code>file_renamed</code></td>
|
||||
<td style="padding:8px 12px;border-bottom:1px solid var(--border)">Renommage via l'API</td>
|
||||
<td style="padding:8px 12px;border-bottom:1px solid var(--border)"><code>vault</code>, <code>old_path</code>, <code>new_path</code></td>
|
||||
</tr>
|
||||
<tr style="background:var(--bg-secondary)">
|
||||
<td style="padding:8px 12px;border-bottom:1px solid var(--border)"><code>directory_created</code></td>
|
||||
<td style="padding:8px 12px;border-bottom:1px solid var(--border)">Création de dossier via l'API</td>
|
||||
<td style="padding:8px 12px;border-bottom:1px solid var(--border)"><code>vault</code>, <code>path</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:8px 12px;border-bottom:1px solid var(--border)"><code>directory_deleted</code></td>
|
||||
<td style="padding:8px 12px;border-bottom:1px solid var(--border)">Suppression de dossier via l'API</td>
|
||||
<td style="padding:8px 12px;border-bottom:1px solid var(--border)"><code>vault</code>, <code>path</code></td>
|
||||
</tr>
|
||||
<tr style="background:var(--bg-secondary)">
|
||||
<td style="padding:8px 12px;border-bottom:1px solid var(--border)"><code>directory_renamed</code></td>
|
||||
<td style="padding:8px 12px;border-bottom:1px solid var(--border)">Renommage de dossier via l'API</td>
|
||||
<td style="padding:8px 12px;border-bottom:1px solid var(--border)"><code>vault</code>, <code>old_path</code>, <code>new_path</code></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<p><em>Note : l'événement <code>file_modified</code> est réservé pour usage futur. Les modifications de contenu via l'éditeur ne déclenchent pas encore de webhook.</em></p>
|
||||
|
||||
<h3>Format du payload</h3>
|
||||
<p>Chaque webhook reçoit un <code>POST</code> avec <code>Content-Type: application/json</code> :</p>
|
||||
<pre style="background:var(--bg-secondary);padding:12px;border-radius:8px;overflow-x:auto;font-size:0.78rem"><code>{
|
||||
"event": "file_created",
|
||||
"timestamp": "2026-06-03T14:30:00.123456+00:00",
|
||||
"data": {
|
||||
"vault": "IT",
|
||||
"path": "procedures/deploiement.md"
|
||||
}
|
||||
}</code></pre>
|
||||
|
||||
<h3>Sécurité : signature HMAC-SHA256</h3>
|
||||
<p>Si vous configurez un secret, chaque requête inclut un header <code>X-ObsiGate-Signature</code> :</p>
|
||||
<pre style="background:var(--bg-secondary);padding:12px;border-radius:8px;overflow-x:auto;font-size:0.78rem"><code>X-ObsiGate-Signature: sha256=9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08</code></pre>
|
||||
<p>Pour vérifier côté récepteur : calculez <code>HMAC-SHA256(corps_brut, secret)</code> et comparez. Le header <code>X-ObsiGate-Event</code> contient aussi le type d'événement pour un routage rapide.</p>
|
||||
|
||||
<h3>Configuration</h3>
|
||||
<p>Les webhooks se gèrent dans le modal <strong>Configurations</strong> (⚙️ menu Options), section Webhooks. Réservé aux administrateurs.</p>
|
||||
<ol>
|
||||
<li>Allez dans ⚙️ Configurations → onglet Webhooks</li>
|
||||
<li>Remplissez : <strong>Nom</strong> (descriptif), <strong>URL</strong> (endpoint cible), <strong>Secret</strong> (optionnel)</li>
|
||||
<li>Cochez les événements à écouter</li>
|
||||
<li>Cliquez <strong>Ajouter</strong></li>
|
||||
</ol>
|
||||
<p>Les webhooks peuvent être activés/désactivés, modifiés ou supprimés à tout moment. Le <code>last_fired_at</code> indique la dernière exécution.</p>
|
||||
|
||||
<h3>Exemples concrets</h3>
|
||||
|
||||
<h4>Récepteur Python (Flask)</h4>
|
||||
<pre style="background:var(--bg-secondary);padding:12px;border-radius:8px;overflow-x:auto;font-size:0.78rem"><code>from flask import Flask, request\nimport hmac, hashlib\n\napp = Flask(__name__)\nWEBHOOK_SECRET = "mon-secret" # même que dans ObsiGate\n\[email protected]("/webhook", methods=["POST"])\ndef webhook():\n # Vérifier la signature\n signature = request.headers.get("X-ObsiGate-Signature", "")\n body = request.get_data()\n expected = "sha256=" + hmac.new(\n WEBHOOK_SECRET.encode(), body, hashlib.sha256\n ).hexdigest()\n if not hmac.compare_digest(signature, expected):\n return "Invalid signature", 403\n\n payload = request.get_json()\n print(f"Événement: {payload['event']}")\n print(f"Fichier: {payload['data']['vault']}/{payload['data']['path']}")\n return "OK", 200\n\napp.run(port=5000)</code></pre>
|
||||
|
||||
<h4>n8n / Make (no-code)</h4>
|
||||
<ol>
|
||||
<li>Créez un <strong>Webhook Trigger</strong> dans n8n ou Make</li>
|
||||
<li>Copiez l'URL générée (ex: <code>https://n8n.monserveur.com/webhook/abc123</code>)</li>
|
||||
<li>Dans ObsiGate, ajoutez un webhook pointant vers cette URL</li>
|
||||
<li>Sélectionnez les événements souhaités</li>
|
||||
<li>Le workflow se déclenche automatiquement à chaque événement</li>
|
||||
</ol>
|
||||
|
||||
<h4>Notification Discord</h4>
|
||||
<p>Utilisez un webhook relais (n8n, Make, ou un script) pour transformer le payload ObsiGate en message Discord :</p>
|
||||
<pre style="background:var(--bg-secondary);padding:12px;border-radius:8px;overflow-x:auto;font-size:0.78rem"><code># Exemple avec curl + jq dans un script bash
|
||||
WEBHOOK_URL="https://discord.com/api/webhooks/..."
|
||||
OBSIGATE_SECRET="mon-secret"
|
||||
|
||||
# Lire le payload depuis stdin
|
||||
read -r payload
|
||||
event=$(echo "$payload" | jq -r '.event')
|
||||
path=$(echo "$payload" | jq -r '.data.path')
|
||||
|
||||
curl -H "Content-Type: application/json" -d "{
|
||||
\"content\": \"📝 **$event** — $path\"
|
||||
}" "$WEBHOOK_URL"</code></pre>
|
||||
|
||||
<h4>Tester avec curl</h4>
|
||||
<pre style="background:var(--bg-secondary);padding:12px;border-radius:8px;overflow-x:auto;font-size:0.78rem"><code># Simuler ce qu'ObsiGate envoie (pour tester votre endpoint)
|
||||
curl -X POST https://votre-serveur.com/webhook \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-ObsiGate-Event: file_created" \
|
||||
-H "X-ObsiGate-Signature: sha256=$(echo -n '{"event":"file_created",...}' | openssl dgst -sha256 -hmac 'mon-secret' | cut -d' ' -f2)" \
|
||||
-d '{"event":"file_created","timestamp":"2026-06-03T14:30:00Z","data":{"vault":"IT","path":"notes/test.md"}}'</code></pre>
|
||||
|
||||
<h3>Limitations actuelles</h3>
|
||||
<ul>
|
||||
<li>Timeout de <strong>5 secondes</strong> par requête — les webhooks sont "fire and forget" (pas de retry)</li>
|
||||
<li>Les modifications détectées par le watcher filesystem (watchdog) <strong>ne déclenchent pas</strong> de webhooks — seules les opérations via l'API REST sont prises en compte</li>
|
||||
<li><code>file_modified</code> n'est pas encore dispatché (réservé pour version future)</li>
|
||||
<li>Pas de retry automatique en cas d'échec</li>
|
||||
<li>Pas de filtrage par vault — un webhook écoute toutes les vaults</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="help-section" id="help-sauvegardes">
|
||||
<h2>💾 Sauvegardes et Audits</h2>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user