Skrzynka info@firma.pl to czarna dziura każdego biura SMB. 50–150 maili dziennie. Większość to nie pilne sprawy, ale ktoś musi je posortować: oferty do handlowca, faktury do księgowej, reklamacje do menedżera, prośby o termin do recepcji. W praktyce: 60–120 minut dziennie jednej osoby, której kompetencje są warte więcej niż klikanie "przenieś do folderu".
To pierwszy workflow, który stawiamy klientom w ramach Sprint AI · 30 dni. Zwraca się w 2 tygodnie. Działa od 4 godzin po wdrożeniu. Ten artykuł to kompletna instrukcja — node po node, z promptami, kosztami i znanymi pułapkami.
Co Konkretnie Robi Ten Workflow
Wejście: nowy mail trafia na info@firma.pl (IMAP). Wyjście:
- •OFERTA → forward do handlowca + DM w Slack + tag w HubSpot.
- •FAKTURA → folder "Księgowość" + ping do Anny + dopisek do arkusza księgowego.
- •TERMIN → ekstrakcja daty i godziny → automatyczna propozycja w Cal.com.
- •REKLAMACJA → forward do menedżera + ticket w Trello/Linear z severity.
- •PYTANIE INFORMACYJNE → auto-odpowiedź z linkiem do FAQ + kolejka do CS.
- •SPAM/MARKETING → archiwizacja.
Klasyfikator: GPT-4o-mini (~$0.15/1M tokens input). Średni koszt: ~$0.001 na maila. Przy 100 mailach/dziennie to $3/msc — czyli pomijalnie.
Stos Technologiczny
- •n8n — self-hosted na Hetzner CX22 (30 PLN/msc), wersja Community.
- •OpenAI API — model
gpt-4o-mini(tańszy niżgpt-4o, w zupełności wystarczy do klasyfikacji). - •PostgreSQL — n8n trzyma tu egzekucje + dane workflow.
- •IMAP — Gmail/Office365/własny mailserver, wszystkie wspierane.
Jeśli pierwszy raz słyszysz o n8n — zacznij od pillara o n8n + GPT dla polskich firm, gdzie wyjaśniamy, czemu n8n bije Make.com i Zapier kosztowo przy 100+ egzekucjach dziennie.
Krok 1 — IMAP Trigger Node
n8n ma natywny Email Trigger (IMAP) node. Konfiguracja:
Credentials: info@firma.pl + hasło aplikacji Host: imap.gmail.com (lub mailserver klienta) Port: 993 (SSL) Mailbox: INBOX Polling: every 1 minute Action on read: Mark Seen (po przeczytaniu workflow oznacza)
Uwaga praktyczna: dla Gmaila trzeba wygenerować hasło aplikacji (App Password) — nie działa bez 2FA. Dla Office365 użyj OAuth2 zamiast IMAP, bo Microsoft blokuje Basic Auth.
Krok 2 — Preprocessing (Function Node)
Surowy mail z IMAP zawiera HTML, podpisy, threading. Przed wysłaniem do GPT czyszczę:
// Function Node: clean-email
const html = $input.item.json.text || $input.item.json.html || '';
const cleaned = html
.replace(/<[^>]+>/g, ' ') // strip HTML
.replace(/\s+/g, ' ') // collapse whitespace
.replace(/On .+ wrote:[\s\S]+/i, '') // strip quoted reply
.replace(/-- ?\n[\s\S]+/, '') // strip signature
.trim()
.slice(0, 2000); // GPT-4o-mini context budget
return [{
json: {
from: $input.item.json.from,
subject: $input.item.json.subject,
body: cleaned,
messageId: $input.item.json.messageId,
receivedAt: new Date().toISOString()
}
}];Dlaczego slice na 2000 znaków? Bo dla klasyfikacji GPT-4o-mini nie potrzebuje pełnego maila. Pierwsze 2000 znaków + subject = wystarczy w 99% przypadków, a koszt spada 10×.
Krok 3 — Klasyfikacja OpenAI Node
To serce workflow. Prompt jest structured output JSON, żeby Switch Node mógł routować bez błędów:
{
"model": "gpt-4o-mini",
"messages": [
{
"role": "system",
"content": "Jesteś klasyfikatorem maili przychodzących do biura. Zwracasz wyłącznie JSON w formacie: {\"category\": \"OFERTA|FAKTURA|TERMIN|REKLAMACJA|INFORMACYJNE|SPAM\", \"urgency\": \"high|medium|low\", \"language\": \"pl|en|other\", \"summary\": \"max 15 słów\"}. Definicje: OFERTA = pytanie o produkt/usługę/cenę. FAKTURA = załącznik PDF/zapytanie księgowe/przypomnienie płatności. TERMIN = prośba o spotkanie/kalendarz. REKLAMACJA = niezadowolenie/błąd/zwrot. INFORMACYJNE = pytanie ogólne bez intencji kupna. SPAM = newsletter/marketing/phishing."
},
{
"role": "user",
"content": "Od: {{ $json.from }}\nTemat: {{ $json.subject }}\nTreść: {{ $json.body }}"
}
],
"response_format": { "type": "json_object" },
"temperature": 0.1
}Dlaczego temperature 0.1? Bo klasyfikacja ma być deterministyczna. Wyższe temperature → workflow zaczyna kreatywnie wymyślać kategorie typu "OFERTA-REKLAMACJA" i Switch Node leci w default.
Dlaczego response_format: json_object? Bo bez tego GPT raz na 50 odpowiedzi zwróci JSON owinięty w \\\json ... \\\, co rozbije parser w n8n.
Krok 4 — Switch Node z 6 Wyjściami
Switch routuje na podstawie {{ $json.message.content.category }}:
| Wyjście | Warunek | Następny Node | |---------|---------|---------------| | 0 | category == "OFERTA" | HubSpot + Slack | | 1 | category == "FAKTURA" | Google Sheets + Slack | | 2 | category == "TERMIN" | Cal.com + GPT date extractor | | 3 | category == "REKLAMACJA" | Linear/Trello + Slack | | 4 | category == "INFORMACYJNE" | Gmail auto-reply + CS queue | | 5 | fallback (SPAM/INNE) | Move to archive |
Krok 5 — Branch OFERTA: HubSpot + Slack
Tutaj robi się ciekawie. Drugi GPT call ekstraktuje strukturalnie dane leada:
{
"model": "gpt-4o-mini",
"messages": [{
"role": "user",
"content": "Z tego maila wyciągnij JSON: {\"company\": \"...\", \"contact_name\": \"...\", \"phone\": \"...\", \"product_interest\": \"...\", \"budget_signal\": \"yes|no|unclear\", \"timeline\": \"...\"}. Treść: {{ $json.body }}"
}],
"response_format": { "type": "json_object" }
}Następnie:
- 01HubSpot Node →
createContactz extraktem + tagsource:info-inbox. - 02HubSpot Node →
createDealw stage "Inbound Inquiry" przypisany do handlowca z roundrobina. - 03Slack Node → DM do handlowca: "Nowy lead od [company]. Interesuje go [product]. Budget signal: [yes/no]. Mail: [link do oryginału]."
- 04Gmail Node → forward oryginalnego maila do handlowca z zachowanym threading.
Czas reakcji handlowca: z 4 godzin do 30 sekund. Konwersja leadów (statystyki branżowe): pierwsza odpowiedź w 5 min daje 21× wyższą szansę zamknięcia.
Krok 6 — Branch TERMIN: Cal.com Integration
Najbardziej "magiczna" gałąź. Ekstraktor daty:
{
"messages": [{
"role": "system",
"content": "Zwracasz JSON: {\"proposed_date\": \"YYYY-MM-DDTHH:mm\", \"duration_min\": 30|60, \"timezone\": \"Europe/Warsaw\", \"flexibility\": \"firm|flexible\"}. Jeśli klient nie podał konkretnej daty, ustaw proposed_date na null."
}, {
"role": "user",
"content": "Dzisiaj: {{ $now.toISO() }}. Treść: {{ $json.body }}"
}],
"response_format": { "type": "json_object" }
}Dlaczego przekazujemy $now? Bo bez tego GPT halucynuje rok i wpisuje 2024 dla maila z "w przyszłą środę". Z kontekstem aktualnej daty halucynacje spadają do ~2%.
Następnie:
- 01Jeśli
proposed_date!= null → Cal.com API sprawdza dostępność. - 02Dostępne → utwórz rezerwację + wyślij confirmation do klienta i AM.
- 03Niedostępne → Gmail auto-reply z linkiem do publicznego booking page Cal.com.
Krok 7 — Logging i Observability
Każda egzekucja workflow loguje się do PostgreSQL:
INSERT INTO email_routing_log (message_id, category, urgency, action_taken, latency_ms, cost_cents, created_at) VALUES (...);
Dashboard w Metabase pokazuje:
- •Średni koszt per mail (powinien być < $0.002).
- •Rozkład kategorii (jeśli FAKTURA > 60% — w workflow brakuje preklasyfikacji po nadawcy).
- •Latencję end-to-end (cel: < 8 sekund od IMAP do akcji).
- •Klasyfikacje "INNE" — to feedback loop do iteracji promptu.
Znane Pułapki i Jak Je Obejść
1. Threading maili. Gdy GPT klasyfikuje pojedynczego maila w wątku, nie zna kontekstu wcześniejszych odpowiedzi. Rozwiązanie: w Function Node dołączaj ostatnie 2 wiadomości w threadzie jako kontekst (In-Reply-To header).
2. Załączniki PDF. Workflow nie czyta załączników domyślnie. Jeśli FAKTURA przychodzi tylko jako PDF bez tekstu w body — dodaj PDF.co lub Tesseract OCR w gałęzi FAKTURA przed zapisem do Sheets.
3. Polskie znaki w GPT response. GPT-4o-mini czasem koduje "ą" jako \u0105. Dodaj JSON.parse(content) w Function Node — automatycznie dekoduje.
4. Rate limity OpenAI. Konto Tier 1 ma 200 RPM dla GPT-4o-mini. Przy 100 mailach/dziennie nie ma problemu. Przy 1000+ — Tier 2 (50$ wpłaty) lub kolejkowanie w Redis.
5. False positives w klasyfikacji SPAM. Reklamacje czasem mają "ofertowy" subject ("Dostałem złą ofertę"). Rozwiązanie: dodaj w prompcie "REKLAMACJA ma pierwszeństwo nad OFERTA jeśli ton jest negatywny."
Koszt 30-Dniowy w Praktyce
| Pozycja | Koszt | |---------|-------| | n8n self-hosted (Hetzner CX22) | 30 PLN | | PostgreSQL (na tym samym serwerze) | 0 PLN | | OpenAI API (100 maili/dziennie × 30 dni × $0.001) | $3 (~12 PLN) | | Cal.com self-hosted (opcjonalnie) | 0 PLN | | Razem | ~42 PLN/msc |
Vs. Make.com Pro dla tego samego workflow: ~$29/msc (limity operacji), nie self-hosted, dane lecą przez chmurę Make. Vs. Zapier Team: $69/msc.
Kiedy Wdrożyć Sam, a Kiedy Zlecić
Wdroż sam jeśli:
- •Masz w zespole kogoś, kto kliknie 5 GodzinTutorial n8n na YouTube.
- •Akceptujesz 1–2 tygodnie iteracji (każdy biuro ma swoje edge cases).
- •100 maili/dziennie to dla Ciebie max obciążenie.
Zleć jeśli:
- •Chcesz workflow + monitoring + dokumentację + handover w 30 dni.
- •Masz mailbox 500+ dziennie i potrzebujesz przemyślanego rate-limitingu.
- •Łączysz to z innymi automatyzacjami (faktury, leady, raporty) — wtedy Sprint AI · 30 dni jest tańszy w skali niż sklejanie pojedynczo.
Podsumowanie
Workflow email routing to najlepszy entry point do automatyzacji biura. Zwraca się szybko, jest mało ryzykowny (zawsze masz oryginał w INBOX), a uwalnia czas, który dotąd ginął na sortowaniu skrzynki.
Stos: n8n + GPT-4o-mini + IMAP. Koszt: ~42 PLN/msc. Oszczędność: 5–7 godzin tygodniowo. ROI: 2 tygodnie.
Chcesz przejść z teorii do działającego workflow w 30 dni? Zobacz Sprint AI albo napisz o wycenę — odpowiadamy w 24h, bez umowy rocznej.


