O n8n serve para o que acontece em redor do Odoo: recolher um formulário externo, avisar um chat, montar um relatório diário. O que altera o estado de negócio lá dentro (preços, reservas de stock, validações de operação de stock, reconciliação de pagamentos) pede um módulo. A fronteira vê-se ao executar as duas coisas contra um Odoo a sério: este artigo nasce de um laboratório próprio com Odoo 19.0-20260630 e n8n 2.30.6.
Ideia-chave: um fluxo que chama a API do Odoo não executa a sua interface. Pode receber um 200 com um assistente lá dentro e julgar que validou uma operação de stock que continua aberta.
Como o n8n fala com o Odoo: quatro caminhos, não um
- XML-RPC:
/xmlrpc/2/commonpara autenticar e/xmlrpc/2/objectparaexecute_kw. O da documentação. - JSON-RPC: um
POST /jsonrpccomservice,methodeargs. O mesmo serviço em JSON. - Sessão web:
/web/session/authenticatee/web/dataset/call_kwcom o cookie. O que faz o seu navegador. - A API JSON-2, só no Odoo 19:
POST /json/2/<modelo>/<método>comAuthorization: bearer <clave API>eX-Odoo-Database. Sem sessão: os argumentos vão como campos com nome,contextincluído.
Os três primeiros continuam a funcionar na 19, mas o servidor avisa no log: «The /xmlrpc, /xmlrpc/2 and /jsonrpc endpoints are deprecated in Odoo 19 and scheduled for removal in Odoo 22». Um fluxo novo contra uma 19 deveria ir por /json/2; se serve também a 17 e 18, pela sessão.
# 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." O nó Odoo do n8n 2.30.6 escolhe por si conforme a credencial: a de chave API vai por /json/2; a clássica vai por /jsonrpc com execute, posicional, que não aceita kwargs e não pode passar contexto. A credencial de chave API avisa ainda de que requer «Odoo 19+ and a Custom pricing plan».
O nó HTTP Request, tal como ficou
Repare onde não está a chave: o corpo só leva dados e o cabeçalho Authorization é posto por uma credencial do n8n, que se cifra e se roda à parte.
// 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.O fluxo também não entra como administrador, mas como utilizador técnico com os grupos certos e o limite que o Odoo 19 põe à sua chave:
# 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"Esse limite de 90 dias é a data em que o seu fluxo deixará de funcionar sem que ninguém lhe toque. Anote-a no dia em que cria a chave.
Cinco automatizações que cabem num fluxo
Todas partilham o mesmo: o facto já ocorreu e o fluxo apenas o move de sítio.
| Caso | Disparador | Chamada ao Odoo |
|---|---|---|
| Lead a partir de um formulário externo | Webhook do n8n | crm.lead / create |
| Aviso ao chat ao validar uma operação de stock | Automatização do Odoo com ação de webhook | Nenhuma: o Odoo empurra |
| Contactos para uma ferramenta de marketing | Agendado, todas as noites | res.partner / search_read por write_date |
| Alerta de stock baixo | Agendado, todas as manhãs | product.product / search_read de qty_available |
| Relatório diário para a direção | Agendado | read_group sobre sale.order |
O segundo caso tem letra pequena. A ação de webhook envia _model, _id e o nome da ação, e é «lançar e esquecer»: um POST de um segundo, sem nova tentativa. Na 19 sai depois do commit; na 17 e 18 vai dentro da transação, pelo que um n8n lento atrasa o utilizador.
# 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.Cinco que não, e o motivo exato
- Calcular preços ou descontos. O Odoo calcula-os a partir da tarifa; se o fluxo os calcula fora, ao mudar a tarifa há duas verdades.
- Reservar stock para vários canais. O Odoo resolve a corrida dentro de uma transação; um fluxo que lê, decide e escreve em separado vende em excesso.
- Reconciliar pagamentos. Emparelhar e lançar andam juntos: se um se faz fora e o outro dentro, um corte de rede deixa meia reconciliação.
- O que alguém vá auditar. O histórico do n8n não é o chatter: «quem alterou isto e porquê?» responde-se no documento.
- O que dependa de um campo que muda entre versões. Comprovámo-lo escrevendo no Odoo 19 o que funcionava na 18.
O caso que melhor o resume: validar uma operação de stock a partir de um fluxo. Preparámos uma de 10 unidades com 4 reservadas e chamámos button_validate, o mesmo que o botão.
# 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, sem erro, e uma operação de stock em assigned. Para o n8n o passo saiu verde; para o armazém, a encomenda não saiu. Um módulo reconhece o assistente e deixa-o registado no documento: a mesma fronteira que em Odoo 19 face aos conectores de middleware.
E os campos que mudam de nome entre versões, o que parte um fluxo estável depois de uma migração:
# 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 obligatorioMantemos o mesmo código no Odoo 19, 18 e 17 em 105 módulos publicados: estas diferenças paga-as o módulo, não o cliente. É também o limite do Odoo Studio quando o processo deixa de ser um campo e passa a ser uma regra.
Os quatro erros que vemos sempre
- O ciclo. Uma automatização avisa o n8n ao mudar um campo, o fluxo escreve no Odoo e o que foi escrito volta a disparar a automatização. Corta-se com uma condição no disparador.
- A credencial em texto simples. Nem no corpo do nó nem num nó de código: numa credencial do n8n, com um utilizador técnico de grupos mínimos.
- Sem idempotência. Um webhook repetido do outro lado cria o registo outra vez: três
POSTidênticos ao nosso fluxo deram três leads. - Sem nova tentativa a sério. Um nó não volta a tentar a menos que ative Retry On Fail, e o motor limita as tentativas a cinco e a espera a cinco segundos. Sobra para um chat; não para uma transportadora: o nosso módulo de Correos Express volta a tentar aos 5, 15, 30, 60, 120 e 240 minutos.
A solução não é do n8n, é de desenho: guarde no Odoo a referência externa e verifique-a antes de criar. Num módulo é uma restrição única na base de dados; num fluxo, uma leitura prévia com janela de corrida.
Quando um fluxo se converte em módulo
O fluxo é uma forma barata de descobrir se o processo merece existir. O sinal de que ficou curto é um destes seis:
- Escreve um campo que o Odoo calcula por conta própria.
- Duas escritas têm de ocorrer juntas ou não ocorrer.
- Alguém vai auditar dentro do Odoo o que aconteceu e quando.
- O processo tem de sobreviver à próxima migração.
- É preciso poder repetir a chamada sem duplicar nada.
- O utilizador precisa de voltar a tentar a partir do próprio documento.
Chegado esse ponto não se deita fora o fluxo: leva-se para o módulo a parte que toca o estado de negócio e o n8n fica com a periferia. Passa-se o mesmo em automatizar tarefas administrativas e na integração com a Signaturit.
Resumo: se o fluxo falha e o único efeito é alguém não receber um aviso, o n8n serve. Se falha e o armazém ou o livro de faturas ficam num estado que ninguém sabe ler, isso era um módulo.
Perguntas frequentes
Posso passar o idioma ou a empresa na chamada?
Pelos três caminhos modernos sim: kwargs.context em call_kw e em execute_kw, e um campo context em /json/2 (um país sai «Spain» com en_US e «España» com es_ES). Não pode com a credencial clássica, que chama execute, posicional.
Onde guardo a chave API e quanto dura?
Numa credencial do n8n, nunca no corpo do nó. No Odoo 19 a chave de um utilizador não administrador precisa de caducidade, e o limite fixa-o o grupo: 90 dias para um utilizador interno.
O meu fluxo parte-se ao migrar do Odoo 18 para o 19?
Depende dos campos em que toque, e não avisa: res.users.groups_id passou a group_ids e stock.move.name, obrigatório na 17 e 18, não existe na 19. Teste os seus fluxos contra uma cópia.
Ligações úteis dentro da FlexigoTech
O que fazemos sobre isto
Tem fluxos do n8n contra o Odoo e já não sabe quais aguentam?
Revemo-los, dizemos-lhe quais ficam como estão e quais há que levar para um módulo, e fazemos o módulo se for preciso. Escreva para comercial@flexigobe.com ou ligue para o +34 616 809 504.

