Notification Hub
1. Quoi ? — Définition et contexte
Section intitulée « 1. Quoi ? — Définition et contexte »Le Notification Hub est le workflow N8N qui centralise toutes les notifications de l’infrastructure. Il dédoublonne les alertes, applique les quiet hours, route vers les bons canaux, et délègue les callbacks à un sub-workflow dédié extrait depuis le refactoring #276.
Composants
Section intitulée « Composants »| Workflow | Nodes | Rôle |
|---|---|---|
| Notification Hub (parent) | 41 | Dedup + quiet hours + format + send multi-canal |
NH Callback Handler (9Xb3mplmzE5994bi) | 18 | Ack, approve, retry, ignore, delivery callbacks |
Sources de notifications
Section intitulée « Sources de notifications »| Source | Type d’événements |
|---|---|
| Docker DIUN | Nouvelles versions d’images, demandes d’approbation |
| Alertmanager | Alertes Prometheus (CPU, RAM, disk) |
| Health Check | Status des services |
| Global Error Handler | Erreurs N8N classifiées avec actions [Retry] [Details] [Ignore] [Fix] |
| Security CVE Watch | Alertes CRITICAL + digest hebdomadaire |
| Workflows N8N | Résultats d’exécution, événements business |
Canaux de sortie
Section intitulée « Canaux de sortie »| Canal | Usage |
|---|---|
| Telegram | Principal, notifications interactives avec boutons |
| ntfy | Backup push mobile (canal CRITICAL) |
| Discord | Optionnel, pour équipes |
Architecture visuelle
Section intitulée « Architecture visuelle »2. Pourquoi ? — Enjeux et motivations
Section intitulée « 2. Pourquoi ? — Enjeux et motivations »Problèmes résolus
Section intitulée « Problèmes résolus »| Problème | Sans hub | Avec hub |
|---|---|---|
| Spam de notifications | Chaque service notifie indépendamment | Point unique de sortie contrôlé |
| Doublons | Même alerte envoyée plusieurs fois | Déduplication par clé + TTL |
| Alertes nocturnes | Réveillé pour un warning | Quiet hours pour non-critiques |
| Pas d’audit | Notifications perdues | Historique complet en base |
| Boutons cassés | Logique callback dispersée | Sub-workflow dédié réutilisable |
Pourquoi extraire un Callback Handler (#276) ?
Section intitulée « Pourquoi extraire un Callback Handler (#276) ? »Le hub initial mélangeait l’ingestion de notifications et la gestion des callbacks Telegram dans un seul workflow de 57 nodes. Trois symptômes ont déclenché l’extraction :
| Symptôme | Cause |
|---|---|
| Double-trigger ambigu | Webhook entrant pouvait être une nouvelle notif OU un callback |
| Dedup bypass mal géré | Les callbacks ne devaient pas passer par dedup mais le code le faisait parfois |
| Tests difficiles | Tester un callback impliquait d’envoyer une vraie notif d’abord |
L’extraction en sub-workflow NH Callback Handler (18 nodes, ID 9Xb3mplmzE5994bi) résout ces tensions : le parent route en début de chaîne via Is Callback?, et les callbacks bypassent dedup + quiet hours.
Fonctionnalités clés
Section intitulée « Fonctionnalités clés »| Fonction | Bénéfice |
|---|---|
| Déduplication | Évite les notifications en double sur une fenêtre de temps |
| Quiet Hours | Notifications non-critiques différées 22h-8h |
| Multi-canal | Telegram + ntfy + Discord selon la sévérité |
| Historique | Toutes les notifications stockées pour audit |
| Callbacks routés | Bypass dedup pour boutons Telegram, sub-workflow extraite |
3. Comment ? — Mise en œuvre technique
Section intitulée « 3. Comment ? — Mise en œuvre technique »Le parcours d’une notification
Section intitulée « Le parcours d’une notification »1. Réception — Le hub reçoit via webhook /webhook/notification-hub (interne uniquement) ou via Execute Workflow.
2. Is Callback? — Détection précoce : si le payload contient un callback_data Telegram, route vers NH Callback Handler. Bypasse dedup + quiet hours.
3. Validation — Type requis, severity valide (info / warning / critical), format JSON conforme.
4. Déduplication — Calcul d’une clé <type>:<container>:<severity>, lookup Redis, skip si présent.
5. Quiet Hours — Si l’heure est entre 22h et 8h ET la severity n’est pas critical, marquer deferred=true et différer.
6. Format — Template par type et canal (Telegram HTML, Discord embed, ntfy texte).
7. Send multi-canal — Telegram toujours, ntfy si critical, Discord si configuré.
8. Historisation — Insert dans notification_history avec dedup_key, channels, timestamp.
Déduplication
Section intitulée « Déduplication »// Clé de déduplicationconst dedupeKey = `${type}:${container}:${severity}`;
// TTL variable selon la sévéritéconst ttl = { info: 3600, // 1 heure warning: 1800, // 30 min critical: 300 // 5 min};
const existing = await redis.get(dedupeKey);if (existing) { return { skipped: true, reason: 'duplicate' };}
await redis.set(dedupeKey, Date.now(), { EX: ttl[severity] });Quiet Hours
Section intitulée « Quiet Hours »| Heure | Info | Warning | Critical |
|---|---|---|---|
| 08h-22h | Immédiat | Immédiat | Immédiat |
| 22h-08h | Queue | Queue | Immédiat |
Les notifications différées sont stockées dans une Data Table pending_notifications et envoyées au prochain passage à 8h via le workflow Deferred Sender.
Bypass callbacks
Section intitulée « Bypass callbacks »Les callbacks Telegram (boutons inline) reviennent au hub via le même webhook. Le node Is Callback? (IF en début de chaîne) les détecte par la présence de source='telegram_callback' ou de callback_query dans le payload :
Sans ce bypass, un clic sur [Retry] à 23h serait dédupliqué avec la notification originale ou différé jusqu’au matin — ce qui casserait l’UX.
Format d’entrée
Section intitulée « Format d’entrée »{ "type": "update_success", "severity": "info", "title": "Docker Update réussi", "message": "n8n-stack mis à jour vers 1.73.0", "container": "n8n", "image": "n8nio/n8n:1.73.0", "project": "n8n-stack", "timestamp": "2026-01-20T10:30:00.000Z", "callback_actions": [ { "label": "Détails", "callback": "notif_details_<id>" }, { "label": "Ignorer", "callback": "notif_ignore_<id>" } ], "metadata": { "duration_seconds": 45, "previous_version": "1.72.0" }}Types supportés
Section intitulée « Types supportés »| Type | Sévérité par défaut | Origine |
|---|---|---|
update_success / update_failed / update_queued | info / critical / info | Docker Updates |
approval_request | warning | Docker Updates, GEH Fix Applier |
alert_prometheus | variable | Alertmanager |
container_down | critical | Health Check |
error_classified | variable | Global Error Handler |
cve_alert | critical | Security CVE Watch |
Appel du hub
Section intitulée « Appel du hub »Depuis un workflow N8N (Execute Workflow) :
{ "workflowId": { "__rl": true, "value": "<notification-hub-id>", "mode": "id" }, "inputData": { "type": "update_success", "severity": "info", "title": "...", "message": "..." }}Via webhook interne :
curl -X POST http://n8n:5678/webhook/notification-hub \ -H "Content-Type: application/json" \ -d '{"type":"custom","severity":"info","title":"Test","message":"Hello"}'Historisation
Section intitulée « Historisation »Table notification_history (PostgreSQL N8N) :
| Colonne | Type | Description |
|---|---|---|
id | UUID | Identifiant unique |
type | Text | Type de notification |
severity | Text | info / warning / critical |
payload | JSONB | Contenu complet |
channels | Array | Canaux utilisés |
sent_at | Timestamp | Date d’envoi effective |
deferred | Boolean | Si différé pendant quiet hours |
dedupe_key | Text | Clé de déduplication |
callback_results | JSONB | Réponses aux boutons (cumulatif) |
4. Et si ? — Perspectives et limites
Section intitulée « 4. Et si ? — Perspectives et limites »Limites actuelles
Section intitulée « Limites actuelles »| Limite | Impact | Mitigation |
|---|---|---|
| Redis single-instance | Perte du cache si Redis down | Notification envoyée (pas de dédupe) — fail-open |
| Pas d’escalade automatique | Alertes non acquittées restent warning | Prévu mais non implémenté |
| Quiet hours fixes | Pas de configuration par utilisateur | Suffisant pour usage solo |
| Callback timeout | Si l’utilisateur ne clique jamais, le state reste pending | TTL 7j sur les callbacks dans la DT |
Scénarios d’évolution
Section intitulée « Scénarios d’évolution »Si besoin d’escalade automatique :
- Tracker les alertes non acquittées dans
pending_notifications - Après délai configurable, passer en
critical→ ntfy + appel Twilio optionnel - Dashboard Grafana avec heatmap des alertes ignorées
Si volume de notifications augmente :
- Agrégation par batch (résumé toutes les heures pour les
info) - Digest quotidien pour les notifications non urgentes
- Filtrage par abonnement (opt-in par type via Data Table)
Si équipe multi-utilisateurs :
- Configuration quiet hours par utilisateur (Data Table
notification_routing) - Routage selon l’utilisateur de garde
- Acquittements partagés (un acquit suffit)
Pages liées
Section intitulée « Pages liées »Infrastructure
Section intitulée « Infrastructure »- N8N en mode Queue — Backend automation
- Monitoring Stack — Source Prometheus
- Notify Stack — DIUN et ntfy
Workflows
Section intitulée « Workflows »- Telegram Orchestrator — Réception des callbacks
- Docker Updates — Source DIUN + approval
- Error Handler — Notifie via Hub avec boutons d’action
Référence
Section intitulée « Référence »- Glossaire — Webhook, Deduplication, Quiet Hours