Przejdź do głównej zawartości

Praca z danymi w n8n

Moduł 3 · Poziom: średnio zaawansowanyCzas czytania: ~22 minItems, wyrażenia, logika, pliki

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.

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 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: {{ }}.

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.

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 }}
// 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() }}

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.

  • 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ę.

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ń.

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.

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.

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.

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ą.

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.

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.

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.

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

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 json na plik binarny. Np. z listy itemów tworzy plik CSV/XLSX gotowy do wysłania lub zapisania.
  1. Trigger pobiera maila z załącznikiem CSV → plik ląduje w binary.
  2. Extract from File rozbija CSV na itemy w json.
  3. Edit Fields / Filter czyszczą i odsiewają dane.
  4. Convert to File tworzy z przerobionych danych nowy plik XLSX.
  5. Node wysyłki dołącza plik z binary do 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.

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.

  1. 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.
  2. 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.
  3. 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.
  4. 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.

  1. 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).
  2. Dodaj node IF z warunkiem {{ $json.kwota }} > 100.
  3. Na gałęzi true dodaj kolejny Edit Fields, który ustawia pole komunikat na "Rabat 10%".
  4. Na gałęzi false dodaj analogiczny Edit Fields z polem komunikat ustawionym na "Standardowa cena".
  5. Uruchom Execute workflow i sprawdź w panelu Output obu gałęzi, że dane trafiły tam, gdzie się spodziewałeś - a potem zmień wartość kwota w 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 json i opcjonalnie binary.
  • 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.

Następny krok

Utknąłeś w tym module albo coś jest nieaktualne? Napisz do mnie - poprawię materiał.

made with ❤️ by aitomate.pl - Łukasz Podgórski