Wróć do bloga
n8n

n8n Sub-workflows i Code node – zaawansowane techniki

Modularność, reusability, custom logic. Techniki, które oddzielają amatorski workflow od produkcyjnego.

9 min czytania
n8n, sub-workflow, Code node, JavaScript, zaawansowane, modularność

Twój workflow ma 40 node'ów. Nikt nie wie co robi. Debugowanie trwa godziny. Zmiana jednej rzeczy psuje trzy inne. Brzmi znajomo? Sub-workflows i Code node to rozwiązanie – modularność, reusability i custom logic, które zamieniają spaghetti w inżynierię.

TL;DR

  • Sub-workflow – osobny workflow wywoływany jak funkcja (parametry → wynik)
  • Execute Workflow node – wywołuje sub-workflow z głównego workflow
  • Code node – JavaScript lub Python bezpośrednio w n8n (pełna kontrola)
  • Kiedy co: sub-workflow = reusable logika, Code node = transformacje danych
  • Zasada: workflow z >20 node'ów → rozważ rozbicie na sub-workflows

Nie masz n8n? Zainstaluj w 15 minut. Kontekst: kompletny poradnik n8n.


Sub-workflows – modularność

Co to jest

Sub-workflow to osobny workflow, który wywołujesz z innego workflow – jak funkcja w programowaniu. Wysyłasz parametry, dostajesz wynik.

Kiedy używać

  • Ta sama logika w wielu workflow – zamiast kopiować 5 node'ów do 10 workflow, stwórz sub-workflow i wywołuj go
  • Workflow >20 node'ów – rozbij na mniejsze, czytelne moduły
  • Zespół – różne osoby odpowiadają za różne sub-workflows
  • Testowanie – testujesz sub-workflow niezależnie od reszty

Jak to działa

1. Stwórz sub-workflow

Nowy workflow → dodaj Execute Workflow Trigger (to trigger dla sub-workflow).

Przykład: sub-workflow „Send Notification":

Execute Workflow Trigger → IF (channel = slack) → Slack (wyślij wiadomość) → IF (channel = email) → Gmail (wyślij email)

2. Wywołaj z głównego workflow

W głównym workflow dodaj node Execute Workflow:

  • Workflow: wybierz sub-workflow „Send Notification"
  • Data: przekaż parametry:
json
{
  "channel": "slack",
  "message": "Nowy lead!",
  "recipient": "#leads"
}

3. Odbierz wynik

Sub-workflow może zwrócić dane (przez Return node lub ostatni node w chain). Główny workflow otrzymuje je jako output Execute Workflow node.

Wzorce sub-workflows

1. Notification Hub

Jeden sub-workflow obsługuje WSZYSTKIE powiadomienia (Slack, email, SMS, push). Główne workflow wywołują go z parametrami channel i message.

Main workflow → Execute Workflow ("Notify") → Notify: Switch na channel → Slack / Gmail / Twilio

2. Data Enrichment

Sub-workflow wzbogaca dane o kontakcie – szuka w LinkedIn, Clearbit, Google.

Main workflow → Execute Workflow ("Enrich Contact") → Enrich: HTTP Request (Clearbit) + HTTP Request (LinkedIn) → Merge → Return

3. Error Reporter

Sub-workflow loguje błąd i wysyła alert. Wywoływany z Error Workflow.

Error Workflow → Execute Workflow ("Log Error") → Log Error: Google Sheets (log) + Slack (alert) → Return
Wskazówka

Nazewnictwo sub-workflows: prefix [SUB] – np. [SUB] Send Notification, [SUB] Enrich Contact. Od razu widać co jest modułem, a co głównym workflow.


Code node – pełna kontrola

Nie wszystko da się zrobić klikając. Czasami potrzebujesz pętli, regex, custom formatowania, obliczeń. Code node daje Ci JavaScript (lub Python) bezpośrednio w workflow.

Tryby

1. Run Once for All Items – kod wykonuje się raz, masz dostęp do wszystkich itemów:

javascript
const items = $input.all();
const total = items.reduce((sum, item) => sum + item.json.amount, 0);
const avg = total / items.length;

return [{ json: { total, avg, count: items.length } }];

2. Run Once for Each Item – kod wykonuje się osobno dla każdego itemu:

javascript
const name = $input.item.json.name;
const email = $input.item.json.email;

return {
  json: {
    name: name.trim(),
    email: email.toLowerCase(),
    domain: email.split('@')[1],
    initials: name.split(' ').map(n => n[0]).join('').toUpperCase()
  }
};

Kiedy Code node

ZadanieBez CodeZ Code
Prosty mapping pólEdit FieldsNie potrzebny
Regex (wyciągnij numer faktury)Nie da siętext.match(/FV\/\d+\/\d+/)?.[0]
Deduplikacja po emailuNie da się (prosto)[...new Map(items.map(i => [i.json.email, i])).values()]
Obliczenia (suma, średnia, top N)Nie da się (prosto)Standard JS
Formatowanie daty (polskie)Ograniczonedate.toLocaleDateString('pl-PL')
Parsowanie HTML/XMLNie da sięcheerio / regex
Custom walidacjaIF (ograniczona)Pełna logika

Przykłady praktyczne

Deduplikacja listy po emailu:

javascript
const items = $input.all();
const seen = new Set();
const unique = [];

for (const item of items) {
  const email = item.json.email?.toLowerCase();
  if (email && !seen.has(email)) {
    seen.add(email);
    unique.push(item);
  }
}

return unique;

Wyciągnij numer faktury z tekstu:

javascript
const text = $input.item.json.email_body;
const match = text.match(/(?:FV|FA|FAKT)[\/\-]?\s*(\d+[\/\-]\d+[\/\-]?\d*)/i);

return {
  json: {
    ...($input.item.json),
    invoice_number: match ? match[0] : 'NOT_FOUND'
  }
};

Grupowanie itemów po kategorii:

javascript
const items = $input.all();
const groups = {};

for (const item of items) {
  const cat = item.json.category || 'other';
  if (!groups[cat]) groups[cat] = [];
  groups[cat].push(item.json);
}

return Object.entries(groups).map(([category, items]) => ({
  json: { category, count: items.length, items }
}));
Uwaga

Code node to potężne narzędzie, ale każdy Code node to miejsce, które trzeba debugować ręcznie. Nie pisz w Code tego, co da się zrobić node'ami (Edit Fields, IF, Switch). Code = ostatnia deska ratunku, nie pierwszy wybór.


Python w Code node

n8n obsługuje Python w Code node (od wersji 1.x). Przydatne gdy:

  • Znasz Python lepiej niż JavaScript
  • Potrzebujesz bibliotek ML (pandas, numpy – ograniczone w sandboxie)
  • Parsowanie danych (Python jest wygodniejszy do data wrangling)
python
items = _input.all()
total = sum(item.json['amount'] for item in items)

return [{"json": {"total": total, "count": len(items)}}]
Informacja

Python w n8n działa w sandboxie – nie masz dostępu do pip install. Dostępne są podstawowe moduły. Dla zaawansowanych potrzeb (ML, scraping) – użyj HTTP Request do zewnętrznego API.


Debugging workflow

Executions log

Każde uruchomienie workflow jest zapisywane w Executions. Kliknij execution → widzisz dane w każdym node'ie (input/output).

Test workflow

Kliknij Test workflow – uruchomi się raz, zobaczysz dane w każdym node'ie w czasie rzeczywistym. Najlepszy sposób na debugging.

Console.log w Code node

javascript
console.log('Debug:', JSON.stringify($input.item.json));
// Widoczne w execution data

Typowe pułapki

  1. Brakujące dane – node zwraca undefined bo pole ma inną nazwę niż myślisz. Sprawdź Input w execution.
  2. Typy"123" (string) vs 123 (number). Code node: parseInt() / Number().
  3. Puste tablice – workflow zatrzymuje się gdy node zwraca 0 itemów. Dodaj „Always Output Data" w settings.
  4. Expression vs Code – expressions n8n ({{ }}) to nie JavaScript. W Code node piszesz czysty JS.

Best practices

1. Konwencja nazewnictwa

  • Główne workflow: Lead Capture Pipeline
  • Sub-workflows: [SUB] Send Notification
  • Sticky Notes: opis sekcji workflow (kto, co, dlaczego)

2. Sticky Notes jako dokumentacja

Dodaj Sticky Notes z opisem sekcji workflow:

SEKCJA: Walidacja danych - Sprawdza czy email jest poprawny - Sprawdza czy firma istnieje w CRM - Odrzuca spam (AI klasyfikacja)

3. Minimalizuj Code node

Code node = kod do utrzymania. Im mniej kodu, tym mniej bugów. Zanim napiszesz Code – sprawdź czy nie ma node'a, który to robi.

4. Wersjonowanie

n8n nie ma wbudowanego Git. Workaround:

  • Regularny eksport workflow (JSON) → Git repo
  • Nazwy workflow z wersją: Lead Pipeline v2.3
  • Tagi w n8n do organizacji

Więcej o stabilności na produkcji: n8n Error Handling.


FAQ

Czy sub-workflow spowalnia workflow?

Minimalnie – wywołanie sub-workflow to ~50-100ms overhead. Dla typowych workflow to nieistotne. Nie optymalizuj przedwcześnie – czytelność > kilkadziesiąt milisekund.

Ile sub-workflows mogę mieć?

Bez limitu na self-hosted. Praktycznie: typowy projekt ma 3-10 sub-workflows. Więcej = overengineering.

Czy Code node obsługuje npm packages?

Nie natywnie – Code node działa w sandboxie. Masz dostęp do wbudowanych modułów (crypto, url, querystring). Dla zewnętrznych bibliotek – użyj HTTP Request do API lub rozszerzenia n8n (custom node).

Python czy JavaScript w Code node?

JavaScript: domyślny, lepsze wsparcie, szybszy. Python: wygodniejszy do data processing. Wybierz ten, który znasz lepiej.