n8n służy do tego, co dzieje się wokół Odoo: odebrać zewnętrzny formularz, powiadomić czat, przygotować dzienny raport. To, co zmienia stan biznesu wewnątrz (ceny, rezerwacje zapasów, zatwierdzanie dostaw, uzgadnianie płatności), wymaga modułu. Granicę widać dopiero po uruchomieniu obu rozwiązań na prawdziwym Odoo: ten artykuł powstał w naszym laboratorium z Odoo 19.0-20260630 i n8n 2.30.6.
Kluczowa myśl: przepływ wywołujący API Odoo nie uruchamia jego interfejsu. Może dostać 200 z kreatorem w środku i uznać, że zatwierdził dostawę, która nadal jest otwarta.
Jak n8n rozmawia z Odoo: cztery drogi, nie jedna
- XML-RPC:
/xmlrpc/2/commondo uwierzytelnienia i/xmlrpc/2/objectdlaexecute_kw. Ten z dokumentacji. - JSON-RPC:
POST /jsonrpczservice,methodiargs. Ta sama usługa w JSON. - Sesja webowa:
/web/session/authenticatei/web/dataset/call_kwz ciasteczkiem. To, co robi Twoja przeglądarka. - API JSON-2, tylko w Odoo 19:
POST /json/2/<modelo>/<método>zAuthorization: bearer <clave API>iX-Odoo-Database. Bez sesji: argumenty idą jako pola nazwane,contextteż.
Pierwsze trzy nadal działają w 19, ale serwer ostrzega w logu: „The /xmlrpc, /xmlrpc/2 and /jsonrpc endpoints are deprecated in Odoo 19 and scheduled for removal in Odoo 22”. Nowy przepływ do Odoo 19 powinien korzystać z /json/2; jeśli obsługuje też 17 i 18, z sesji.
# Sesion + call_kw: funciona igual en 17, 18 y 19.
POST /web/session/authenticate
{"params":{"db":"lab","login":"n8n_bot2","password":"..."}}
-> 200 {"result":{"uid":6,"server_version":"19.0-20260630"}} # + cookie
POST /web/dataset/call_kw # con esa cookie
{"params":{"model":"crm.lead","method":"create",
"args":[{"name":"Lead web","type":"lead"}],
"kwargs":{"context":{"lang":"es_ES"}}}}
-> 200 {"result": 10}
# Clave API en la cabecera, sin sesion: solo Odoo 19.
POST /json/2/crm.lead/create
Authorization: bearer <clave> X-Odoo-Database: lab
{"vals_list":[{"name":"Lead via /json/2 (API key)"}]}
-> 200 [9]
# Sin cabecera -> 401 "User not authenticated, use an API Key with a
# Bearer Authorization header."
# Metodo privado -> 403 "Private methods (such as
# 'crm.lead._compute_display_name') cannot be called remotely." Węzeł Odoo w n8n 2.30.6 wybiera za Ciebie w zależności od poświadczeń: ten z kluczem API korzysta z /json/2; klasyczny korzysta z /jsonrpc z execute, pozycyjnym, który nie przyjmuje kwargs i nie może przekazać kontekstu. Poświadczenie z kluczem API ostrzega ponadto, że wymaga „Odoo 19+ and a Custom pricing plan”.
Węzeł HTTP Request, dokładnie tak, jak został
Zwróć uwagę, gdzie nie ma klucza: treść zawiera tylko dane, a nagłówek Authorization ustawia poświadczenie n8n, które jest szyfrowane i rotowane osobno.
// Lineas del nodo real, copiadas de `n8n export:workflow`.
"type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2,
"url": "http://odoo:8069/json/2/crm.lead/create",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"headerParameters": { "parameters": [
{ "name": "X-Odoo-Database", "value": "lab" } ] },
"jsonBody": "={{ JSON.stringify({ vals_list: [{ name: 'Web: ' + $json.body.empresa, contact_name: $json.body.nombre, email_from: $json.body.email, description: $json.body.mensaje, type: 'lead' }] }) }}",
"credentials": { "httpHeaderAuth": { "name": "Odoo lab - API key (header)" } }
// La clave no esta aqui: la pone esa credencial.Przepływ nie loguje się też jako administrator, lecz jako użytkownik techniczny z minimalnymi grupami i limitem, jaki Odoo 19 nakłada na jego klucz:
# Usuario tecnico nuevo (solo grupo de usuario interno):
POST /json/2/crm.lead/create
-> 403 "No puede crear informes 'Lead' (crm.lead) ...
- Sales/Administrator
- Sales/User: Own Documents Only"
# Tras anadirle sales_team.group_sale_salesman: -> 200
# Su clave API tampoco dura lo que uno quiera:
_generate(..., +200 dias) -> "No puede exceder 90.0 dias."
_generate(..., sin fecha) -> "La clave API debe tener una
fecha de vencimiento"Ten limit 90 dni to data, w której Twój przepływ przestanie działać bez udziału kogokolwiek. Zapisz ją w dniu utworzenia klucza.
Pięć automatyzacji, które mieszczą się w przepływie
Wszystkie łączy jedno: fakt już się wydarzył, a przepływ tylko przenosi go w inne miejsce.
| Przypadek | Wyzwalacz | Wywołanie Odoo |
|---|---|---|
| Lead z zewnętrznego formularza | Webhook n8n | crm.lead / create |
| Powiadomienie na czacie po zatwierdzeniu dostawy | Automatyzacja Odoo z akcją webhooka | Brak: Odoo wypycha dane |
| Kontakty do narzędzia marketingowego | Harmonogram, co noc | res.partner / search_read według write_date |
| Alert o niskim stanie magazynowym | Harmonogram, co rano | product.product / search_read z qty_available |
| Dzienny raport dla zarządu | Harmonogram | read_group na sale.order |
Drugi przypadek ma drobny druk. Akcja webhooka wysyła _model, _id i nazwę akcji, a działa zgodnie z zasadą „wyślij i zapomnij”: POST trwający sekundę, bez ponowienia. W wersji 19 wychodzi po commit; w 17 i 18 odbywa się wewnątrz transakcji, więc wolny n8n opóźnia użytkownika.
# Accion de servidor state='webhook' al crear un lead.
INFO Webhook call to http://n8n:5678/webhook/odoo-lead
INFO Webhook call to http://n8n:5678/webhook/odoo-lead - succeeded
# Apuntando a un flujo borrado (el lead se crea igual):
WARNING Webhook call failed: 404 Client Error: Not Found for url:
http://n8n:5678/webhook/flujo-borrado
WARNING Webhook call timed out after 1s - it may or may not have failed.Pięć, które nie, i dokładny powód
- Obliczanie cen lub rabatów. Odoo liczy je z cennika; jeśli przepływ liczy je na zewnątrz, po zmianie cennika są dwie prawdy.
- Rezerwowanie zapasów dla wielu kanałów. Odoo rozstrzyga wyścig wewnątrz transakcji; przepływ, który osobno czyta, decyduje i zapisuje, sprzeda więcej, niż jest.
- Uzgadnianie płatności. Dopasowanie i zaksięgowanie idą razem: jeśli jedno dzieje się na zewnątrz, a drugie wewnątrz, przerwa w sieci zostawia pół uzgodnienia.
- To, co ktoś będzie audytował. Historia n8n to nie chatter: „kto to zmienił i dlaczego?” sprawdza się w dokumencie.
- To, co zależy od pola zmieniającego się między wersjami. Sprawdziliśmy to, zapisując w Odoo 19 to, co działało w 18.
Przypadek, który najlepiej to podsumowuje: zatwierdzenie dostawy z przepływu. Przygotowaliśmy dostawę na 10 sztuk z 4 zarezerwowanymi i wywołaliśmy button_validate, czyli to samo, co przycisk.
# WH/OUT/00003: 10 pedidas, 4 reservadas.
POST /web/dataset/call_kw
{"model":"stock.picking","method":"button_validate","args":[[2]]}
-> 200 {"result": {"name": "¿Crear entrega parcial?",
"type": "ir.actions.act_window",
"res_model": "stock.backorder.confirmation", ...}}
read -> [{"name":"WH/OUT/00003","state":"assigned"}] # sigue abiertoHTTP 200, bez błędu, i dostawa w assigned. Dla n8n krok wyszedł na zielono; dla magazynu zamówienie nie wyszło. Moduł rozpoznaje kreator i zapisuje to w dokumencie: ta sama granica co w Odoo 19 a konektory middleware.
A pola, które zmieniają nazwę między wersjami, czyli to, co psuje stabilny przepływ po migracji:
# Odoo 19, escribiendo lo que funcionaba en 17 y 18:
res.users write {"groups_id": [[4, 1]]}
-> "Invalid field 'groups_id' in 'res.users'" # en 19 se llama group_ids
stock.move create {"name": "Latiguillo", "product_id": 1, ...}
-> "Invalid field 'name' in 'stock.move'" # en 17 y 18 era obligatorioUtrzymujemy ten sam kod w Odoo 19, 18 i 17 w 105 opublikowanych modułach: te różnice pokrywa moduł, nie klient. To także granica Odoo Studio, gdy proces przestaje być polem i staje się regułą.
Cztery błędy, które widzimy zawsze
- Pętla. Automatyzacja powiadamia n8n o zmianie pola, przepływ zapisuje w Odoo, a zapis ponownie ją uruchamia. Przerywa się to warunkiem w wyzwalaczu.
- Poświadczenie jawnym tekstem. Ani w treści węzła, ani w węźle z kodem: w poświadczeniu n8n, z użytkownikiem technicznym o minimalnych grupach.
- Brak idempotencji. Webhook ponowiony po drugiej stronie tworzy rekord jeszcze raz: trzy identyczne
POSTdo naszego przepływu dały trzy leady. - Brak prawdziwego ponowienia. Węzeł nie ponawia, dopóki nie włączysz Retry On Fail, a silnik ogranicza próby do pięciu i oczekiwanie do pięciu sekund. Wystarcza dla czatu, nie dla przewoźnika: nasz moduł Correos Express ponawia po 5, 15, 30, 60, 120 i 240 minutach.
Rozwiązanie nie leży w n8n, lecz w projekcie: zapisz w Odoo zewnętrzny odnośnik i sprawdź go przed utworzeniem. W module to unikalne ograniczenie w bazie danych; w przepływie wcześniejszy odczyt z oknem wyścigu.
Kiedy przepływ staje się modułem
Przepływ to tani sposób, by odkryć, czy proces zasługuje na istnienie. Sygnałem, że okazał się za ciasny, jest jeden z tych sześciu:
- Zapisuje pole, które Odoo oblicza samo.
- Dwa zapisy muszą wydarzyć się razem albo wcale.
- Ktoś będzie audytować w Odoo, co się stało i kiedy.
- Proces musi przetrwać następną migrację.
- Wywołanie trzeba móc powtórzyć bez duplikowania czegokolwiek.
- Użytkownik musi móc ponowić próbę z samego dokumentu.
W tym momencie nie wyrzuca się przepływu: do modułu przenosi się część dotykającą stanu biznesu, a n8n zostaje na brzegu. Tak samo jest przy automatyzacji zadań administracyjnych i w integracji z Signaturit.
Podsumowanie: jeśli przepływ padnie i jedyną konsekwencją jest to, że ktoś nie dostanie powiadomienia, n8n wystarczy. Jeśli padnie, a magazyn lub rejestr faktur zostaną w stanie, którego nikt nie umie odczytać, to był przypadek na moduł.
Najczęstsze pytania
Czy mogę przekazać język lub firmę w wywołaniu?
Trzema nowoczesnymi drogami tak: kwargs.context w call_kw i w execute_kw, a pole context w /json/2 (kraj wychodzi jako „Spain” z en_US i „España” z es_ES). Nie da się tego klasycznym poświadczeniem, które wywołuje execute, pozycyjne.
Gdzie przechowywać klucz API i jak długo działa?
W poświadczeniu n8n, nigdy w treści węzła. W Odoo 19 klucz użytkownika niebędącego administratorem wymaga daty wygaśnięcia, a limit ustala grupa: 90 dni dla użytkownika wewnętrznego.
Czy mój przepływ przestanie działać po migracji z Odoo 18 do 19?
To zależy od pól, których dotyka, i nie ostrzega: res.users.groups_id zmieniło się w group_ids i stock.move.name, obowiązkowe w 17 i 18, nie istnieje w 19. Przetestuj swoje przepływy na kopii.
Przydatne linki w FlexigoTech
Co robimy w tym temacie
Masz przepływy n8n działające z Odoo i nie wiesz już, które wytrzymają?
Przeglądamy je, mówimy, które zostają jak są, a które trzeba przenieść do modułu, i tworzymy moduł, jeśli trzeba. Napisz na comercial@flexigobe.com lub zadzwoń pod numer +34 616 809 504.

