This work already existed uncommitted in the main working tree (not authored by this branch) and is required as a runtime dependency for the campaign outreach port (zpro-client, templates, outreach routes/UI). Copied in as-is, untouched, so this feature branch has a working baseline; the original uncommitted state in the main checkout is left exactly as it was.
6.9 KiB
Automação de envio WhatsApp (Z-PRO)
Manda automaticamente a primeira mensagem de WhatsApp pro produto/serviço recomendado de cada lead, usando um template por produto, e registra tudo (quem recebeu, qual produto, quando) pra nunca mandar a mesma coisa duas vezes pro mesmo lead.
Como funciona
- Roda sozinha, dentro do próprio servidor, a cada 20 minutos, enquanto o app estiver ligado — não depende de Agendador de Tarefas do Windows nem de cron. Isso é de propósito: o projeto hoje roda local, mas vai ser migrado pra um container Docker no Proxmox da empresa, e um agendador do sistema operacional teria que ser reconfigurado nesse dia. O timer interno funciona idêntico nos dois ambientes.
- Só considera leads ainda não exportados (
exported_atvazio). Assim que um lead vira oportunidade manual no Z-PRO (exportação normal da tela de Tratamento), a automação para de mandar mensagem pra ele — quem assumiu o lead foi um vendedor, não o robô. - Cada lead tem uma lista de produtos recomendados por nicho (ex.: ERP 5⭐,
G-Delivery 3⭐). Hoje a automação só tenta o produto principal (o de
maior estrela), uma única vez por lead. Existe uma segunda etapa pronta
(mas desligada) pra tentar o próximo produto da lista se não houver
resposta depois de alguns dias — ver
outreach.tentarProximoProdutoabaixo. - Manda uma mensagem por número, com controle nosso de quem já recebeu o
quê — não pelo
bulkSendMessageWithVariableusado na exportação manual em massa, que depende de um CSV com substituição posicional de variável. Cada produto tem um canal próprio (ver seção abaixo). - Depois de mandar, aplica duas tags no contato do Z-PRO:
GTI P1/GTI P2/GTI P3/GTI P4(prioridade do lead) eGTI Oferta: <produto>(o que foi ofertado) — pra quem for atender depois já ver esse contexto direto na conversa.
Canal oficial x não-oficial
Cada produto/template tem um seletor de canal em Configurações:
-
Não-oficial (texto livre) — usa
bulkIndividual, funciona numa conexão QR Code/Baileys do Z-PRO. Manda o texto do template com{empresa}/{cidade}/{segmento}substituídos. É o padrão, e o risco aqui é o de sempre com WhatsApp não-oficial: possibilidade de bloqueio do número por comportamento automatizado (por isso o limite diário e o intervalo aleatório entre envios). -
Oficial (Meta, template aprovado) — usa a API oficial do WhatsApp (Cloud API/WABA) via Z-PRO. Aqui não dá pra mandar texto livre: o WhatsApp só permite iniciar uma conversa com um template pré-aprovado pelo Meta Business Manager (fora da janela de 24h de uma conversa já iniciada pelo cliente). Por isso o campo vira "Nome do template aprovado" (tem que ser exatamente o nome cadastrado no Meta) + "Idioma" (ex.:
pt_BR).A aprovação do template em si é feita fora deste app — no Meta Business Manager (ou no painel do Z-PRO, se ele tiver essa tela) — o Z-PRO só expõe o envio usando um template que já existe, não a criação. Cadastre e espere aprovar lá antes de configurar o nome aqui.
Limitação atual: o envio oficial aqui é só nome+idioma, sem variáveis dentro do corpo do template aprovado (a API do Z-PRO tem endpoints
templateBody/templateMarketingBodyque parecem aceitar variáveis, mas o formato exato não está documentado na collection — se for necessário, precisa testar contra a instância real antes de automatizar).
Configurar pela primeira vez
-
Credenciais do Z-PRO: no painel do Z-PRO, vá em Admin > API e gere um token (Base URL, API ID, Token e WhatsApp ID). Na tela, abra ⚙️ Configurações > Credenciais Z-PRO (WhatsApp), preencha os 4 campos e clique em Testar conexão (salva e faz uma chamada real e barata pra confirmar que as credenciais estão certas, sem mandar nenhuma mensagem). Sem essas 4 credenciais a automação não manda nada, mesmo ligada.
Alternativa pra quem prefere não guardar o token no banco local (ex.: em produção no Docker/Proxmox, gerenciando segredo por variável de ambiente): deixe os 4 campos da tela em branco e defina
ZPRO_BASE_URL/ZPRO_API_ID/ZPRO_BEARER_TOKEN/ZPRO_WHATSAPP_IDno.env— a tela vazia cai automaticamente pro.env. Se a tela tiver algum valor preenchido, ele tem prioridade sobre o.env. -
Na mesma tela, em Automação de envio (WhatsApp): revise o texto de cada template (um por produto —
{empresa},{cidade}e{segmento}são substituídos automaticamente), ajuste o limite por dia se quiser, e marque Ativada. Salve.
Antes de ativar, vale mandar um teste manual (próxima seção) pro seu próprio WhatsApp.
Configurações (settings, chave → o que faz)
| Chave | Padrão | O que faz |
|---|---|---|
outreach.ativo |
false |
Interruptor geral. Começa desligado de propósito. |
outreach.mensagensPorDia |
10 |
Máximo de envios automáticos por dia (soma de todos os produtos). |
outreach.diasEntreProdutos |
5 |
Dias de espera antes de tentar o próximo produto (só usado se a cascata estiver ligada). |
outreach.tentarProximoProduto |
false |
Liga a cascata: quando false, só tenta o produto principal uma vez. |
outreach.horaInicio / outreach.horaFim |
08:00 / 18:00 |
Só manda mensagem dentro desse horário. |
Tudo isso é editável pela tela de Configurações (os dois primeiros) ou
diretamente via PUT /api/settings (todos).
Disparo manual (fora do ciclo automático)
Pra testar ou forçar um lote sem esperar o próximo ciclo de 20 min:
npm run outreach
Respeita as mesmas regras do ciclo automático (outreach.ativo, horário
comercial, limite diário) — não manda nada que a tela não mostraria.
Enviar pra um número específico
Em Configurações > Enviar mensagem manual: digite o número (com DDI+DDD,
ex.: 5511999999999), escolha o canal (texto livre ou template oficial já
aprovado) e clique em Enviar. Não depende de lead cadastrado nem de produto.
No canal Não-oficial (texto livre), o app usa createTicket para criar uma
conversa visível no painel do Z-PRO. O ticket usa o canal informado em
WhatsApp ID e o usuário de Responsável nas configurações.
No canal Oficial, o app usa o endpoint de template aprovado (template) e
também espera um ticketId na resposta.
Toda tentativa fica registrada no mesmo histórico dos envios automáticos (marcado como origem "manual") e conta pro limite diário, já que o risco de bloqueio é do número de WhatsApp usado, não de quem disparou a mensagem.
Onde fica o histórico
Toda tentativa de envio (sucesso ou erro) vira uma linha na tabela
outreach_sends (lead, produto, mensagem exata mandada, status, quando).
Um resumo do dia (enviados hoje, por produto, últimos 20 envios) fica
disponível em GET /api/outreach/status.