Praca z danymi w n8n
Każdy workflow to tak naprawdę przepływ danych z node'a do node'a. Gdy zrozumiesz, w jakiej strukturze n8n trzyma te dane i jak się do nich odwoływać wyrażeniami, przestaniesz zgadywać, a zaczniesz świadomie kształtować, filtrować i łączyć informacje. Ten moduł to fundament wszystkich kolejnych integracji.
Jak n8n przechowuje dane - items i struktura JSON
Dział zatytułowany „Jak n8n przechowuje dane - items i struktura JSON”Dane w n8n nie są pojedynczym obiektem - są listą (tablicą) elementów zwanych items. Każdy node przyjmuje listę itemów na wejściu, przetwarza je i zwraca listę itemów na wyjściu. Zrozumienie tego jednego faktu rozwiązuje większość problemów początkujących.
Każdy pojedynczy item to obiekt, który może mieć dwa klucze: json (dane tekstowe/strukturalne)
oraz binary (pliki - opcjonalnie). Pełna struktura danych płynących między node'ami wygląda
następująco:
[ { "json": { "imie": "Anna", "email": "anna@example.com", "zamowienie": { "kwota": 199, "waluta": "PLN" } }, "binary": { "faktura": { "data": "JVBERi0xLjQ...", // zawartość pliku zakodowana w base64 "mimeType": "application/pdf", "fileName": "faktura.pdf" } } }, { "json": { "imie": "Marek", "email": "marek@example.com", "zamowienie": { "kwota": 49, "waluta": "PLN" } } }]Powyżej widać dwa itemy. Pierwszy ma zarówno dane json, jak i plik w binary; drugi ma
tylko json. To normalne - klucz binary pojawia się tylko wtedy, gdy item niesie ze sobą plik.
Treść pliku w polu data zapisana jest w base64 - to sposób przedstawienia dowolnego pliku
(np. PDF) jako jednego długiego ciągu zwykłych znaków tekstowych.
Lista itemów
Wejście i wyjście node'a to zawsze tablica - nawet jeśli zawiera tylko jeden element.
Klucz json
Tu mieszkają dane strukturalne: pola, liczby, teksty, zagnieżdżone obiekty i tablice.
Klucz binary
Opcjonalny - przechowuje pliki (PDF, obrazy, CSV) wraz z metadanymi (mimeType, fileName).
Node na każdym itemie
Domyślnie node wykonuje swoją operację raz dla każdego itemu z listy wejściowej.
Wyrażenia (expressions) i składnia {{ }}
Dział zatytułowany „Wyrażenia (expressions) i składnia {{ }}”Wyrażenia to sposób, w jaki sięgasz po dane z poprzednich node'ów wprost w polach formularza.
Każde pole node'a możesz przełączyć z trybu Fixed (wpisujesz wartość na stałe) na tryb
Expression (wartość wyliczana dynamicznie z danych). Wyrażenia zapisujesz w podwójnych
klamrach: {{ }}.
Tryb Fixed vs Expression
Dział zatytułowany „Tryb Fixed vs Expression”Fixed (stały)
Wpisujesz dosłowną wartość, np. witaj@firma.pl. n8n traktuje to jako zwykły tekst i nic nie
wylicza.
Expression (wyrażenie)
Wartość liczona dynamicznie z danych, np. {{ $json.email }}. Przy każdym wykonaniu podstawia
się realna wartość.
Przełącznik trybu znajdziesz najeżdżając kursorem na pole - pojawia się opcja Fixed / Expression. W trybie Expression pole zmienia kolor, a pod spodem widzisz podgląd wyliczonej wartości na żywo.
Najważniejsze zmienne wbudowane
Dział zatytułowany „Najważniejsze zmienne wbudowane”Wewnątrz klamer masz dostęp do zmiennych zaczynających się od $. Oto te, których będziesz
używać najczęściej:
| Zmienna | Co zwraca | Przykład |
|---|---|---|
$json |
Dane json bieżącego itemu z poprzedniego node'a |
{{ $json.email }} |
$binary |
Dane binarne bieżącego itemu | {{ $binary.faktura.fileName }} |
$node |
Dostęp do danych konkretnego, nazwanego node'a (po nazwie) | {{ $node["Webhook"].json.id }} |
$input |
Wejście bieżącego node'a - z metodami .item, .all(), .first(), .last() |
{{ $input.first().json.imie }} |
$now |
Aktualna data i czas (obiekt DateTime / Luxon) | {{ $now.toISO() }} |
$workflow / $execution |
Metadane bieżącego workflow i wykonania (id, nazwa) | {{ $workflow.name }} |
Przykłady wyrażeń
Dział zatytułowany „Przykłady wyrażeń”// Pole proste - pobranie e-maila z poprzedniego node'a{{ $json.email }}
// Zagnieżdżone pole{{ $json.zamowienie.kwota }}
// Połączenie tekstu z danymi (interpolacja)Cześć {{ $json.imie }}, dziękujemy za zamówienie!
// Odwołanie do konkretnego, nazwanego node'a{{ $node["HTTP Request"].json.results[0].id }}
// Metody JavaScript działają wewnątrz klamer{{ $json.email.toLowerCase() }}{{ $json.kwota * 1.23 }}
// Pierwszy item z całego wejścia{{ $input.first().json.imie }}
// Data w formacie ISO{{ $now.toISO() }}Edit Fields (Set) - kształtowanie i mapowanie danych
Dział zatytułowany „Edit Fields (Set) - kształtowanie i mapowanie danych”Node Edit Fields (wcześniej i nadal nazywany Set) to Twoje główne narzędzie do porządkowania danych: dodawania pól, zmiany istniejących, mapowania jednej struktury na inną. To prawdopodobnie najczęściej używany node do transformacji w całym n8n.
Do czego służy
Dział zatytułowany „Do czego służy”- Dodawanie pól - tworzysz nowe pole i nadajesz mu wartość (stałą lub z wyrażenia).
- Zmiana istniejących pól - nadpisujesz wartość, łączysz teksty, przeliczasz liczby.
- Mapowanie - przekształcasz dane z jednego systemu na format wymagany przez kolejny (np. dopasowanie nazw pól pod API).
- Czyszczenie - z opcją "Keep Only Set" zostawiasz wyłącznie pola, które jawnie zdefiniowałeś, odrzucając resztę.
Praktyczny przykład - przygotowanie danych pod CRM
Dział zatytułowany „Praktyczny przykład - przygotowanie danych pod CRM”Wyobraź sobie, że z formularza dostajesz surowe dane, a Twoje API CRM oczekuje innej struktury. W node Edit Fields definiujesz pola wyjściowe:
| Nazwa pola (wyjście) | Typ | Wartość (wyrażenie) |
|---|---|---|
full_name |
String | {{ $json.imie }} {{ $json.nazwisko }} |
email |
String | {{ $json.email.toLowerCase() }} |
order_value |
Number | {{ $json.zamowienie.kwota }} |
created_at |
String | {{ $now.toISO() }} |
source |
String | formularz-www (stała / fixed) |
Efekt: niezależnie od tego, jak wyglądały dane wejściowe, na wyjściu otrzymasz schludny,
przewidywalny obiekt gotowy do wysłania dalej. Pole source jest wpisane na stałe, reszta liczona
z wyrażeń.
Logika: IF, Switch, Filter
Dział zatytułowany „Logika: IF, Switch, Filter”Te trzy node'y decydują, co dzieje się z danymi w zależności od warunków. Choć bywają mylone, robią różne rzeczy: dwie z nich rozgałęziają przepływ, jedna odsiewa itemy bez tworzenia gałęzi.
IF
Dwie gałęzie: true i false. Itemy spełniające warunek idą jedną drogą, reszta - drugą.
Switch
Wiele gałęzi. Kierujesz itemy do różnych wyjść w zależności od wartości - jak rozjazd kolejowy.
Filter
Jedno wyjście. Przepuszcza tylko itemy spełniające warunek, resztę po prostu usuwa z przepływu.
IF rozdziela itemy na dwie ścieżki: spełniające warunek (true) i resztę (false). Switch robi to na wiele wyjść, Filter po prostu odsiewa.
| Cecha | IF | Switch | Filter |
|---|---|---|---|
| Liczba wyjść | 2 (true / false) | Wiele (definiujesz reguły) | 1 |
| Co robi | Rozgałęzia na dwie ścieżki | Rozgałęzia na wiele ścieżek | Odsiewa itemy |
| Itemy odrzucone | Trafiają na gałąź false | Mogą trafić do gałęzi "fallback" | Znikają z przepływu |
| Typowe użycie | "Jeśli kwota > 100 to…, inaczej…" | Routing wg statusu / typu / kraju | "Zostaw tylko aktywnych klientów" |
| Kiedy wybrać | Prosty warunek dwustanowy | 3+ możliwych dróg | Nie potrzebujesz drugiej gałęzi |
Pętle - kiedy n8n iteruje sam, a kiedy potrzebujesz jawnej pętli
Dział zatytułowany „Pętle - kiedy n8n iteruje sam, a kiedy potrzebujesz jawnej pętli”Najczęstsze nieporozumienie początkujących: "muszę dodać pętlę, żeby przetworzyć wszystkie rekordy". Zwykle nie musisz - node domyślnie wykonuje swoją operację raz dla każdego itemu z listy wejściowej. Pętla automatyczna jest wbudowana.
Domyślne przetwarzanie itemów
Dział zatytułowany „Domyślne przetwarzanie itemów”Jeśli na wejście node'a (np. HTTP Request albo wysyłka maila) trafi 50 itemów, node wykona się 50 razy - po jednym dla każdego itemu - bez żadnej pętli z Twojej strony. To zachowanie domyślne i pożądane.
Loop Over Items (Split in Batches)
Dział zatytułowany „Loop Over Items (Split in Batches)”Node Loop Over Items (znany też jako Split in Batches) służy do jawnego sterowania pętlą: dzieli itemy na paczki (batche) i przepuszcza je przez podłączoną gałąź porcjami, aż przerobi wszystkie. Używasz go w konkretnych sytuacjach:
- Batchowanie - gdy API ma limit (np. maks. 100 rekordów na żądanie albo rate limit), przetwarzasz dane partiami.
- Paginacja - pobieranie kolejnych stron wyników (strona 1, 2, 3…) aż do wyczerpania danych.
- Operacje krok po kroku - gdy każda iteracja zależy od wyniku poprzedniej i musisz je rozdzielić w czasie.
Merge - łączenie danych z wielu źródeł
Dział zatytułowany „Merge - łączenie danych z wielu źródeł”Gdy workflow rozdziela się na kilka gałęzi albo pobierasz dane z dwóch różnych źródeł, node Merge scala je z powrotem w jeden strumień. Kluczowy jest wybór trybu - to on decyduje, jak dane się połączą.
Tryby łączenia
Dział zatytułowany „Tryby łączenia”| Tryb | Jak łączy | Kiedy użyć |
|---|---|---|
| Append | Dokleja itemy z wejścia 2 za itemami z wejścia 1 - jedna dłuższa lista, bez dopasowywania. | Chcesz po prostu zsumować dwie listy w jedną. |
| Combine → by matching fields | Łączy itemy po wspólnym kluczu (np. email albo id), scalając ich pola - jak JOIN w SQL. |
Wzbogacasz dane: dane z A uzupełniasz pasującymi danymi z B. |
| Combine → by position | Łączy itemy po pozycji: pierwszy z pierwszym, drugi z drugim itd. | Obie listy mają tę samą kolejność i długość. |
| Combine → all combinations | Tworzy każdą możliwą parę itemów z obu wejść (iloczyn kartezjański). | Rzadziej - gdy świadomie potrzebujesz wszystkich kombinacji. |
| SQL Query | Łączysz dane zapytaniem SQL na wejściach jak na tabelach. | Złożone połączenia, gdy znasz SQL. |
Przykład - wzbogacanie po kluczu
Dział zatytułowany „Przykład - wzbogacanie po kluczu”Masz listę zamówień (wejście 1) i listę klientów z ich danymi (wejście 2). Wybierasz tryb
Combine → by matching fields i wskazujesz pole email jako klucz. Merge dopasuje każde
zamówienie do właściwego klienta i scali ich pola w jeden item - dokładnie tak, jak JOIN
w bazach danych (łączenie dwóch tabel po wspólnej kolumnie - tu rolę kolumny pełni pole email).
Merge łączy dwa wejścia po wspólnym kluczu (email) w jeden wzbogacony strumień - jak JOIN w SQL.
Pliki binarne - PDF, obrazy, CSV
Dział zatytułowany „Pliki binarne - PDF, obrazy, CSV”Nie wszystkie dane to tekst. Pliki - PDF-y, zdjęcia, arkusze CSV, archiwa - to dane binarne.
n8n trzyma je oddzielnie od json, w kluczu binary itemu. Praca z plikami rządzi się trochę
innymi prawami niż praca z polami JSON.
Czym binarne różni się od JSON
Dział zatytułowany „Czym binarne różni się od JSON”Dane JSON
- Tekst i struktura: pola, liczby, obiekty, tablice
- Widoczne wprost w panelu danych (Table / JSON)
- Odwołujesz się przez
$json.pole
Dane binarne
- Zawartość pliku - nie nadaje się do czytania jako tekst
- Przechowywane z metadanymi:
mimeType,fileName - Odwołujesz się przez
$binary.nazwa
Konwersje: binary ⇄ JSON
Dział zatytułowany „Konwersje: binary ⇄ JSON”Najczęściej chcesz albo wyciągnąć dane z pliku, albo zapisać dane jako plik. Służą do tego dwa node'y:
- Extract from File - wyciąga dane z pliku binarnego do
json. Np. z CSV robi listę itemów, z PDF wyciąga tekst, odczytuje XLSX/JSON/XML. - Convert to File - odwrotnie: zamienia dane
jsonna plik binarny. Np. z listy itemów tworzy plik CSV/XLSX gotowy do wysłania lub zapisania.
Typowy scenariusz
Dział zatytułowany „Typowy scenariusz”- Trigger pobiera maila z załącznikiem CSV → plik ląduje w
binary. - Extract from File rozbija CSV na itemy w
json. - Edit Fields / Filter czyszczą i odsiewają dane.
- Convert to File tworzy z przerobionych danych nowy plik XLSX.
- Node wysyłki dołącza plik z
binarydo wiadomości lub zapisuje go w chmurze.
Pipeline plików: z maila wyciągasz CSV, przerabiasz dane i zapisujesz je jako nowy plik XLSX gotowy do wysyłki.
Sprawdź się
Dział zatytułowany „Sprawdź się”Zanim ruszysz dalej, odpowiedz sobie na te pytania - na głos albo w dwóch zdaniach na kartce. Jeśli przy którymś się zawahasz, wróć do podlinkowanej sekcji.
- Na wejście node'a HTTP Request trafia 50 itemów, a Ty nie dodałeś żadnej pętli. Ile razy wykona się ten node i dlaczego nie musisz sam pisać pętli, żeby obsłużyć wszystkie 50? Jeśli nie masz pewności - Domyślne przetwarzanie itemów.
- To samo pole w node'ie ustawiasz raz w trybie Fixed, raz w trybie Expression. Czym będzie się różnić zachowanie tych dwóch pól, gdy workflow przetworzy po kolei dwa różne itemy? Jeśli nie masz pewności - Tryb Fixed vs Expression.
- Masz itemy z polem
status, które przyjmuje pięć różnych wartości, i każda ma trafić w inne miejsce workflow. Lepiej użyć kilku node'ów IF z rzędu, czy jednego Switcha? Dlaczego? Jeśli nie masz pewności - Logika: IF, Switch, Filter. - Pobierasz z API 10 000 rekordów, a usługa ogranicza jedno zapytanie do maksymalnie 100 rekordów. Które narzędzie z tego modułu pozwoli Ci to sensownie obsłużyć i na czym dokładnie polega jego działanie? Jeśli nie masz pewności - Loop Over Items (Split in Batches).
Mini-zadanie: rozgałęź dane warunkiem IF
Potrzebujesz działającej instancji n8n i kilkunastu minut.
- Dodaj Manual Trigger, a po nim Edit Fields - utwórz w nim 3-4 testowe pola, np.
imie,kwota,kraj(wpisz wartości na stałe, tryb Fixed). - Dodaj node IF z warunkiem
{{ $json.kwota }} > 100. - Na gałęzi true dodaj kolejny Edit Fields, który ustawia pole
komunikatna "Rabat 10%". - Na gałęzi false dodaj analogiczny Edit Fields z polem
komunikatustawionym na "Standardowa cena". - Uruchom Execute workflow i sprawdź w panelu Output obu gałęzi, że dane trafiły tam,
gdzie się spodziewałeś - a potem zmień wartość
kwotaw kroku 1 i uruchom ponownie, żeby zobaczyć, jak przełącza się gałąź.
Co warto zapamiętać z tego modułu
- Dane w n8n to lista itemów; każdy item ma klucz
jsoni opcjonalniebinary. - Wyrażenia w
{{ }}sięgają po dane:$json,$node,$input,$now- przełącz pole z Fixed na Expression. - Edit Fields (Set) to główne narzędzie do dodawania, zmiany i mapowania pól.
- IF = 2 gałęzie, Switch = wiele gałęzi, Filter = odsiewa itemy bez rozgałęziania.
- Node domyślnie iteruje po itemach sam - jawna pętla (Loop Over Items) potrzebna głównie przy paginacji i batchowaniu.
- Merge łączy dane: Append (doklejanie) lub Combine (po kluczu / pozycji / wszystkie kombinacje).
- Pliki to dane binarne; konwersje robisz przez Extract from File i Convert to File.
Częste pytania
Dlaczego mój node przetwarza tylko jeden rekord, a nie wszystkie?
Najczęstsze przyczyny: w ustawieniach node'a włączona jest opcja Execute Once, albo na wejściu masz jeden item z tablicą w środku zamiast wielu itemów. W drugim przypadku użyj node'a Split Out, by rozbić tablicę na osobne itemy.
Czym różni się $json od $node?
$json odwołuje się do danych itemu pochodzących z bezpośrednio poprzedniego node'a. $node["Nazwa"] pozwala sięgnąć do danych dowolnego wcześniejszego, nazwanego node'a - przydatne, gdy potrzebujesz wartości sprzed kilku kroków.
Kiedy użyć Filter, a kiedy IF?
Jeśli chcesz tylko usunąć z przepływu itemy, które nie spełniają warunku, i jechać dalej jednym torem - użyj Filter. Jeśli potrzebujesz obsłużyć osobno itemy spełniające i niespełniające warunek (dwie różne ścieżki) - użyj IF i podłącz obie gałęzie.
Jak połączyć dane z dwóch list po wspólnym polu?
Użyj node'a Merge w trybie Combine → by matching fields i wskaż pole będące kluczem (np. email lub id). n8n dopasuje itemy z obu wejść po tej wartości i scali ich pola - analogicznie do JOIN-a w SQL.
Jak wyciągnąć dane z pliku CSV lub PDF?
Użyj node'a Extract from File - odczytuje on plik z klucza binary i zamienia jego zawartość na dane json (np. CSV na listę itemów, tekst z PDF). W drugą stronę, by zapisać dane jako plik, użyj Convert to File.
made with ❤️ by aitomate.pl - Łukasz Podgórski