Package Information
Available Nodes
Documentation generating…
Documentation
n8n-nodes-revflow
Node community do n8n para o RevFlow, CRM multi-tenant
brasileiro. Consome a API pública /api/v1/* do RevFlow (contrato completo em../API_CONTRACT.md, na raiz de integrations/).
Status: publicado — n8n-nodes-revflow@0.2.0
está no registry do npm (publicado 2026-08-30, token de automação
fornecido pelo dono do RevFlow naquela sessão — não persiste entre
sessões, ver seção "Publicando de verdade" pra publicar uma versão nova
depois de mudar o código de novo). Instalável vianpm install n8n-nodes-revflow ou pela aba Settings → Community Nodes
do próprio n8n.
Changelog
- 0.2.0 (2026-08-30, publicada) —
RevFlow Triggermigrado de polling
(poll()) pra webhook em tempo real (webhookMethods+webhook()),
consumindo a API de webhooks nova (POST /api/v1/webhooks). Ver seção
"RevFlow Trigger precisa de URL pública" abaixo antes de testar
localmente. - 0.1.0 (2026-08-30, publicada) — primeira versão.
RevFlow(ação) +RevFlow Trigger(polling).
O que este pacote faz
- Credencial
RevFlow API(credentials/RevFlowApi.credentials.ts): guarda
a chave de API (rfk_...) e a Base URL (padrãohttps://crmrevflow.vercel.app/api/v1, editável). Injeta o headerAuthorization: Bearer <chave>em toda chamada e testa a credencial contraGET /companies?limit=1. - Node
RevFlow(nodes/RevFlow/RevFlow.node.ts): node de ação
programático (não declarative-only) com os 6 recursos do contrato —
Company, Contact, Deal, Lead, Ticket, Task — e as operações que a API
realmente oferece por objeto:Create(POST),Update(PATCH/{id}),Get(GET/{id}),Get Many(GET lista, comSince/Limit/Return All);Find By Email(GET?email=&limit=1) só em Company, Contact e Lead —
os 3 únicos objetos com colunaemail.- Sem operação de exclusão em nenhum recurso (a API pública não tem
DELETE) e sem campo para trocar a Company associada numUpdatede
Contact/Deal/Ticket (a API só aceita isso na criação).
- Node
RevFlow Trigger(nodes/RevFlowTrigger/RevFlowTrigger.node.ts):
trigger de webhook em tempo real desde a v0.2.0 (2026-08-30) — a API
pública ganhou webhooks de saída (POST /api/v1/webhooks, verAPI_CONTRACT.md). Ao ativar o workflow, o node se inscreve
(webhookMethods.create, chamado com a própria URL de webhook do n8n) e
passa a receber umPOSTassinado (HMAC-SHA256, headerX-RevFlow-Signature: sha256=<hex>) a cada registro novo do objeto
escolhido — sem cursorsince, sem intervalo de checagem.webhook()
valida a assinatura contra os bytes crus da requisição
(req.rawBody, preenchido pelo próprio middleware do n8n antes do parse
— nunca reserializa o JSON pra comparar, o que arriscaria produzir um
texto diferente do que foi assinado) antes de emitir o item; assinatura
inválida ou ausente →401, sem disparar o workflow.webhookMethods.deletecancela a inscrição (DELETE /api/v1/webhooks/{id})
quando o workflow é desativado ou o node é removido;checkExists
confirma que a inscrição salva ainda existe do lado da RevFlow antes de
decidir se recria (ex.: alguém revogou manualmente em/chaves-de-api).
Versão anterior (v0.1.0,version: 1) fazia polling (poll(),
cursorsinceemgetWorkflowStaticData) — descontinuada semIVersionedNodeType(sem base real de workflow em produção usando a
v1 no momento da mudança, ver comentário no topo do arquivo do node).
Nenhum campo ou endpoint aqui foi inventado — tudo foi implementado lendoAPI_CONTRACT.md inteiro antes de escrever código.
Rodando localmente
cd integrations/n8n
npm install
npm run build # tsc -> dist/
npm run lint # eslint-plugin-n8n-nodes-base (preset oficial de community node)
npm test # jest, com mocks do contexto do n8n (sem subir n8n de verdade)
Os três passam limpos neste ambiente (Node 22, TypeScript 5.9, n8n-workflow
2.16 — a versão retornada por npm view n8n-workflow version no momento em
que este pacote foi criado).
Sobre o lint
O preset eslint-plugin-n8n-nodes-base é o mesmo conjunto de regras usado
pela verificação automática do n8n quando o pacote é instalado ou submetido
para a listagem de community nodes — por isso ele está configurado aqui (não
foi preciso pular por falta de rede; o pacote e o @typescript-eslint/parser
que ele precisa foram instalados normalmente do registry).
Uma única regra do preset foi desligada deliberadamente, com o motivo
documentado em .eslintrc.js:n8n-nodes-base/cred-class-field-documentation-url-miscased. A própria
descrição da regra diz "Only applicable to nodes in the main repository" — ela
assume que documentationUrl é um slug interno do site de docs do n8n e tenta
"corrigir" qualquer outra coisa convertendo para camelCase, o que destrói uma
URL real de community node (ela transformavahttps://crmrevflow.vercel.app/chaves-de-api emhttpsCrmrevflowVercelAppChavesDeApi). Todas as outras regras do preset
(nodes, credentials e package.json) passam sem exceção.
Testando dentro de uma instância n8n local
Depois de npm run build, existem duas formas de expor o pacote pra uma
instância n8n rodando na sua máquina:
Opção 1 — npm link
cd integrations/n8n
npm link
# numa instância n8n local (self-hosted, via npm/pnpm, não Docker Cloud):
cd ~/.n8n # ou onde estiver instalado o n8n
npm link n8n-nodes-revflow
Depois, suba o n8n com a variável de ambiente apontando pra onde os
community nodes ficam:
export N8N_CUSTOM_EXTENSIONS="$(npm root -g)/n8n-nodes-revflow"
n8n start
(Ajuste o caminho se o seu npm link resolver para outro diretório — rodenpm ls -g n8n-nodes-revflow pra confirmar.)
Opção 2 — copiar pra ~/.n8n/custom
mkdir -p ~/.n8n/custom
cp -r integrations/n8n ~/.n8n/custom/n8n-nodes-revflow
cd ~/.n8n/custom/n8n-nodes-revflow
npm install --omit=dev
npm run build
n8n start
Em qualquer uma das duas opções, os nodes RevFlow e RevFlow Trigger
devem aparecer na busca de nodes do editor do n8n após reiniciar.
RevFlow Trigger precisa de URL pública (desde a v0.2.0)
Diferente da v0.1.0 (polling — o n8n é quem chamava a RevFlow, de dentro
pra fora), o RevFlow Trigger agora é um webhook de verdade: ao ativar
o workflow, a RevFlow passa a chamar de fora pra dentro da sua
instância n8n a cada registro novo. Uma instância local
(http://localhost:5678) não é alcançável pela internet — pra testar de
ponta a ponta (não só os testes automatizados com mock), exponha-a com um
túnel (n8n start --tunnel, ou ngrok http 5678 + configurarWEBHOOK_URL com a URL pública) antes de ativar o workflow. Sem isso, a
inscrição em POST /api/v1/webhooks é criada normalmente, mas a entrega
nunca chega — o destino (target_url) simplesmente não responde.
Testando com uma chave de API de verdade
Pra testar de ponta a ponta (não só os testes automatizados com mock), você
precisa de uma chave de API rfk_... gerada numa organização RevFlow real,
em RevFlow → Chaves de API (/chaves-de-api, como administrador da
organização). Sem isso:
Get Many/Get/Find By Emailem Company, Contact, Task funcionam com
qualquer chave válida (objetos Core, sem módulo pago).- Deal, Lead, Ticket exigem, respectivamente, os módulos pagos
sales,marketingeservicesativos pra organização da chave — sem isso a API
responde403(o node propaga essa mensagem, não a esconde).
Nunca commite uma chave de API real em nenhum lugar deste repositório —
nem em código, nem em fixtures de teste, nem em exemplos de README. Use apenas
via credencial configurada na UI do n8n (que fica fora do controle de versão).
Publicando de verdade (o que só você pode fazer)
Eu não tenho conta npm nem acesso à verificação de community node do n8n —
os passos abaixo dependem de uma pessoa:
- Criar/logar numa conta npm própria:
npm login(o pacote precisa ser
publicado sob um nome ou escopo que pertença a você — hoje ele se chaman8n-nodes-revflow; se esse nome já estiver em uso por outra pessoa no
registry público, será preciso escopar, ex.:@sua-org/n8n-nodes-revflow,
e então também ajustarpackage.json→n8n→ os caminhos continuam os
mesmos, só onamemuda). Ajuste tambémrepository.urleauthorempackage.json— os valores atuais (github.com/revflow/n8n-nodes-revflow,
autor "RevFlow") são placeholders escritos durante o desenvolvimento, não
uma conta ou repositório real. - Publicar: depois de
npm run build(o scriptprepublishOnlyjá roda
build + test automaticamente antes do publish, mas rode manualmente antes
pra revisar onpm pack --dry-runprimeiro):npm run build npm test npm publish - Submeter pra listagem oficial de community nodes do n8n: hoje isso
acontece automaticamente quando alguém instala o pacote (o n8n roda uma
verificação own no momento da instalação) — pra aparecer na lista
pesquisável de community nodes dentro do editor do n8n, existe também um
processo de submissão / pedido de inclusão na lista "verified", que exige
aprovação da equipe do n8n. Isso está fora do meu controle e do desta
automação — acompanhe a documentação oficial do n8n sobre "community
nodes" no momento da publicação, pois o processo evolui com o tempo. - Versionamento: depois do primeiro publish, qualquer mudança exige subir
versionempackage.json(npm version patch|minor|major) antes de
publicar de novo — o npm registry rejeita republicar a mesma versão.
Estrutura do pacote
integrations/n8n/
├── credentials/
│ ├── RevFlowApi.credentials.ts
│ └── RevFlowApi.credentials.test.ts
├── nodes/
│ ├── RevFlow/
│ │ ├── RevFlow.node.ts
│ │ ├── RevFlow.node.test.ts
│ │ ├── GenericFunctions.ts # requisição HTTP + tratamento de erro compartilhados
│ │ └── revflow.svg # ícone (não é a marca real — "RF" genérico)
│ └── RevFlowTrigger/
│ ├── RevFlowTrigger.node.ts
│ ├── RevFlowTrigger.node.test.ts
│ └── revflow.svg
├── test/
│ └── mockContext.ts # fábrica de contexto falso p/ testar nodes sem subir n8n
├── package.json
├── tsconfig.json
├── jest.config.js
└── .eslintrc.js
Decisões de design não 100% explícitas no contrato
Return Allnão é um export completo da base: a API não pagina por
cursor (API_CONTRACT.md, "Padrão de gatilho"). O node segue o padrão
idiomáticoReturn All/Limitdo n8n, mas comReturn Allmarcado ele
busca exatamente o teto de 200 registros mais recentes — nunca mais que
isso. Isso está documentado no campo "Since" e na descrição da operação
"Get Many", já que a descrição do próprio campoLimit/Return Allsegue
o texto padrão exigido pelo preset de lint do n8n (não deu pra colocar a
ressalva ali sem violar a regranode-param-description-wrong-for-limit).- Validação client-side de
pipeline_id/stage_id: a API já rejeita com400se só um dos dois for informado (Deal/Ticket), mas o node valida isso
antes de chamar a API, poupando uma chamada e dando um erro mais claro. - Validação client-side de "Update Fields" vazio: mesma lógica — a API já
rejeita PATCH sem nenhum campo com400, o node antecipa isso. - Verificação de assinatura do RevFlow Trigger usa
req.rawBody, nuncagetBodyData()reserializado: comparar HMAC contraJSON.stringify(getBodyData())arriscaria produzir um texto diferente do
que a RevFlow assinou de fato (ordem de chave, formatação de número) —
invalidaria a verificação por um falso negativo.req.rawBodyé
preenchido pelo próprio middleware de body-parsing do n8n
(rawBodyReader,packages/cli/src/middlewares/body-parser.ts) antes do
JSON ser parseado, mas não está no tipo públicoexpress.RequestdeIWebhookFunctions.getRequestObject()— daqui o cast explícito no node. - Sem
IVersionedNodeTypena migração de polling pra webhook: a v0.1.0
(sópoll(), publicada 1 dia antes) não tinha base real de workflow em
produção — manter as duas versões vivas lado a lado (nodeVersions)
adicionaria complexidade sem ninguém pra proteger.RevFlowTriggerfoi
direto praversion: 2como node único, comportamento novo pra quem
reativar o workflow depois do upgrade. - Erros de API:
GenericFunctions.tsextrai a mensagem{ "error": "..." }
da API e monta umNodeApiErrorcom essa mensagem como texto principal
(nunca escondida atrás de "Request failed"), com um destaque extra pro
headerRetry-Afterem erros429.continueOnFailfunciona normalmente
porque o erro só é capturado no loop principal doexecute(), nunca dentro
deGenericFunctions.ts.