Workflows multi-step
Encadeie múltiplas ações: ler API → filtrar resultado → enviar notificação. Tudo declarativo, sem JS arbitrário.
Quando usar
- "Toda madrugada: pega pedidos do Bling, filtra os atrasados, manda WhatsApp pro gestor"
- "Toda segunda: lê planilha do RH, pega quem completa 1 ano, manda email parabéns"
- "A cada hora: checa estoque baixo, dispara alerta Slack"
Estrutura
await Bea.cron.create({
expression: "0 3 * * *", // toda noite às 3h
name: "Alerta pedidos atrasados",
action: {
type: "workflow",
steps: [
// Step 1: busca pedidos
{
id: "fetchOrders",
type: "integration",
integrationId: "bling",
action: "get",
payload: { path: "/pedidos/vendas?situacao=aberto" }
},
// Step 2: notifica via WhatsApp
{
id: "alertManager",
type: "integration",
integrationId: "zapi",
action: "send-text",
payload: {
phone: "5511999999999",
message: "Pedidos abertos: {{ $fetchOrders.data.length }}"
},
skipIf: "{{ $fetchOrders.data.length === 0 }}"
}
]
}
});
Sintaxe de templates
Use {{ $stepId.path.to.field }} em qualquer payload pra referenciar saída de step anterior:
"Total: {{ $fetch.data.count }}"
"{{ $foo.array.length === 0 }}" // boolean
"Olá {{ $user.name }}"
Operadores: ===, !==, >, <, >=, <=. Não tem &&, ||, chamadas de função.
skipIf
Pula o step se a expressão for truthy:
{ ..., skipIf: "{{ $fetch.data.length === 0 }}" }
continueOnError
Por default, falha em um step aborta o workflow. Pra continuar:
{ ..., continueOnError: true }
3 tipos de step
| type | O que faz |
|---|---|
integration | Chama qualquer integração (integrationId, action, payload) |
webhook | HTTP fetch (url, method, headers, body) |
email | Envia email (to, subject, html, replyTo?) |
Limites
- Max 25 steps por workflow
- Timeout 30s por step
- Sem loops (
for/while) — pra iterar muito, processe no destino
Exemplo completo: digest semanal
{
expression: "0 9 * * 1",
name: "Digest semanal",
action: {
type: "workflow",
steps: [
{ id: "vendas", type: "integration",
integrationId: "bling", action: "get",
payload: { path: "/pedidos/vendas?dataEmissao_de=2026-04-23" } },
{ id: "leads", type: "integration",
integrationId: "pgExternal", action: "query",
payload: { sql: "SELECT COUNT(*) FROM leads WHERE created_at > NOW() - INTERVAL '7 days'" } },
{ id: "email", type: "email",
to: "diretor@empresa.com",
subject: "Resumo da semana",
html: "Vendas: {{ $vendas.data.length }}<br/>Leads: {{ $leads.rows.0.count }}" }
]
}
}