Trilha 08 · Integrações e implantação
Padrões de integração na prática
Como um processo do Autoflow conversa com outros sistemas: buscar dados em APIs, registrar em ERPs, esperar respostas, receber pedidos e avisar por webhook. Cinco padrões, o papel do conector intermediário e o que acontece quando algo dá errado.
Por que processos precisam falar com outros sistemas
Quase nenhum processo real vive sozinho. No meio do fluxo aparecem momentos em que a informação está em outro lugar ou precisa ir para outro lugar:
- um escritório de advocacia precisa buscar processos em que o cliente é parte nos tribunais antes de aceitar o caso;
- uma prefeitura precisa consultar a situação cadastral de um CNPJ antes de emitir um alvará;
- uma concessionária precisa avisar o ERP quando a venda for concluída;
- um sistema de captura de publicações precisa abrir um processo de prazo sempre que sai uma intimação.
Sem integração, alguém faz isso à mão: abre outro sistema, copia, cola, anexa um print. É lento, gera erro de digitação e não deixa rastro.
Integração costuma ser a parte que mais gera valor (elimina digitação dupla e espera) e a que mais gera risco de prazo no projeto, porque depende de outro sistema, de outra equipe e, às vezes, de outro fornecedor. Saber qual padrão usar em cada caso evita prometer o que o Autoflow não faz e evita construir algo complicado onde um padrão simples resolve.
As quatro direções
Toda integração responde a uma pergunta: quem começa a conversa e quem espera quem?
O processo pede algo
Bloco Enviar a sistema externo. Pode seguir na hora (padrão 1) ou esperar o retorno (padrão 2).
Outro sistema abre o processo
API pública: POST /public/v1/process-instances (padrão 3).
O Autoflow avisa o que aconteceu
Webhook assinado a cada evento: processo concluído, tarefa criada… (padrão 4).
Trabalhar sem trocar de tela
Login único (SSO) + tarefa aberta dentro do ERP (padrão 5).
Explore cada padrão abaixo: a sequência mostra quem chama quem, e os blocos de código mostram exatamente o que trafega.
O ponto que mais confunde: o conector intermediário
Este é o conceito mais importante da lição. Leia com calma.
O bloco Enviar a sistema externo do Autoflow sempre faz a chamada do mesmo jeito:
- método POST, corpo JSON;
- para o endereço URL base da integração + caminho configurado no bloco;
- assinado pelo Autoflow (cabeçalho
X-ProcessFlow-Signature, HMAC-SHA256 com o segredo do webhook da integração); - sem campo para colocar o token, a chave ou o certificado de outro sistema.
Já as APIs do mundo real são todas diferentes. A API de um tribunal pede uma chave própria num cabeçalho e usa uma consulta específica. Um provedor de dados cadastrais pede OAuth. Um sistema legado do órgão só fala SOAP ou exige certificado digital. Um ERP quer o cliente num formato próprio.
Por isso, na maioria dos casos, existe uma peça no meio: o conector intermediário (também chamado de adaptador ou middleware). É um serviço pequeno, mantido pela sua equipe ou pela TI do cliente, que:
- Recebe o pedido do Autoflow e confere a assinatura (garante que veio mesmo do Autoflow).
- Traduz para o formato da API de destino e usa as credenciais dela (que ficam guardadas no conector, não no Autoflow).
- Chama uma ou várias APIs, pagina resultados, junta fontes, trata indisponibilidade.
- Devolve ao Autoflow um resultado simples: na hora (resposta 2xx) ou depois, pelo
callbackUrl, com variáveis e arquivos.
“O Autoflow sabe pedir e sabe esperar a resposta. Quem sabe falar a língua de cada sistema é o conector.” Assim fica claro quem constrói e mantém cada parte, e o fluxo desenhado no Autoflow não muda quando um fornecedor troca a API.
Quando NÃO precisa de conector
Quando o sistema de destino é construído para conversar com o Autoflow: ele aceita o POST, confere a assinatura e, se for o caso, chama o callbackUrl. É o caso de sistemas internos que a TI do cliente pode adaptar, ou de parceiros que implementam o contrato do Autoflow. O despachante do pacote Concessionária (parceiro gerenciado) é um exemplo: o Autoflow já sabe falar com ele.
Exemplo de conector (Node.js)
Um conector mínimo, para você mostrar à TI do cliente. Ele recebe o pedido, confere a assinatura, responde 202, faz a busca e devolve pelo callback.
// conector-juridico.js — exemplo didático (Node 22+, Express)
import express from 'express';
import crypto from 'node:crypto';
const app = express();
app.use(express.raw({ type: 'application/json' })); // precisa do corpo BRUTO para conferir a assinatura
const WEBHOOK_SECRET = process.env.AUTOFLOW_WEBHOOK_SECRET; // whsec_… da integração no Autoflow
const AUTOFLOW_API_KEY = process.env.AUTOFLOW_API_KEY; // pf_… da mesma integração (para o callback)
function assinaturaValida(req) {
const header = req.get('X-ProcessFlow-Signature') || ''; // "t=1761220800,v1=abc…[,v1=…]"
const parts = Object.groupBy(header.split(','), (p) => p.split('=')[0]);
const t = Number(parts.t?.[0]?.split('=')[1]);
if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false; // mais de 5 min: recusa
const esperado = crypto.createHmac('sha256', WEBHOOK_SECRET).update(`${t}.${req.body}`).digest('hex');
return (parts.v1 || []).some((p) => {
const v = Buffer.from(p.split('=')[1] ?? '', 'hex');
return v.length === 32 && crypto.timingSafeEqual(v, Buffer.from(esperado, 'hex'));
});
}
app.post('/consultas/processos-por-parte', async (req, res) => {
if (!assinaturaValida(req)) return res.status(401).end();
const pedido = JSON.parse(req.body);
if (!pedido.parte?.documento) return res.status(422).json({ erro: 'documento obrigatório' }); // 4xx = recusa
res.status(202).json({ recebido: pedido.pedido }); // responde já; o trabalho vem depois
const processos = await buscarNosTribunais(pedido.parte.documento, pedido.tribunais); // usa as credenciais DO TRIBUNAL
const contra = processos.filter((p) => p.poloPassivo.includes(pedido.parte.documento));
await fetch(pedido.callbackUrl, {
method: 'POST',
headers: {
Authorization: `Bearer ${AUTOFLOW_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': `retorno-${pedido.pedido}`,
},
body: JSON.stringify({
exchangeId: pedido.pedido,
variables: {
processosEncontrados: processos.length,
processosContraCliente: contra.length,
resumoBusca: contra.map((p) => `${p.numero} (${p.tribunal})`).join('; ') || 'Nada contra o cliente',
},
}),
});
});
app.listen(8080);
Fila e novas tentativas se o callback falhar, registro (log) das consultas, guarda segura das credenciais, limite de chamadas às APIs de terceiros e tratamento de LGPD (não guardar dados pessoais além do necessário). Para o cliente, o conector é um sistema como outro qualquer: precisa de dono, hospedagem e monitoramento.
Montando o corpo do pedido: o template
Por padrão, o Autoflow envia um corpo com tudo (id da troca, dados do processo, todas as variáveis públicas, links dos documentos). Quando o sistema de destino espera um formato específico, você escreve um template no campo Template do payload do bloco, usando {{ caminho }}. Experimente:
O corpo padrão manda todas as variáveis do processo. Com o template, você manda só o necessário. É melhor para o outro sistema, que recebe exatamente o formato que espera, e melhor para a LGPD, porque nenhum dado pessoal sai sem necessidade. Em órgãos públicos e escritórios de advocacia, prefira sempre o template.
Síncrono ou assíncrono? Como escolher
A decisão mais comum na modelagem é entre o padrão 1 (enviar e seguir) e o padrão 2 (enviar e aguardar). Use esta regra:
| Pergunta | Se a resposta for “sim” |
|---|---|
| Um gateway vai decidir o caminho com base no resultado? | Padrão 2. No padrão 1 o resultado é um texto JSON numa variável; gateways não leem campos de dentro dele com facilidade. |
| A consulta pode levar mais de alguns segundos? | Padrão 2. O envio tem limite de 10 segundos. |
| O resultado traz arquivos (certidão, relatório, guia)? | Padrão 2. Arquivos só entram pelo retorno (callback). |
| É só registrar ou avisar algo em outro sistema? | Padrão 1. |
| Uma pessoa vai ler o resultado na tarefa seguinte e decidir? | Padrão 1 pode servir (o texto fica nas variáveis do processo), mas o padrão 2 deixa a informação mais limpa. |
No padrão 2, o retorno pode trazer desfechos de negócio além do sucesso: rejected (recusou), needs_correction (falta dado, com a lista de itens), cancelled, status (andamento, que aparece na linha do tempo sem liberar a espera) e partial (arquivos em partes). Cada um precisa estar habilitado no bloco (Aceitar recusa, Aceitar pendência…) e ter um caminho num gateway logo depois da espera, testando integrationOutcome. O editor avisa se você habilitar um desfecho e esquecer o caminho.
Quando dá errado
Integração falha. O outro sistema cai, recusa dados ou demora. O Autoflow tem um comportamento definido para cada caso. Clique nos cenários:
- “Aguardar retorno externo” sem prazo de borda. Se o retorno nunca vier, o processo fica parado para sempre sem nenhum alerta. Coloque sempre um timer não interruptivo que abre uma tarefa de cobrança.
- Recusa (4xx) sem “Código de erro para 4xx”. Toda recusa vira incidente técnico, quando na verdade era um problema de dado que o próprio usuário poderia corrigir. Configure o código e um evento de borda de erro levando a uma tarefa “Corrigir dados”.
Configurando no Autoflow, passo a passo
- Crie a integração. Administração › Configurações › Integrações › Nova integração (cargo de escopo Grupo com
integration.manage). No assistente: tipo, nome, processos liberados e unidade padrão, chave de acesso (pf_…, aparece uma única vez: entregue ao conector com segurança) e webhook (URL + segredowhsec_…, que também assina as ações). - Informe a “URL base das ações”. Na aba Webhook da integração. É o endereço do conector (HTTPS, acessível pela internet). O bloco Enviar soma o caminho a essa base.
- Teste e ative. O último passo do assistente faz um ping assinado e mostra um exemplo em curl.
- No fluxo, coloque o bloco “Enviar a sistema externo”. Escolha a integração, o caminho (ex.:
/consultas/processos-por-parte), o template do payload e a variável de resultado. - Se for esperar resposta: preencha Mensagem de retorno (ex.:
resultado-tribunais), coloque o bloco Aguardar retorno externo com a mesma mensagem e um timer de cobrança. Habilite os desfechos que o conector pode mandar. - Trate a recusa: preencha Código de erro para 4xx e coloque um evento de borda de erro com esse código.
- Publique e acompanhe. Cada chamada aparece em Integração › Trocas (pedido, resposta, status) e na linha do tempo do processo. Webhooks enviados aparecem em Entregas, com reenvio.
Levantamento de uma integração com o cliente
Antes de prometer prazo, levante estes pontos. A maioria dos atrasos em integração vem de uma pergunta que não foi feita no começo.
Resumo
- Cinco padrões: enviar e seguir, enviar e aguardar retorno, sistema inicia processo, webhook de eventos e tarefa dentro de outro sistema (SSO).
- O bloco Enviar sempre faz POST JSON assinado para a URL da integração. APIs de terceiros com autenticação e formato próprios precisam de um conector intermediário.
- Resultado para gateway decidir, consulta lenta ou retorno com arquivos: use enviar e aguardar. As variáveis do callback viram variáveis do processo.
- Use template de payload para mandar só o necessário (formato certo e LGPD).
- Sempre: prazo de cobrança em toda espera e código de erro para 4xx com caminho de correção.