> For the complete documentation index, see [llms.txt](https://ajuda.digitalsac.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ajuda.digitalsac.io/digicrm/operacao-uso-do-sistema/campanha-waba.md).

# Campanha WABA

**Campanha WABA** envia mensagens em massa pela **WhatsApp Business API (oficial / Cloud API)**, usando **templates aprovados pela Meta**. Diferente da campanha Baileys (WhatsApp Web), o envio depende de:

* conexão do tipo **WABA Oficial** (`wabaoficial`) **conectada**;
* **template** com status **APPROVED** vinculado a essa conexão;
* preenchimento dos **campos de runtime** do template (variáveis, mídia de cabeçalho, botões, carrossel etc.);
* audiência (contatos do sistema e/ou importação CSV/XLSX).

A tela também oferece **régua de relacionamento** (etapas, janela de resposta, tags, fila, carteira, Kanban) e relatórios (PDF, CSV e consolidado).

**Caminho:** menu lateral → grupo **Campanhas** → **Campanha Waba**\
**URL:** `/campanhaswaba`\
**Contatos da campanha:** `/campanhaswaba/:campanhaId`

**Licença / Premium:** recurso **PREMIUM** (e, quando aplicável, liberação pelo plano/módulo do tenant). Sem a licença/permissão adequada, o item de menu e a rota ficam bloqueados.

**Perfis:** tipicamente **admin** / **super** (menus de campanha). Usuários não-admin só veem conexões WABA permitidas para eles.

\[\[FOTO]]

***

### O que você vê na tela (listagem)

#### Dashboard (topo)

Os cards e contadores respeitam o **filtro de mês/ano** da listagem (não o total histórico absoluto, e sim o conjunto filtrado).

| Card / bloco             | O que mostra                                                                                                                                      |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Total de Campanhas**   | Quantidade de campanhas no filtro atual                                                                                                           |
| **Campanhas Ativas**     | Status `processing` ou `scheduled`                                                                                                                |
| **Mensagens Enviadas**   | Soma do campo `sent` das campanhas filtradas                                                                                                      |
| **Taxa de Sucesso**      | `finalizadas / (finalizadas + canceladas) × 100` (0% se não houver nenhum dos dois)                                                               |
| **Campanhas por Status** | Contagens de Pendente, Processando, Finalizada, Cancelada (também existem scheduled/paused no sistema)                                            |
| **Últimos 3 Meses**      | Por mês (atual, passado, retrasado): campanhas, contatos e mensagens — com base nas datas `start` (ou `createdAt`) das campanhas **já filtradas** |

\[\[FOTO]]

#### Cabeçalho da listagem

| Elemento                       | Função                                                        |
| ------------------------------ | ------------------------------------------------------------- |
| Título **Campanhas Waba**      | Gerenciamento de Campanhas WhatsApp Business API              |
| Alternância **Tabela / Cards** | Preferência salva em `localStorage` (`campaignsWabaViewMode`) |
| **Atualizar**                  | Recarrega a lista da API                                      |
| **Adicionar**                  | Abre o modal de criação                                       |

#### Filtros

* **Mês** e **Ano** (padrão: mês e ano atuais; opção “Todos”).
* Filtram pela data de `start` (ou `createdAt`) da campanha.

#### Colunas (visão tabela)

| Coluna              | Conteúdo                                                          |
| ------------------- | ----------------------------------------------------------------- |
| #                   | ID                                                                |
| Campanha            | Nome                                                              |
| Início              | Data/hora de início (formato do tenant)                           |
| Status              | Pendente, Programada, Processando, Cancelada, Finalizada, Pausada |
| Quantidade Contatos | Contatos vinculados                                               |
| Enviadas            | Mensagens enviadas (`sent`)                                       |
| Ações               | Ver abaixo                                                        |

Na visão **Cards**: nome, ID, badge de status, data de início, contatos e enviadas, mais os mesmos botões de ação.

\[\[FOTO]]

***

### Status da campanha e ações disponíveis

| Status (código) | Label (pt-BR) | Agendar / Iniciar | Pausar | Retomar | Cancelar | Editar | Excluir        | Contatos                                 |
| --------------- | ------------- | ----------------- | ------ | ------- | -------- | ------ | -------------- | ---------------------------------------- |
| `pending`       | Pendente      | Sim               | —      | —       | —        | Sim    | Sim\*          | Sim                                      |
| `canceled`      | Cancelada     | Sim               | —      | —       | —        | Sim    | Sim\*          | Sim                                      |
| `scheduled`     | Programada    | —                 | Sim    | —       | Sim      | Não    | Não (regra UI) | Sim                                      |
| `processing`    | Processando   | —                 | Sim    | —       | Sim      | Não    | Não            | Sim                                      |
| `paused`        | Pausada       | —                 | —      | Sim     | —        | Não    | Não            | Sim                                      |
| `finished`      | Finalizada    | —                 | —      | —       | —        | Não    | Não            | Sim (leitura; import/incluir bloqueados) |

\* **Excluir (UI):** só permite se status for `pending` ou `canceled` **e** (na prática da tela) se não houver contatos vinculados quando o status não for pending/canceled — a mensagem de erro da UI: *“Só é permitido deletar campanhas que estejam pendentes ou canceladas e não possuam contatos vinculados.”* O backend também exige status `pending` ou `canceled`.

**Editar:** só `pending` ou `canceled` (frontend e backend alinhados). Após o disparo, o botão fica cinza com tooltip *“Edição bloqueada após o envio…”*.

**Agendar / Programar envio** (`IniciarCampanha`):

1. Status deve ser `pending` ou `canceled`.
2. Data de início **não pode ser anterior ao dia atual** (comparação por dia).
3. Deve haver **pelo menos 1 contato** na audiência.

Se falhar, a UI mostra erro genérico de programação/início.

**Pausar:** remove jobs da fila `SendMessageWabaCampaign` e define status `paused`.\
**Retomar:** só a partir de `paused`.\
**Cancelar:** remove jobs da fila e define status `canceled` (confirmação Sim/Não).

\[\[FOTO]]

***

### Criar / editar campanha (modal)

Botão **Adicionar** (criação) ou ícone de editar (apenas pendente/cancelada).

**Aviso no cabeçalho do modal:** *“As mensagens sempre serão enviadas em horário comercial e dias úteis.”*\
Na prática o envio respeita a **janela de horário** configurada na própria campanha (`startTime` / `endTime`), calculada no serviço de start (timezone do tenant).

\[\[FOTO]]

#### Campos do formulário (obrigatórios e opcionais)

| Campo                             | Obrigatório   | Padrão                | Descrição                                                                                                                                                                                                                                                                                                                                                                              |
| --------------------------------- | ------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Nome da Campanha**              | Sim           | —                     | Nome interno. No backend, ao **criar**, o sistema acrescenta um sufixo com data/hora (`Nome-YYYYMMDDHHMM`) para evitar conflito de nome único.                                                                                                                                                                                                                                         |
| **Data/Hora início**              | Sim           | —                     | `datetime-local`. Não pode ser **inferior ao dia atual**. É o momento a partir do qual a fila começa a programar os envios (ajustado à janela horária).                                                                                                                                                                                                                                |
| **Enviar por**                    | Sim           | —                     | Seleção da conexão **WhatsApp Business API**. Só entram conexões `type === "wabaoficial"`, não deletadas e com `status === "CONNECTED"`. Admin/Master vê todas; outros perfis só as de `allowedConnections` (ou todas se a lista vier vazia). Cada opção mostra badge Conectado/Desconectado e o texto “WhatsApp Business API”. Se não houver conexão: *“Nenhuma conexão disponível”*. |
| **Delay**                         | Sim (marcado) | `20`                  | Intervalo entre mensagens, em **segundos**. Controla o espaçamento dos jobs na fila.                                                                                                                                                                                                                                                                                                   |
| **Horário de Início**             | Não           | `08:00`               | Início da janela diária de envio (hint: ex. 08:00).                                                                                                                                                                                                                                                                                                                                    |
| **Horário de Fim**                | Não           | `20:00`               | Fim da janela diária de envio (hint: ex. 20:00). Envios fora da janela são reagendados para o próximo horário válido.                                                                                                                                                                                                                                                                  |
| **Template**                      | Sim           | —                     | Lista **somente templates APPROVED**. Ao escolher a conexão WABA, a lista é **filtrada** pelos templates daquela `whatsappId`. Se o template atual não pertencer à conexão, o campo é limpo.                                                                                                                                                                                           |
| **Campos de runtime do template** | Condicional   | —                     | Aparecem quando há template selecionado (componente `TemplateRuntimeInputEditor`). Ver seção abaixo.                                                                                                                                                                                                                                                                                   |
| **Pré-visualização**              | —             | —                     | HTML do template com placeholders preenchidos (quando disponível).                                                                                                                                                                                                                                                                                                                     |
| **Configurações avançadas**       | Não           | Desligadas / defaults | Régua, resposta, Kanban etc. Ver seção dedicada.                                                                                                                                                                                                                                                                                                                                       |

Botões: **Cancelar** | **Salvar**.

Validações ao salvar:

* Nome, data/hora, conexão e template preenchidos; senão: *“Verifique se todas os campos obrigatórios estão preenchidos”*.
* Se houver **campos de runtime pendentes**, o save é bloqueado com aviso listando os campos.

Ao criar: notificação *“Campanha criada!”*. Ao editar: *“Campanha editada!”*.

\[\[FOTO]]

#### Campos de runtime do template (variáveis e mídia)

Depois de escolher o template, o editor monta dinamicamente o que a Meta exige naquele modelo. Podem aparecer:

| Tipo de campo                       | Quando aparece                  | O que preencher                                                                         |
| ----------------------------------- | ------------------------------- | --------------------------------------------------------------------------------------- |
| **Parâmetros de cabeçalho (texto)** | Header TEXT com variáveis       | Valores posicionais (`{{1}}`…) ou nomeados                                              |
| **Parâmetros de corpo**             | Body com variáveis              | Idem (posicional ou nomeado)                                                            |
| **Mídia de cabeçalho**              | Header IMAGE / VIDEO / DOCUMENT | Tipo, **link** da mídia e/ou **ID** de mídia na Meta; pode usar galeria conforme o tipo |
| **Localização**                     | Header LOCATION                 | Latitude, longitude, nome, endereço                                                     |
| **Flow**                            | Botão/fluxo WhatsApp Flow       | Token do flow (`flowToken`) e parâmetros relacionados                                   |
| **Catálogo**                        | Template de catálogo            | IDs locais de catálogo/produto e seções                                                 |
| **Botões**                          | Template com botões dinâmicos   | Textos / parâmetros de botão (ex.: URL com variável)                                    |
| **Carrossel**                       | Template CAROUSEL               | Por card: mídia (link/id) e parâmetros de corpo/botões do card                          |

Ferramentas auxiliares nos campos de texto (`ParamFieldTools`) permitem inserir variáveis / contexto de IA (contexto i18n: *“Variável de template WABA para campanha de WhatsApp”*).

**Contador de caracteres e bloqueio (limites da Meta):** cada seção mostra o tamanho do texto **final** (texto fixo do template + valores digitados) contra o limite da Meta — **cabeçalho 60**, **corpo 1024**. O contador amarela perto do limite e o campo para de aceitar o que não cabe; o salvar fica bloqueado enquanto houver estouro. Textos colados com quebras de linha/espaços múltiplos são normalizados automaticamente (a Meta rejeita).

> Variáveis de sistema (`{{nome}}`, `{{primeiroNome}}`…) só viram texto na hora do disparo, por contato. Se o valor real estourar o limite, o **servidor bloqueia antes de enviar** e o contato aparece como *Rejeitado* com o motivo — sem gastar disparo.

**Vídeo/imagem/documento no cabeçalho:** a mídia é **enviada previamente para a Meta** e o disparo usa o identificador dela (não um link) — isso garante que o vídeo chegue reproduzível no destinatário. O upload é feito uma única vez por template/canal (com cache de 24h), mesmo em campanhas grandes.

**Botão “?” — campanha rastreável:** ao lado do seletor de template há um guia rápido de como criar campanhas cuja resposta é atribuível (resumo: prefira templates com **botões** de resposta rápida; veja a seção *Rastreio de origem da resposta*).

Banner laranja se faltarem campos: **Campos de runtime pendentes:** lista dos nomes.

O payload salvo inclui `runtimeInput` (e aliases de compatibilidade: `templateRuntimeInput`, `templateVariables`, `campaignRuntimeState`). O backend normaliza o runtime com base no `templateId`.

\[\[FOTO]]

#### Configurações avançadas (régua / automação / Kanban)

Bloco expansível: **Configurações avançadas (régua, resposta, Kanban)**.

**Interruptor mestre**

| Estado        | Efeito                                                                             |
| ------------- | ---------------------------------------------------------------------------------- |
| **Desligado** | Campanha simples: campos abaixo desativados; automações não são aplicadas.         |
| **Ligado**    | Tag, fila, usuário, carteira, Kanban etc. **serão aplicados** conforme preenchido. |

**Validade da campanha**

| Campo                                      | Padrão | Intervalo | Função                                                             |
| ------------------------------------------ | ------ | --------- | ------------------------------------------------------------------ |
| **Janela para considerar resposta (dias)** | 7      | 1–365     | Respostas após esse prazo **não** disparam tag/fila/usuário/Kanban |
| **Fechar sem resposta após (dias)**        | 15     | 1–365     | Marca a jornada do contato como `closed_no_reply`                  |

**Importação de audiência**

| Campo                                   | Padrão | Função                                                                                  |
| --------------------------------------- | ------ | --------------------------------------------------------------------------------------- |
| **Salvar contato ao importar CSV/XLSX** | Não    | Se desligado, números do CSV ficam só no item da campanha (não poluem Contatos)         |
| **Carteira (vendedor) ao enviar**       | —      | Aplica usuário como carteira do contato **sem sobrescrever** carteira de outro vendedor |

**Automação na resposta**

| Campo                                    | Padrão | Função                                                     |
| ---------------------------------------- | ------ | ---------------------------------------------------------- |
| **Criar contato quando responder (CSV)** | Sim    | Promove número CSV → Contact ao responder dentro da janela |
| **Tag aplicada na resposta**             | —      | Tag no Contact; botão “+” cria etiqueta nova               |
| **Fila atribuída ao ticket**             | —      | Move o ticket para a fila ao responder                     |
| **Usuário atribuído ao ticket**          | —      | Responsável do ticket ao responder                         |

**Etapas da régua**

| Campo                                        | Padrão | Função                                                    |
| -------------------------------------------- | ------ | --------------------------------------------------------- |
| **Etapas máximas**                           | 1      | Quantidade total de mensagens da régua (1–10)             |
| **Permitir reenviar para não respondedores** | Sim    | Habilita o botão de avançar etapa para quem não respondeu |

**Encerramento sem resposta**

| Campo                                       | Padrão | Função                                               |
| ------------------------------------------- | ------ | ---------------------------------------------------- |
| **Tag aplicada no encerramento**            | —      | Tag no Contact quando fecha sem resposta             |
| **Criar ticket no fechamento sem resposta** | Não    | Necessário para mover lead ao Kanban no encerramento |

**Integração com Kanban**

| Campo                                | Função                                                                                        |
| ------------------------------------ | --------------------------------------------------------------------------------------------- |
| **Coluna do Kanban na resposta**     | Move o card quando o cliente responde                                                         |
| **Coluna do Kanban no encerramento** | Move não respondedores (precisa de ticket; aviso se “criar ticket no fechamento” estiver off) |

\[\[FOTO]]

***

### Contatos / audiência

Acesse pelo ícone **Lista de Contatos da Campanha** (ou rota `/campanhaswaba/:id`).

#### Cabeçalho

Mostra nome da campanha, data de início e status. Botão **Listar Campanhas** volta para a listagem.

\[\[FOTO]]

#### Métricas da audiência

Painel com:

* Total, Enviados, Lidos, Respondidos, Sem resposta, Fora da janela, Conflitos de carteira
* (quando > 0) Entraram no Kanban por resposta / por fechamento

Botão de atualizar chama `/campaignswaba/:id/audience-metrics`.

#### Tabela de contatos da campanha

| Coluna        | Conteúdo                                                                                                                        |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| Foto          | Avatar do contato                                                                                                               |
| Nome          | Nome                                                                                                                            |
| WhatsApp      | Número; ou “Sem número • BSUID da conexão selecionada” / “Sem número”                                                           |
| Origem        | Contato / CSV / XLSX / Manual (chip) + ícone de aviso se houver `warningMessage`                                                |
| Etapa         | Etapa atual da régua                                                                                                            |
| Jornada       | Pendente, Enviando, Enviado, Entregue, Lido, Respondeu, Sem resposta, Falhou, **Rejeitado pela Meta** (+ chip “Fora da janela”) |
| Status (ACK)  | Envio Pendente, Entrega Pendente, Recebida, Lida, Reproduzido, Error                                                            |
| Respondido em | Data/hora da resposta                                                                                                           |
| Carteira      | Aplicada / Mesma carteira / Conflito / Sem contato                                                                              |
| Kanban        | Ícones se entrou por resposta e/ou fechamento                                                                                   |
| Etiquetas     | Tags do contato                                                                                                                 |
| Estado        | Região (`regionName`) ou inferência por DDD (EX.: BR)                                                                           |
| Ações         | Excluir contato (oculto se campanha `finished`/`completed`)                                                                     |

#### Ações da audiência (por status da campanha)

| Ação                              | Quando aparece                               | O que faz                                                                               |
| --------------------------------- | -------------------------------------------- | --------------------------------------------------------------------------------------- |
| **Atualizar**                     | Sempre                                       | Recarrega contatos + métricas                                                           |
| **Reenviar p/ não respondedores** | Status `finished`, `completed` ou `canceled` | POST `resend-non-responders` — reagenda próxima etapa para itens sem resposta na janela |
| **Relatório consolidado**         | Sempre                                       | Abre modal com KPIs, taxas, breakdown por origem/etapa, filtros e export CSV            |
| **Limpar Campanha**               | `pending` ou `canceled`                      | Remove **todos** os contatos (confirmação irreversível)                                 |
| **Importar CSV/XLSX**             | Não `finished`/`completed`                   | Modal de importação de audiência                                                        |
| **Incluir Contatos**              | Não `finished`/`completed`                   | Modal de seleção a partir da base de contatos                                           |

\[\[FOTO]]

#### Incluir contatos (da base)

Modal largo com:

1. **Filtros** (expansíveis — “Filtros (Data criação do contato)”):
   * Data início / data final (criação do contato; padrão \~10 anos atrás até hoje)
   * **País** (ISO2; padrão BR)
   * **Estado/Região** (UF, estado US, província CA, oblast RU etc., conforme país)
   * **Etiqueta(s)**
   * **Carteira** (usuários)
   * Busca por **nome ou telefone** (debounce \~800 ms)
   * Botão **Gerar** aplica os filtros
2. Filtro por **letra** (A–Z / Todas)
3. Paginação (5–100 por página) e seleção múltipla
4. Contexto de canal: busca com `channelContext: 'wabaoficial'` e, se a campanha tiver `whatsappId`, envia `wabaWhatsappId` (importante para identidades BSUID)

**Adicionar** envia os selecionados para `POST /campaignswaba/contacts/:id/`.

\[\[FOTO]]

#### Importar CSV / XLSX

* Arquivos: `.csv`, `.xlsx`, `.xls`
* Coluna esperada: **número** (e opcionalmente **nome**)
* Toggle **Salvar como Contato no sistema** (herda o default da campanha `saveContactOnImport`)
* Pré-visualização das primeiras linhas (só CSV)
* Resultado: total lidos, importados, inválidos, duplicados, contatos criados, vínculos, estatísticas de carteira e avisos

Endpoint: `POST /campaignswaba/contacts/:id/import` (multipart).

\[\[FOTO]]

***

### Consentimento de marketing (opt-in / opt-out)

O bloco **Configurações avançadas** também traz duas seções próprias de consentimento (fora do interruptor mestre, para não ficarem desligadas junto com o resto):

* **Opt-out:** toggle **Respeitar lista Não perturbe** (padrão ligado, exclui contatos com opt-out ativo do disparo) + palavras de opt-out próprias da campanha (chips; vazio = usa o padrão do tenant).
* **Opt-in:** toggle **Detectar aceite de marketing** (padrão ligado) + palavras próprias + toggle **Modo rigoroso** (enviar só para quem tem opt-in ativo).

Ao programar o envio, se algum desses toggles estiver ativo, a tela mostra um aviso *“N contato(s) serão excluídos…”* antes de confirmar o início.

Detalhes completos (detecção automática, badge no contato, exportação de evidência, guard no envio avulso de template MARKETING) na página **Consentimento de marketing**.

\[\[FOTO]]

***

### Rastreio de origem da resposta

Quando o contato responde a uma campanha, o sistema identifica **de qual campanha** a resposta veio e mostra isso ao atendente.

#### Como a atribuição funciona

| Como o contato respondeu                        | Atribuição                                                                                                              |
| ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| Tocou num **botão** do template                 | **Exata** — o WhatsApp devolve a referência da mensagem original; vale até fora da janela                               |
| Respondeu **citando** a mensagem (reply nativo) | **Exata** — mesma referência                                                                                            |
| Digitou uma **mensagem solta**                  | **Por janela** — atribui à última campanha recebida dentro do prazo *“Responder em até (dias)”* configurado na campanha |

> Por isso o guia de campanha rastreável recomenda templates com **botões**: toque em botão = atribuição cravada.

#### O que o atendente vê no ticket

* A **mensagem original do template** aparece no histórico, acima da resposta do cliente (com o texto real, variáveis substituídas), e a resposta chega **citando** o template.
* A bolha da resposta ganha o selo **📣 com o nome da campanha**.
* O **card do ticket** na lista de atendimento mostra um chip com o nome da campanha.

As automações de resposta (tag, fila, usuário, Kanban) continuam regidas pela janela e pelo estado do item — resposta fora da janela mostra a origem, mas não dispara automações.

***

### Relatórios

#### Estatísticas de Campanhas WABA (módulo Relatórios)

**Caminho:** menu lateral → Relatórios → **Estatísticas de Campanhas WABA**

Visão consolidada de **todas** as campanhas do período (filtro por data de início): por campanha — enviados, entregues, lidos, **respondidos**, falhas, fora da janela e as taxas de entrega/leitura/resposta — com linha de totais, impressão em paisagem e exportação Excel. É onde se mede a **conversão real** de cada campanha.

#### PDF (listagem)

Ícone PDF em cada campanha:

1. Chama `GET /campaignswaba/report/:id/`
2. Gera PDF no browser (`generateCampaignWabaPdf`) com logo do tenant
3. Nome do arquivo: `relatorio-campanha-waba-{id}-{ddMMyyyy-HHmm}.pdf`

Conteúdo típico:

* Informações: nome, ID, status, template, início, fim, duração, janela de envio, delay, velocidade média (msg/hora)
* Resumo: total de contatos, enviados, pendentes, falhas
* Detalhamento por contato: índice, nome, número, status da jornada, data de envio

#### CSV (listagem)

Mesma API de relatório; arquivo CSV (separador `;`, BOM UTF-8) com o resumo + tabela de contatos.\
Nome: `relatorio-campanha-waba-{id}-{ddMMyyyy-HHmm}.csv`.

#### Relatório consolidado (tela de contatos)

Modal com:

* Visão geral (audiência, enviados, entregues, lidos, respondidos, encerrados s/ resposta)
* Indicadores operacionais (fora da janela, conflitos de carteira, contatos criados ao responder, Kanban, falhas)
* Taxas (entrega, leitura, resposta, sem resposta)
* Breakdown por origem e por etapa
* Filtros (etapa, respondeu/não respondeu, fora da janela, conflito de carteira, origem CSV/contato, Kanban…)
* Lista de itens e **Exportar CSV**

Endpoint: `GET /campaignswaba/:id/consolidated-report`.

\[\[FOTO]]

***

### Fluxo operacional recomendado

1. Ter conexão **WABA Oficial** conectada e templates **APPROVED** (sincronizados da Meta).
2. **Adicionar** campanha → preencher nome, data/hora, conexão, delay, janela horária, template e runtime.
3. (Opcional) Ativar **configurações avançadas** da régua.
4. **Salvar** (status inicial: `pending`).
5. Ir em **Contatos** → incluir da base e/ou importar CSV/XLSX.
6. Voltar à listagem → **Programar envio** (vira `scheduled` / depois `processing`).
7. Acompanhar métricas, pausar/retomar/cancelar conforme necessário.
8. Ao final, baixar PDF/CSV ou abrir relatório consolidado; se houver régua, usar **Reenviar p/ não respondedores**.

\[\[FOTO]]

***

### Regras Meta / templates

* Só entram templates com status **APPROVED**. Templates em revisão, rejeitados ou pausados **não** aparecem no select.
* O template deve pertencer à **mesma conexão WABA** (`whatsappId`) escolhida em “Enviar por”.
* Variáveis e mídias do template precisam estar preenchidas no runtime; a Meta rejeita envios incompletos.
* Campanhas WABA usam a API oficial: políticas de categoria (utility/marketing/authentication), limites de qualidade e janela de 24h da Meta continuam valendo no lado Meta — o sistema envia o template aprovado.
* Header de mídia: link público acessível ou ID de mídia já hospedado na Meta.
* Carrossel e catálogo exigem o preenchimento de todos os cards/seções obrigatórios.
* Conexão precisa estar **CONNECTED**; se cair, novos envios falham até reconectar.
* **Falhou × Rejeitado pela Meta**: *Falhou* é erro transitório (instabilidade, limite de envio) — o sistema tenta de novo algumas vezes com espera crescente. **Rejeitado pela Meta** é erro permanente (template com variáveis erradas, texto acima do limite, template pausado, número sem WhatsApp, token expirado) — **não retenta** e grava o motivo em português no contato. Corrija a causa e reative.
* **Retomada automática**: ao **reconectar o canal** (ex.: token novo salvo na conexão), os contatos rejeitados/falhados que nunca foram enviados voltam para a fila sozinhos, respeitando janela de horário e intervalo da campanha. Campanha **pausada** pelo usuário não é retomada.
* A UI reforça que o envio ocorre em **horário configurado** (e mensagem de “dias úteis / horário comercial” no modal); ajuste `startTime`/`endTime` e o delay para caber nos limites de throughput da conta WABA.

\[\[FOTO]]

***

### Matriz rápida: botões da listagem

| Ícone / ação         | Tooltip                       | Condição                               |
| -------------------- | ----------------------------- | -------------------------------------- |
| Contatos             | Lista de Contatos da Campanha | Sempre                                 |
| Relógio (calendário) | Programar Envio               | `pending` ou `canceled`                |
| Cancelar (múltiplo)  | Cancelar Campanha             | `scheduled` ou `processing`            |
| Pausar               | Pausar Campanha               | `scheduled` ou `processing`            |
| Play                 | Retomar Campanha              | `paused`                               |
| Editar               | Editar / bloqueado            | Habilitado só `pending`/`canceled`     |
| PDF                  | Relatório PDF                 | Sempre                                 |
| CSV                  | Relatório CSV                 | Sempre                                 |
| Lixeira              | Excluir Campanha              | Confirmação; regras de status/contatos |

\[\[FOTO]]

***

### Mensagens e erros comuns

| Situação                        | Mensagem / comportamento                                               |
| ------------------------------- | ---------------------------------------------------------------------- |
| Sem licença Premium / módulo    | Menu/rota bloqueados                                                   |
| Sem conexão WABA conectada      | Select vazio: “Nenhuma conexão disponível”                             |
| Campos obrigatórios vazios      | “Verifique se todas os campos obrigatórios estão preenchidos”          |
| Runtime incompleto              | “Campos de runtime pendentes: …”                                       |
| Data de início no passado (dia) | “Não pode ser inferior ao dia atual” / erro ao programar               |
| Programar sem contatos          | Erro ao programar campanha                                             |
| Editar campanha já disparada    | “Só é permitido editar campanhas que estejam pendentes ou canceladas.” |
| Excluir com regra inválida      | “Só é permitido deletar… e não possuam contatos vinculados.”           |
| Pausar status inválido          | “Apenas campanhas programadas ou em processamento podem ser pausadas”  |
| Retomar status inválido         | “Apenas campanhas pausadas podem ser retomadas”                        |
| Falha ao listar                 | “Erro ao listar campanhas” (ou equivalente)                            |
| Falha ao criar/editar           | “Algum problema ao criar campanha”                                     |
| Falha PDF/CSV                   | “Erro ao gerar relatório” / “Erro ao gerar relatório em CSV”           |
| Reenvio sem elegíveis           | “Nenhum item elegível para reenvio.”                                   |
| Importação vazia                | “Nenhum contato novo importado.”                                       |
| Lista vazia                     | “Nenhum dado”                                                          |

Erros de API do backend (exemplos): `ERR_NO_CAMPAIGNWABA_FOUND`, `ERR_NO_UPDATE_CAMPAIGNWABA_NOT_IN_CANCELED_PENDING`, `ERROR_CAMPAIGNWABA_NOT_EXISTS`, `ERROR_CAMPAIGNWABA_NOT_EXISTS_OR_FINISHED`.

***

### Dicas de uso

* Prefira delay ≥ 20 s (padrão) e janela horária alinhada ao expediente da operação e aos limites da conta Meta.
* Confira o **preview** do template antes de salvar.
* Para marketing, valide na Meta o template e a qualidade do número antes de grandes audiências.
* Use importação CSV **sem** salvar contato se a lista for descartável; ligue “criar contato ao responder” para só persistir quem engajar.
* Ative configurações avançadas só quando for usar tag/fila/Kanban — campanha simples é mais previsível.
* Filtre a listagem por mês/ano para o dashboard refletir o período que importa.
* Após `finished`, use o relatório consolidado e o reenvio a não respondedores antes de abrir outra campanha.
* Usuários não-admin: garanta permissão de conexão WABA (`allowedConnections`), senão o select pode parecer incompleto.

\[\[FOTO]]

***

### Referência técnica (código)

| Camada                                     | Caminho                                                                        |
| ------------------------------------------ | ------------------------------------------------------------------------------ |
| Listagem                                   | `frontend/src/pages/campanhasWaba/Index.vue`                                   |
| Modal criar/editar                         | `frontend/src/pages/campanhasWaba/ModalCampanha.vue`                           |
| Audiência                                  | `frontend/src/pages/campanhasWaba/ContatosCampanhaWaba.vue`                    |
| Runtime template                           | `frontend/src/components/waba/TemplateRuntimeInputEditor.vue`                  |
| Avançado / import / métricas / consolidado | `frontend/src/components/campaign/*`                                           |
| Service HTTP                               | `frontend/src/service/campanhasWaba.js`                                        |
| i18n pt-BR                                 | `frontend/src/locales/pt-BR.json` → `campaignsWaba.*` e `campaigns.advanced.*` |
| Rotas FE                                   | `campanhaswaba`, `contatos-campanha-waba`                                      |
| Rotas API                                  | `backend/src/routes/campaignWabaRoutes.ts`, `campaignWabaContactsRoutes.ts`    |
| Services BE                                | `backend/src/services/CampaignWabaServices/*`                                  |
| Fila de envio                              | BullMQ `SendMessageWabaCampaign`                                               |

#### Endpoints principais

| Método         | Path                                       |
| -------------- | ------------------------------------------ |
| GET/POST       | `/campaignswaba`                           |
| GET/PUT/DELETE | `/campaignswaba/:id`                       |
| POST           | `/campaignswaba/start/:id`                 |
| POST           | `/campaignswaba/cancel/:id`                |
| POST           | `/campaignswaba/pause/:id`                 |
| POST           | `/campaignswaba/resume/:id`                |
| GET            | `/campaignswaba/report/:id`                |
| GET            | `/campaignswaba/:id/audience-metrics`      |
| GET            | `/campaignswaba/:id/consolidated-report`   |
| POST           | `/campaignswaba/:id/resend-non-responders` |
| GET/POST       | `/campaignswaba/contacts/:id`              |
| POST           | `/campaignswaba/contacts/:id/import`       |
| DELETE         | `/campaignswaba/contacts/:id/:contactId`   |
| DELETE         | `/campaignswaba/deleteall/contacts/:id`    |
