▸ // rozdziały lekcji


Czytnik RSS bez sita zamienia się w śmietnik po tygodniu. Każde uruchomienie przynosi te same wpisy co wczoraj, a ty przewijasz je drugi, trzeci, piąty raz, żeby znaleźć dwa nowe.
Ten workflow co 12 godzin czyta twoje kanały, odrzuca wpisy starsze niż tydzień i dopisuje do tabeli tylko te, których jeszcze w niej nie było. Wszystko ląduje w Data Tables, wbudowanych tabelach n8n. Bez Notiona, bez arkusza, bez żadnego konta.
W teście dwa kanały dały 9 wpisów z ostatnich 7 dni. Drugie uruchomienie zaraz po pierwszym: 0 nowych.
Co robi ten workflow
- Co 12 godzin - harmonogram, odpala się co 12 godzin w 15. minucie.
- Przygotuj tabele - Data Table z operacją Create zakłada tabelę rss_wpisy z kolumnami tytul, link, zrodlo, opublikowano i dodano. Jeśli tabela już jest, używa istniejącej.
- Kanaly RSS - Edit Fields z listą adresów kanałów w polu
kanalyi liczbą dni wstecz w poludni_wstecz(7). - Rozbij kanaly - Split Out robi z listy osobne items, po jednym na kanał, w polu
kanal. - Czytaj kanal - RSS Read pobiera wpisy z każdego kanału.
- Tylko swieze - Filter przepuszcza wpisy opublikowane w ciągu ostatnich
dni_wsteczdni. - Czy nowy wpis? - Data Table z operacją Row Not Exists przepuszcza tylko wpisy, których linku nie ma jeszcze w tabeli.
- Zapisz wpis - Data Table z operacją Insert dopisuje wiersz.
Czego potrzebujesz
Niczego poza n8n. Kanały RSS są publiczne, tabela powstaje sama. Zero kont i kluczy.
Jak uruchomić
- Zaimportuj plik z dołu lekcji (jak importować workflow).
- Otwórz węzeł Kanaly RSS i wpisz swoje kanały w polu
kanaly. To tablica adresów w nawiasach kwadratowych, każdy adres w cudzysłowie, oddzielone przecinkami. W pliku są dwa: blog n8n i Niebezpiecznik. - Ustaw
dni_wstecz, jeśli tydzień ci nie pasuje. - Kliknij Execute workflow.
- Zajrzyj do tabeli: Overview > zakładka Data tables > rss_wpisy.
- Jeśli wynik się zgadza, kliknij Publish. Harmonogram działa dopiero po publikacji (interfejs i publikacja).

Tabela zakłada się sama
Pierwszy węzeł po harmonogramie to Data Table z zasobem Table i operacją Create. Ma włączoną opcję Reuse Existing Tables. Przy pierwszym uruchomieniu zakłada tabelę, przy każdym kolejnym bierze istniejącą.
Haczyk. Bez jawnie włączonej opcji Reuse Existing Tables drugie uruchomienie kończy się błędem „Data table with name 'rss_wpisy' already exists in this project". Sprawdziłem to w teście. W pliku z tej lekcji opcja jest włączona. Jeśli budujesz taki węzeł od zera, włącz ją sam.
Pozostałe węzły Data Table wskazują tabelę po nazwie, w trybie By Name. Dzięki temu nie musisz nic wybierać z listy po imporcie.
Świeże i nowe - dwa sita
Filtr „Tylko swieze" porównuje datę wpisu z datą sprzed tygodnia:
{{ $json.isoDate }} jest po {{ $now.minus({days: $('Kanaly RSS').first().json.dni_wstecz}).toISO() }}isoDate to data publikacji, którą RSS Read oddaje w jednolitym formacie. $('Kanaly RSS').first() sięga po liczbę dni do węzła z ustawieniami. Bez tego sita pierwsze uruchomienie wciągnęłoby całe archiwum kanału, czyli tyle wpisów, ile kanał akurat pokazuje.
Drugie sito to Row Not Exists po kolumnie link. Dla każdego wpisu węzeł pyta tabelę, czy jest w niej wiersz z takim samym linkiem. Jeśli nie ma - wpis idzie dalej do zapisu. Jeśli jest - odpada. Tak działa deduplikacja: drugie uruchomienie nie dopisuje duplikatów.
Kolejność ma znaczenie. Najpierw odcinasz po dacie, potem pytasz tabelę. Odwrotnie pytałbyś tabelę o każdy stary wpis z archiwum.
Kolumnę zrodlo wypełnia wyrażenie {{ $('Rozbij kanaly').item.json.kanal.split('/')[2] }}. Dzieli adres kanału po ukośnikach i bierze trzeci kawałek, czyli domenę, na przykład „blog.n8n.io".
Pro-tip. Węzeł Czytaj kanal ma w ustawieniach On Error na Continue. Jeden martwy kanał na liście nie zatrzymuje pozostałych. Jeśli któryś kanał przestał dawać wpisy, otwórz ostatnie wykonanie i sprawdź, co oddał ten węzeł.
Haczyki z testów
Haczyk. Niebezpiecznik ma swój kanał pod niebezpiecznik.pl/feed/, ale ten adres przekierowuje na FeedBurnera. Dlatego w liście stoi feeds.feedburner.com/niebezpiecznik/. Jeśli twój kanał nie oddaje wpisów, otwórz jego adres w przeglądarce i sprawdź, dokąd cię przeniosło.
Haczyk. Niektóre kanały mają w tytułach encje HTML zamiast znaków, na przykład
“zamiast cudzysłowu. Tak było u Niebezpiecznika. Tytuł trafia do tabeli dokładnie w tej postaci.

Podsumowanie
Osiem węzłów, zero kont. Lista kanałów w jednym polu, tabela zakłada się sama, filtr po dacie odcina archiwum, a Row Not Exists po linku pilnuje, żeby nic nie wpadło dwa razy. Ten sam układ - lista źródeł, Split Out, pobranie, dwa sita, zapis - wróci w dwóch kolejnych lekcjach.
W następnej lekcji, YouTube RSS, ten sam mechanizm zbiera nowe filmy z wybranych kanałów YouTube, bez klucza API.
Pokaż JSON do skopiowania - czytnik-rss.json
{
"name": "Czytnik RSS do Data Table",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 12,
"triggerAtMinute": 15
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
0,
0
],
"id": "06f1f375-d01b-4acd-95e1-bc078bd98477",
"name": "Co 12 godzin"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "96b9f4df-f932-4b97-5906-12307faa01a4",
"name": "kanaly",
"value": "=[\"https://blog.n8n.io/rss/\", \"https://feeds.feedburner.com/niebezpiecznik/\"]",
"type": "array"
},
{
"id": "774ae328-951a-4e84-3702-2a5e0cc53e26",
"name": "dni_wstecz",
"value": "7",
"type": "number"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
440,
0
],
"id": "f7886f98-597c-94ae-03eb-047026c14ec5",
"name": "Kanaly RSS"
},
{
"parameters": {
"resource": "table",
"operation": "create",
"tableName": "rss_wpisy",
"columns": {
"column": [
{
"name": "tytul",
"type": "string"
},
{
"name": "link",
"type": "string"
},
{
"name": "zrodlo",
"type": "string"
},
{
"name": "opublikowano",
"type": "date"
},
{
"name": "dodano",
"type": "date"
}
]
},
"options": {
"createIfNotExists": true
}
},
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1.1,
"position": [
220,
0
],
"id": "49e5ea48-f163-9326-893a-dfd26539e811",
"name": "Przygotuj tabele"
},
{
"parameters": {
"fieldToSplitOut": "kanaly",
"options": {
"destinationFieldName": "kanal"
}
},
"type": "n8n-nodes-base.splitOut",
"typeVersion": 1,
"position": [
660,
0
],
"id": "617bef99-e134-af25-a2e9-00f77435c156",
"name": "Rozbij kanaly"
},
{
"parameters": {
"url": "={{ $('Rozbij kanaly').item.json.kanal }}",
"options": {
"ignoreSSL": false
}
},
"type": "n8n-nodes-base.rssFeedRead",
"typeVersion": 1.2,
"position": [
880,
0
],
"id": "8f2a97c7-13d6-53c4-95ed-75041b394b6e",
"name": "Czytaj kanal",
"onError": "continueRegularOutput"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose",
"version": 2
},
"conditions": [
{
"id": "f1",
"leftValue": "={{ $json.isoDate }}",
"rightValue": "={{ $now.minus({days: $('Kanaly RSS').first().json.dni_wstecz}).toISO() }}",
"operator": {
"type": "dateTime",
"operation": "after"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.filter",
"typeVersion": 2.2,
"position": [
1100,
0
],
"id": "7037fefe-5d14-6217-6472-a353736b27ac",
"name": "Tylko swieze"
},
{
"parameters": {
"operation": "rowNotExists",
"dataTableId": {
"__rl": true,
"value": "rss_wpisy",
"mode": "name"
},
"filters": {
"conditions": [
{
"keyName": "link",
"condition": "eq",
"keyValue": "={{ $json.link }}"
}
]
}
},
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1.1,
"position": [
1320,
0
],
"id": "753efec6-7a8c-2401-3685-7c69daa51ea2",
"name": "Czy nowy wpis?"
},
{
"parameters": {
"operation": "insert",
"dataTableId": {
"__rl": true,
"value": "rss_wpisy",
"mode": "name"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"tytul": "={{ $json.title }}",
"link": "={{ $json.link }}",
"zrodlo": "={{ $('Rozbij kanaly').item.json.kanal.split('/')[2] }}",
"opublikowano": "={{ $json.isoDate }}",
"dodano": "={{ $now.toISO() }}"
},
"matchingColumns": [],
"schema": [
{
"id": "tytul",
"displayName": "tytul",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"readOnly": false,
"removed": false
},
{
"id": "link",
"displayName": "link",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"readOnly": false,
"removed": false
},
{
"id": "zrodlo",
"displayName": "zrodlo",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"readOnly": false,
"removed": false
},
{
"id": "opublikowano",
"displayName": "opublikowano",
"required": false,
"defaultMatch": false,
"display": true,
"type": "date",
"readOnly": false,
"removed": false
},
{
"id": "dodano",
"displayName": "dodano",
"required": false,
"defaultMatch": false,
"display": true,
"type": "date",
"readOnly": false,
"removed": false
}
]
},
"options": {}
},
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1.1,
"position": [
1540,
0
],
"id": "422a09c7-d873-466f-77b1-c009d6b560e8",
"name": "Zapisz wpis"
}
],
"connections": {
"Co 12 godzin": {
"main": [
[
{
"node": "Przygotuj tabele",
"type": "main",
"index": 0
}
]
]
},
"Przygotuj tabele": {
"main": [
[
{
"node": "Kanaly RSS",
"type": "main",
"index": 0
}
]
]
},
"Kanaly RSS": {
"main": [
[
{
"node": "Rozbij kanaly",
"type": "main",
"index": 0
}
]
]
},
"Rozbij kanaly": {
"main": [
[
{
"node": "Czytaj kanal",
"type": "main",
"index": 0
}
]
]
},
"Czytaj kanal": {
"main": [
[
{
"node": "Tylko swieze",
"type": "main",
"index": 0
}
]
]
},
"Tylko swieze": {
"main": [
[
{
"node": "Czy nowy wpis?",
"type": "main",
"index": 0
}
]
]
},
"Czy nowy wpis?": {
"main": [
[
{
"node": "Zapisz wpis",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"active": false
}