ServicesÀ proposNotesContact Me contacter →
EN FR
Note

Déduplication de flux RSS dans n8n

Comment éviter les pages Notion en double lors du polling de flux RSS dans n8n, en utilisant un nœud Merge configuré comme une jointure anti-gauche.

Planté
automationdata engineering

Les workflows de polling RSS rencontrent à nouveau des articles déjà traités à chaque exécution, puisque les articles restent dans les flux après traitement. Sans déduplication, exécuter le workflow plusieurs fois crée des pages Notion en double.

La solution est la déduplication via une jointure anti-gauche : récupérer les enregistrements existants, récupérer les nouveaux éléments, et ne laisser passer que les éléments qui apparaissent dans le nouveau lot mais pas dans les enregistrements existants.

Le concept de jointure

Une jointure anti-gauche est une opération ensembliste qui retourne les lignes de la table gauche n’ayant pas de ligne correspondante dans la table droite. C’est le complément d’une jointure interne.

En termes SQL :

-- Retourner uniquement les nouveaux articles (ceux qui ne sont pas déjà dans Notion)
SELECT feed.link
FROM rss_feed AS feed
LEFT JOIN existing_notion_articles AS existing
ON feed.link = existing.content_url
WHERE existing.content_url IS NULL

n8n n’écrit pas de SQL, mais son nœud Merge peut effectuer cette opération exacte visuellement.

Configuration du nœud Merge dans n8n

Le workflow utilise deux nœuds alimentant le nœud Merge :

Entrée 1 (côté gauche) : Get All Articles — interroge votre base de données de contenu Notion pour tous les articles RSS existants. Filtre sur type = "RSS" pour ne retourner que les articles précédemment ingérés. Chaque enregistrement expose un champ property_content_url (l’URL de l’article original stockée comme propriété Notion).

Entrée 2 (côté droit) : Les éléments du flux RSS divisés issus de l’exécution courante. Chaque élément a un champ link provenant du XML RSS.

Configuration du nœud Merge :

Mode: Combine
Combine by: Matching rules
- Input 1 field: property_content_url
- Input 2 field: link
Join mode: Keep Non Matches
Output from: Input 2

Keep Non Matches avec Output from: Input 2 signifie : donnez-moi les éléments du flux RSS qui n’ont PAS correspondance dans Notion. Ce sont les nouveaux articles. Tout le reste est supprimé.

L’indicateur executeOnce

Il y a un détail critique dans le nœud Get All Articles : executeOnce: true.

Sans cela, n8n interrogerait Notion une fois par élément RSS lors du traitement du flux divisé. Si vous avez 50 articles de 5 flux, cela représente 50 requêtes Notion identiques. C’est inutile, lent et susceptible d’atteindre les limites de débit de l’API.

Avec executeOnce: true, le nœud s’exécute une seule fois au début et ses résultats sont mis en cache pour l’ensemble du lot. Le nœud Merge compare ensuite tous les éléments RSS entrants à cet instantané unique en un seul passage.

Cela compte plus qu’il n’y paraît. À l’échelle (plusieurs flux, beaucoup d’articles), la différence entre O(n) appels API et O(1) est la différence entre un workflow qui se termine en quelques secondes et un qui expire.

Pourquoi l’URL est la bonne clé de déduplication

Le workflow utilise l’URL de l’article (link dans RSS, property_content_url dans Notion) comme clé de déduplication plutôt que le titre ou la date de publication.

Les titres peuvent changer — les éditeurs mettent parfois à jour un titre après publication. Les dates peuvent être ambiguës — pubDate n’est pas toujours fiable, et le même article peut apparaître dans plusieurs flux avec des timestamps différents. L’URL est stable. L’URL canonique d’un article ne change pas.

Un cas limite : les paramètres de tracking. Une URL comme https://exemple.com/article?utm_source=feed et https://exemple.com/article?utm_source=twitter sont techniquement des URLs différentes pointant vers le même contenu. Si vos sources RSS incluent des liens avec des paramètres de tracking, vous devrez supprimer les paramètres de requête avant la comparaison. Pour la plupart des flux RSS de blogs, ce n’est pas un problème — les liens sont propres.

Ce qui passe

Après le nœud Merge, seuls les articles qui n’existent pas encore dans Notion continuent en aval. Tout le reste est silencieusement supprimé — pas d’erreur, pas de flag, juste filtré.

Cela rend le workflow naturellement idempotent. Vous pouvez l’exécuter plusieurs fois dans la même journée (ou le ré-exécuter après un échec) et il ne créera pas de doublons. Les articles déjà dans Notion sont simplement ignorés.

L’idempotence est la propriété que vous voulez dans tout pipeline planifié. Elle signifie que « ré-exécuter » est toujours sans risque, ce qui simplifie beaucoup le débogage et la récupération. Le même principe apparaît dans le chargement incrémental dlt et les modèles incrémentaux idempotents dans dbt — des outils différents, la même idée.

Le flux de déduplication complet

Éléments flux RSS (50 articles de 5 flux)
↓ Split Out RSS Feed
50 éléments individuels, chacun avec : title, link, pubDate, dc:creator
├──────────────────────────────────────┐
│ │
Get All Articles from Notion (continue en aval)
(s'exécute une fois, retourne toutes les URLs existantes)
└──────────────────────────────────────┘
Nœud Merge
(jointure anti-gauche sur URL)
Seuls les vrais nouveaux articles passent
(ex. 12 sur 50 si 38 existent déjà)

Limitations

L’approche nécessite que votre base de données Notion soit la source de vérité de ce qui a été traité. Si vous supprimez des enregistrements de Notion, ces articles seront ré-récupérés à la prochaine exécution. C’est généralement acceptable pour une base de connaissances personnelle, mais vaut la peine d’être connu.

Cela signifie également que la première exécution — quand Notion est vide — importera en masse l’intégralité de l’historique de chaque flux RSS (aussi loin que remonte le flux, typiquement 10 à 50 articles par source). La plupart du temps c’est souhaitable : vous voulez une import en masse pour amorcer la base de données. Si vous ne voulez pas d’articles historiques, vous pouvez ajouter un filtre pubDate pour ne traiter que les articles plus récents qu’une certaine date.

Associé