Aller au contenu

Notification Hub

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.

WorkflowNodesRôle
Notification Hub (parent)41Dedup + quiet hours + format + send multi-canal
NH Callback Handler (9Xb3mplmzE5994bi)18Ack, approve, retry, ignore, delivery callbacks
SourceType d’événements
Docker DIUNNouvelles versions d’images, demandes d’approbation
AlertmanagerAlertes Prometheus (CPU, RAM, disk)
Health CheckStatus des services
Global Error HandlerErreurs N8N classifiées avec actions [Retry] [Details] [Ignore] [Fix]
Security CVE WatchAlertes CRITICAL + digest hebdomadaire
Workflows N8NRésultats d’exécution, événements business
CanalUsage
TelegramPrincipal, notifications interactives avec boutons
ntfyBackup push mobile (canal CRITICAL)
DiscordOptionnel, pour équipes

Canaux

Notification Hub · 41 nodes

No

Yes

NH Callback Handler · 18 nodes

Parse Callback

Ack

Approve

Retry

Ignore

Sources

Docker DIUN

Alertmanager

Health Check

Global Error Handler

Security CVE Watch

Workflows N8N divers

Webhook / Execute Workflow

Is Callback?

Validate Payload

Deduplication · Redis

Quiet Hours

Format per Channel

Send Multi-canal

Insert History DT

Telegram · boutons inline

ntfy · push mobile

Discord


ProblèmeSans hubAvec hub
Spam de notificationsChaque service notifie indépendammentPoint unique de sortie contrôlé
DoublonsMême alerte envoyée plusieurs foisDéduplication par clé + TTL
Alertes nocturnesRéveillé pour un warningQuiet hours pour non-critiques
Pas d’auditNotifications perduesHistorique complet en base
Boutons cassésLogique callback disperséeSub-workflow dédié réutilisable

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ômeCause
Double-trigger ambiguWebhook 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 difficilesTester 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.

FonctionBénéfice
DéduplicationÉvite les notifications en double sur une fenêtre de temps
Quiet HoursNotifications non-critiques différées 22h-8h
Multi-canalTelegram + ntfy + Discord selon la sévérité
HistoriqueToutes les notifications stockées pour audit
Callbacks routésBypass dedup pour boutons Telegram, sub-workflow extraite

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.

// Clé de déduplication
const 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] });
HeureInfoWarningCritical
08h-22hImmédiatImmédiatImmédiat
22h-08hQueueQueueImmé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.

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 :

Yes

No

Webhook

source = telegram_callback ?

NH Callback Handler · 18n

Validate → Dedup → Quiet → Format → Send

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.

{
"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évérité par défautOrigine
update_success / update_failed / update_queuedinfo / critical / infoDocker Updates
approval_requestwarningDocker Updates, GEH Fix Applier
alert_prometheusvariableAlertmanager
container_downcriticalHealth Check
error_classifiedvariableGlobal Error Handler
cve_alertcriticalSecurity CVE Watch

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 :

Fenêtre de terminal
curl -X POST http://n8n:5678/webhook/notification-hub \
-H "Content-Type: application/json" \
-d '{"type":"custom","severity":"info","title":"Test","message":"Hello"}'

Table notification_history (PostgreSQL N8N) :

ColonneTypeDescription
idUUIDIdentifiant unique
typeTextType de notification
severityTextinfo / warning / critical
payloadJSONBContenu complet
channelsArrayCanaux utilisés
sent_atTimestampDate d’envoi effective
deferredBooleanSi différé pendant quiet hours
dedupe_keyTextClé de déduplication
callback_resultsJSONBRéponses aux boutons (cumulatif)

LimiteImpactMitigation
Redis single-instancePerte du cache si Redis downNotification envoyée (pas de dédupe) — fail-open
Pas d’escalade automatiqueAlertes non acquittées restent warningPrévu mais non implémenté
Quiet hours fixesPas de configuration par utilisateurSuffisant pour usage solo
Callback timeoutSi l’utilisateur ne clique jamais, le state reste pendingTTL 7j sur les callbacks dans la DT

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)

  • Glossaire — Webhook, Deduplication, Quiet Hours