Lógica de Rotas
Referência completa da sintaxe de condições. Operadores, funções, acesso a variáveis e armadilhas comuns.
Formato das condições
Por padrão, sem nenhuma condição de rota configurada, o processo simplesmente segue o fluxo: cada etapa executa e passa para a próxima na sequência em que aparecem no canvas, sem desviar para lugar nenhum. Uma condição de rota (ou "decisão de rota") é o que quebra essa linearidade: a regra que decide qual etapa executa em seguida, em vez de simplesmente seguir a próxima da sequência. O processo lê variáveis já disponíveis (capturadas antes, vindas de um conector, de um parâmetro de inicialização) e usa esse valor para escolher o caminho: "se o status for aprovado, vá para Emitir Nota; se for rejeitado, vá para Tratar Rejeição". É o mecanismo por trás de qualquer ramificação do fluxo, o equivalente a um if / else if / else dentro do processo.

Qualquer etapa com uma condição de rota configurada, Decisão ou não, ganha um badge 🔀 na lateral do card no canvas:

É o mesmo tipo de indicador visual do badge ⊘ de Execução Condicional, só que para rotas em vez de condição de execução, e a legenda completa de ícones e badges do canvas está em Agent Builder → Cards, badges e conexões.

As condições de rota são expressões JavaScript avaliadas pelo runtime no momento da execução. Toda variável do processo é substituída pelo seu valor antes da avaliação:
// Condição escrita:
Number({valor_total}) > 1000 && {status} == 'aprovado'
// Em tempo de execução, com {valor_total}='1500' e {status}='aprovado':
Number('1500') > 1000 && 'aprovado' == 'aprovado'
// → true → esta rota é seguida
Escrevendo rotas no modo manual
O builder visual (SE / +E (AND) / +OU (OR)) cobre a maioria dos casos, inclusive combinando várias condições numa única regra. O exemplo do início da página tem uma Regra 1 com três linhas: connector.status == "OK" E CNPJ_LIST.length > 0 OU connector.status != undefined. Para lógica que esse builder não expressa, clique em ✎ Manual e escreva o script diretamente:
No campo Valor do builder, digite o texto direto (aprovado) ou {variável}, sem aspas, inclusive misturando os dois (Ticket-{id}). O builder grava a sintaxe JavaScript certa por trás, aspas incluídas quando for texto. Isso vale só para o builder visual: no modo Manual abaixo, o script é JavaScript de verdade, e texto sem aspas quebra a etapa.

[{JS} true].goto(...).O script gerado segue o formato [condição].goto(destino) :: [condição].goto(destino). Cada Regra do builder visual vira um par [condição].goto(destino), e :: é só o separador entre regras: uma linha por rota, na mesma ordem em que aparecem no builder (o botão Remover some com um par inteiro; ↑/↓ reordena os pares, na mesma posição em que reordenam as regras no builder). Os detalhes de como o runtime avalia cada par estão em A função goto(), a seguir. O editor route.js só troca o builder visual por texto livre. Alguns pontos práticos desse modo:
- Digite
{para autocompletar. O editor lista todas as variáveis do processo disponíveis naquele ponto do fluxo, o mesmo atalho "{ → variáveis" usado nas condições de execução e nas condições de mapeamento. - Aninhamento de condições numa mesma regra: dentro de um único par de colchetes, combine quantas condições quiser com
&&e||, como em{connector.status} == "OK" && {CNPJ_LIST}.length > 0 || {connector.status} != undefined. Sem parênteses explícitos, vale a precedência normal do JavaScript:&&agrupa antes de||. Use parênteses ((a && b) || c) sempre que a ordem importar para o resultado. - Converter para visual tenta reconstruir o builder a partir do script manual. Funciona quando a expressão é simples o bastante para ser representada nos campos SE/E/OU; scripts mais elaborados continuam só em modo manual.
A função goto()
Seja pelo builder visual ou pelo modo manual, cada rota que você configura vira uma chamada de goto(). A função que efetivamente desvia o fluxo. O script de rota é uma sequência de pares [condição].goto(destino) separados por :::
[{status} == 'aprovado'].goto({Emitir Nota}) :: [{status} == 'rejeitado'].goto({Tratar Rejeição}) :: [{JS} true].goto(terminate())
Leitura: se {status} for 'aprovado', vá para a etapa Emitir Nota; senão, se for 'rejeitado', vá para Tratar Rejeição; senão (regra padrão), encerre o processo.
Destinos aceitos pelo goto()
| Destino | Efeito |
|---|---|
goto({Nome da Etapa}) | Salta para a etapa com esse nome, sempre entre chaves, exatamente como está no campo Nome da Etapa. |
goto(continue()) | Segue para a próxima etapa na sequência (opção Continuar do builder). |
goto(terminate()) | Encerra o processo (opção Encerrar Processo do builder). No canvas, aparece como o ponto vermelho ⏺. |
A regra padrão [{JS} true]
A última regra do script usa o prefixo {JS} com a condição true. É o catch-all: se nenhuma condição anterior for satisfeita, o goto() dela decide o destino. O builder gera essa regra a partir do campo de rota padrão; nunca deixe o script sem ela, ou o fluxo fica sem destino quando nada casa.
[condição] verdadeiro executa o seu goto() e os demais são ignorados.
Acesso a variáveis
| Sintaxe | O que acessa | Exemplo |
|---|---|---|
{variavel} |
Parâmetro de inicialização do processo ou variável definida por script | {empresa_id} == 'ACME' |
{nome_do_campo} |
Campo capturado por mapeamento (Mapeamento de Dados). O nome vem do campo Nome da linha de mapeamento, não do nome da etapa | {status_nf} == 'aprovado' |
{nome_do_campo}[0] |
Primeiro item de uma captura em lista. O [0] vem depois da chave |
{numeros}[0] != undefined |
Number({valor}). Uma lista comparada com um número é comparada pelo tamanho ({lista} == 0 equivale a {lista}.length == 0), e aceita o índice fora da chave, {lista}[0], ou o atalho {lista}[] para o primeiro item. Detalhes: Arrays e listas.
Operadores de comparação
| Operador | Significado | Exemplo |
|---|---|---|
== | Igual | {status} == 'aprovado' |
!= | Diferente | {status} != 'pendente' |
> | Maior que (use Number() para números) | Number({total}) > 1000 |
< | Menor que | Number({total}) < 500 |
>= | Maior ou igual | Number({score}) >= 70 |
<= | Menor ou igual | Number({tentativas}) <= 3 |
Operadores lógicos
| Operador | Significado | Exemplo |
|---|---|---|
&& | E lógico. Ambas as condições devem ser verdadeiras | Number({total}) > 0 && {status} == 'ok' |
|| | OU lógico. Basta uma ser verdadeira | {tipo} == 'NF-e' || {tipo} == 'CT-e' |
! | NÃO lógico. Inverte o resultado | !({status} == 'cancelado') |
// E lógico
Number({valor}) > 50000 && {status} == 'pendente'
// OU lógico
{status} == 'aprovado' || {status} == 'pago'
// Combinação
({tipo} == 'NF-e' || {tipo} == 'CT-e') && Number({valor}) > 0
Verificadores especiais
| Verificador | Verdadeiro quando | Exemplo |
|---|---|---|
exists |
A variável existe e tem valor não-vazio | {arquivo} exists |
is empty |
A variável está vazia, é null ou não existe |
{resultado} is empty |
true |
Sempre (usado como catch-all obrigatório) | true |
Métodos de string
| Método | Exemplo | Uso |
|---|---|---|
.includes() | {mensagem}.includes('erro') | Verificar se contém substring |
.startsWith() | {codigo}.startsWith('NF') | Verificar prefixo |
.endsWith() | {arquivo}.endsWith('.pdf') | Verificar sufixo/extensão |
.toLowerCase() | {status}.toLowerCase() == 'aprovado' | Comparação sem distinção de maiúsculas |
.trim() | {campo}.trim() != '' | Ignorar espaços extras |
.replace() | {valor}.replace(',', '.') == '1.5' | Normalizar formato antes de comparar |
Conversão de tipos
| Função | Exemplo | Uso |
|---|---|---|
Number() | Number({valor}) > 100 | Converter texto em número antes de comparar |
String() | String({codigo}).padStart(3, '0') == '001' | Tratar um número como texto |
JSON.parse() | JSON.parse({json_texto}).status == 'ok' | Ler um JSON guardado como texto |
Math.abs() | Math.abs(Number({diferenca})) < 0.01 | Comparar valor absoluto (tolerância) |
Math.max() | Math.max(Number({a}), Number({b})) > 0 | Usar maior valor entre dois campos |
parseInt() | parseInt({codigo}) == 42 | Ignorar parte decimal ao comparar |
Arrays e listas
Uma variável é lista quando vem de uma captura em lista (inclusive as colunas da Tabulação Automática), de um caminho com [*] numa resposta de API ou de conector, de uma variável do tipo Lista ou de uma lista gravada por script. Ela entra na condição como lista, e os métodos de lista do JavaScript funcionam direto sobre ela:
| Operação | Exemplo |
|---|---|
| Tamanho da lista | {itens}.length > 0 |
| Lista vazia | {itens} == 0 |
| Primeiro elemento | {itens}[] == 'inicio' ou {itens}[0] == 'inicio' |
| Último elemento | {itens}.at(-1) == 'fim' |
| Contém valor | {lista}.includes('aprovado') |
| Todos satisfazem | {status_list}.every(s => s == 'ok') |
| Algum satisfaz | {status_list}.some(s => s == 'erro') |
Quando cada item da lista é um registro com campos, como a lista inteira de uma resposta de API (itens[*]) ou as linhas de uma consulta de banco, o campo se lê depois do índice, ou dentro da função:
| Operação | Exemplo |
|---|---|
| Campo do primeiro registro | {pedidos}[].status == 'novo' |
| Campo de um registro pela posição | {pedidos}[1].total > 1000 |
| Algum registro atende | {pedidos}.some(p => p.status == 'novo') |
| Quantos registros atendem | {pedidos}.filter(p => p.total > 1000).length > 2 |
Armadilhas comuns
Comparar números como string
// {total} = '10', {limite} = '9'
{total} > {limite} // '10' > '9' → false! (string comparison)
Number({total}) > Number({limite}) // 10 > 9 → true
Comparar com null/undefined
{arquivo} == '' // pode ser undefined se nunca foi definida
{arquivo} is empty // trata null, undefined e '' igualmente
Lista que pode não existir
({lista} || []).length > 0
Sensibilidade a maiúsculas
{status}.toLowerCase() == 'aprovado' // funciona com 'Aprovado', 'APROVADO', etc.
