# Construtor de fluxo (chatbot) (/docs/crm/fluxos)





O **construtor de fluxo** é um chatbot visual: você desenha, num canvas, o caminho que uma conversa percorre — uma saudação, um menu de opções, uma pergunta, uma condição, uma espera — e a plataforma executa esse fluxo **automaticamente** quando uma mensagem chega, antes de qualquer atendente humano. É o mesmo recurso do editor de Fluxos no painel; esta página explica o **modelo** e como operá-lo pela API.

* **No painel:** Fluxos → (novo/editar) — editor visual com arrastar-e-soltar.
* **Na API:** [Fluxos](/docs/api/fluxos/listFlows) — o editor usa exatamente estes endpoints.

## Anatomia de um fluxo [#anatomia-de-um-fluxo]

Um **fluxo** é um cabeçalho (nome, instância, gatilho, ativo) + um conjunto de **nós** ligados por arestas. Regras:

* Um fluxo é **vinculado a uma instância** (número) — ou a nenhuma, valendo para qualquer número do Projeto.
* **Só 1 fluxo pode ficar ATIVO por instância.** Ativar um desativa os outros daquela instância automaticamente.
* O nó de &#x2A;*menor `ordem`** é o ponto de partida.
* Cada nó tem uma posição no canvas (`posicaoX`/`posicaoY`) — puramente visual — e um `conteudo` (objeto JSON) cujo formato depende do **tipo**.

### O gatilho [#o-gatilho]

Quando o fluxo dispara para uma conversa nova:

| `triggerType` | Dispara quando                                                                       |
| ------------- | ------------------------------------------------------------------------------------ |
| `any`         | **Qualquer** mensagem recebida inicia o fluxo.                                       |
| `keyword`     | Só quando o texto recebido **contém** o `triggerValue` (sem diferenciar maiúsculas). |

## Tipos de nó [#tipos-de-nó]

Cada nó tem um `tipo` e um `conteudo`. Os formatos:

### `message` — envia um texto [#message--envia-um-texto]

```json
{ "texto": "Olá {{nome}}, tudo bem? Bem-vindo à Loja X." }
```

Envia a mensagem e segue para o próximo nó (aresta padrão). Suporta [variáveis](#variáveis).

### `menu` — oferece opções numeradas [#menu--oferece-opções-numeradas]

```json
{
  "texto": "Como posso ajudar?",
  "options": [
    { "id": "opt_1", "numero": 1, "texto": "Falar com vendas", "targetNodeId": "nd_vendas" },
    { "id": "opt_2", "numero": 2, "texto": "Suporte", "targetNodeId": "nd_suporte" }
  ]
}
```

Envia o `texto` seguido das opções **numeradas automaticamente** (`1. Falar com vendas` …) e **espera a resposta**. O contato pode responder pelo **número** (`1`) ou pelo **texto** da opção. A resposta leva ao `targetNodeId` daquela opção. Resposta que não casa com nenhuma opção → o menu é **reenviado**.

### `input` — pergunta e guarda a resposta [#input--pergunta-e-guarda-a-resposta]

```json
{ "texto": "Qual o seu nome?", "variavel": "nome_cliente" }
```

Envia a pergunta, **espera a resposta** e guarda o que o contato digitar na variável indicada (aqui, `{{nome_cliente}}`), disponível nos próximos nós. Depois segue pela aresta padrão.

### `condition` — bifurca o caminho [#condition--bifurca-o-caminho]

```json
{ "variavel": "nome_cliente", "operador": "contem", "valor": "João", "onTrue": "nd_a", "onFalse": "nd_b" }
```

Avalia `variavel <operador> valor` e vai para `onTrue` ou `onFalse`. Operadores: `==` (igual), `!=` (diferente), `contem` (substring, sem diferenciar maiúsculas). Não envia mensagem — só decide o ramo.

### `delay` — espera antes de seguir [#delay--espera-antes-de-seguir]

```json
{ "segundos": 30 }
```

Pausa o fluxo pelo tempo indicado e **depois** segue. A espera é **não-bloqueante**: a sessão fica agendada e um agendador a retoma quando o tempo vence — não trava o atendimento. `0` segue na hora; o teto é **24 horas** (86400s).

### `action` — gancho de automação [#action--gancho-de-automação]

Nó reservado para automações (ex.: criar um negócio no funil). Hoje apenas **segue** para o próximo nó; é o ponto de extensão para evoluções.

### `transfer` — entrega ao humano [#transfer--entrega-ao-humano]

Encerra a parte automática e **transfere para um atendente**, seguindo a [política de roteamento](/docs/crm/equipe#roteamento-automático) do Projeto (menos ocupado, rodízio ou manual). É como o bot "passa o bastão".

### `close` — encerra a conversa [#close--encerra-a-conversa]

Finaliza o fluxo e marca a conversa como **resolvida**. Use ao fim de um autoatendimento que não precisa de humano.

## Variáveis [#variáveis]

No início de cada sessão, o fluxo já recebe dados do contato, usáveis com `{{chave}}` em qualquer `texto`:

| Variável               | Conteúdo                                           |
| ---------------------- | -------------------------------------------------- |
| `{{nome}}`             | Nome do contato (push name do WhatsApp).           |
| `{{numero}}`           | Número do contato.                                 |
| `{{numero_formatado}}` | Número do contato (formatado).                     |
| `{{mensagem_inicial}}` | O texto da primeira mensagem que disparou o fluxo. |

Nós do tipo `input` **adicionam** novas variáveis (o que o contato responder). Uma variável inexistente é substituída por vazio.

## Comportamento em tempo de execução [#comportamento-em-tempo-de-execução]

<Callout type="info">
  **O bot tem precedência sobre o roteamento humano.** Se há um fluxo ativo na
  instância, ele decide o atendimento; o roteamento automático para atendentes
  só entra quando o fluxo chega a um nó `transfer`.
</Callout>

* **Convivência com humano.** Se a conversa **já tem um atendente atribuído**, o bot **pausa** — não atropela o atendimento humano em andamento.
* **Uma sessão por conversa.** O estado (nó atual, variáveis, espera agendada) é mantido por conversa enquanto o fluxo roda.
* **Envio durável.** As mensagens do bot saem pela fila de envio confiável (com retries), igual aos demais envios da API.
* **Proteção contra laço.** Um fluxo mal montado (ciclo entre nós que não esperam resposta) é interrompido após um limite de passos, em vez de rodar para sempre.
* **Apagar o fluxo** encerra as sessões que estiverem rodando nele.

## Montando um fluxo pela API [#montando-um-fluxo-pela-api]

O editor visual faz isto nos bastidores; você pode reproduzir programaticamente:

1. **Crie o fluxo** — [`POST /v1/flows`](/docs/api/fluxos/createFlow) com `name`, `instanceId` e `triggerType`. Nasce **inativo**.
2. **Adicione os nós** — [`POST /v1/flows/{id}/nodes`](/docs/api/fluxos/createFlowNode), um por nó, com `tipo`, `conteudo`, posição e `ordem` (o menor é o início).
3. **Ligue os nós** — a aresta padrão (linear) com [`PATCH .../nodes/{nodeId}/connection`](/docs/api/fluxos/setFlowNodeConnection) (`proximoNodeId`); as saídas de um **menu** com [`PATCH .../nodes/{nodeId}/option-connection`](/docs/api/fluxos/setFlowNodeOptionConnection) (liga cada `optionId` a um nó).
4. **Ative** — [`PATCH /v1/flows/{id}`](/docs/api/fluxos/updateFlow) com `active: true`. Isso desativa os outros fluxos da mesma instância (conflito retorna `409`).

<Callout type="warn">
  Ao **ativar**, garanta que o fluxo tem um nó inicial (a menor `ordem`) e que as
  ligações levam a um nó terminal (`transfer` ou `close`) — senão a conversa
  pode ficar no bot sem saída para um humano. Teste no ambiente **sandbox** antes
  de ativar em produção.
</Callout>
