Dinastia · Material do aluno

Construa seu próprio botconversa com o Claude.

A Régua: seu WhatsApp no automático, sem pagar SaaS todo mês.

4 fluxos de mensagem 3 conexões pra plugar Z-API + Supabase + Hotmart + Vercel
01 · O Conceito

Pare de alugar. Seja dono da máquina.

Todo mês você paga uma mensalidade pra um SaaS mandar mensagem no seu WhatsApp. Você é o operador de uma ferramenta que não é sua. A Régua vira o jogo: você constrói a máquina uma vez, ela roda no seu servidor, e a mensalidade some.

AlugandoR$ 97 a R$ 500 todo mês, pra sempre
Alugandoseus contatos moram no banco de outro
Alugandocopy travada no que a ferramenta deixa
Vocêhospeda na Vercel de graça, roda 24h
Vocêé dono do banco e dos telefones
Vocêo Claude escreve a copy do seu jeito

O motor é sempre o mesmo: um gatilho entra, o contato cai numa fila de mensagens agendadas, e um robô que roda a cada minuto dispara na hora certa. Muda só a copy e o momento de disparo. Com essa mesma base você liga 4 fluxos:

Fluxo 01
Gatilho: formulário / lead novo

Aquecer lead

Sequência de mensagens matrícula no curso presencial
Fluxo 02
Gatilho: compra aprovada (Hotmart)

Boas-vindas

Pós-compra manda o link do grupo de alunos
Fluxo 03
Gatilho: X dias após a compra

Upsell

Espera X dias oferta do próximo produto
Fluxo 04
Gatilho: Pix gerado e não pago

Carrinho abandonado

Régua de recuperação traz a venda de volta
02 · A Arquitetura

O motor por baixo do capô.

Cinco peças conversando. Você não precisa entender o código de cor, mas entender o desenho ajuda a mandar bem no Prompt Mestre e a caçar erro quando trava.

1

Gatilho

Um formulário no seu site ou o webhook da Hotmart avisa: "entrou um lead" ou "gerou um Pix". É o pontapé.

2

Supabase — banco e fila

Guarda os contatos e cria a fila de mensagens agendadas (cada mensagem já nasce com a hora certa pra sair).

3

Cron da Vercel — a cada minuto

Um robô acorda de minuto em minuto, olha a fila e pega só as mensagens que já venceram (send_at <= agora).

4

Z-API — a ponte do WhatsApp

Recebe o texto pronto e manda de verdade pelo seu número, via send-text. É o que conecta seu WhatsApp na máquina.

5

WhatsApp do lead

A mensagem chega no celular da pessoa como se você tivesse digitado. A fila marca sent e segue pra próxima.

o coração anti-duplicado (api/dispatch.js)
// pega as vencidas, faz um "claim" otimista pra nunca enviar 2x
const { data: due } = await supabase
  .from('mensagens')
  .select('*, contatos!inner(*)')
  .eq('status', 'pending')
  .lte('send_at', new Date().toISOString())
  .limit(50);

for (const m of due) {
  // só quem conseguir virar 'sending' envia. corrida resolvida.
  const { data: claimed } = await supabase.from('mensagens')
    .update({ status: 'sending' })
    .eq('id', m.id).eq('status', 'pending')
    .select('id').maybeSingle();
  if (!claimed) continue;
  await sendWhatsApp(m.contatos.telefone, buildMessage(m));
}
03 · As 3 Conexões

Plugue as três chaves.

A máquina só precisa de três contas conectadas. Faça uma por vez, copie os valores pras variáveis de ambiente (envs) na Vercel, e pronto.

A

Z-API

a ponte com o seu WhatsApp
  1. Entre em z-api.io, crie uma conta e clique em Criar Instância.
  2. Abra a instância e clique em Conectar. Vai aparecer um QR Code.
    [ tela: QR Code grande no centro ]
  3. No celular: WhatsApp > Aparelhos conectados > Conectar um aparelho > leia o QR. O status vira "Conectado".
  4. Na página da instância, copie o Instance ID e o Token da instância.
    [ tela: ID e Token com botão de copiar ao lado ]
  5. Em Conta > Segurança, copie o Client-Token (o token da sua conta, protege as chamadas).
Cole na Vercel (Settings > Environment Variables)
ZAPI_INSTANCE_ID ZAPI_INSTANCE_TOKEN ZAPI_CLIENT_TOKEN
B

Supabase

o banco e a fila (onde moram os contatos)
  1. Entre em supabase.com, crie uma conta e clique em New Project. Guarde a senha do banco.
  2. No menu lateral, abra o SQL Editor e clique em New query.
    [ tela: editor de SQL em branco ]
  3. Cole o schema.sql (o Claude gera pra você) e clique em Run. Isso cria as tabelas contatos e mensagens com o RLS já ligado.
  4. Vá em Project Settings > API. Copie a Project URL.
    [ tela: campo "Project URL" ]
  5. Na mesma tela, em "Project API keys", revele e copie a service_role (a secreta). Essa NUNCA vai pro front-end.
Cole na Vercel
SUPABASE_URL SUPABASE_SERVICE_ROLE_KEY
C

Hotmart

o gatilho de compra (dispara boas-vindas e carrinho)
  1. Primeiro faça o deploy do projeto na Vercel. Você vai ter uma URL tipo seu-app.vercel.app.
  2. Na Hotmart, entre no produto e vá em Ferramentas > Webhook (Postback 2.0).
    [ tela: lista de ferramentas do produto ]
  3. Clique em Cadastrar Webhook e cole a URL: https://seu-app.vercel.app/api/hotmart.
  4. Marque os eventos: Compra aprovada, Pix / aguardando pagamento e Compra cancelada.
  5. Copie o HotTok gerado (a senha do webhook). O código confere esse token pra ninguém falsificar uma compra.
    [ tela: campo "HotTok" com o token ]
Cole na Vercel
HOTMART_HOTTOK CRON_SECRET (invente uma senha longa)
04 · O Prompt Mestre

A estrela. Cole no Claude e mande construir.

Esse é o comando que faz o Claude Code te entrevistar antes de escrever uma linha e depois montar a máquina inteira. Copie, cole numa conversa nova e responda o que ele perguntar.

Prompt Mestre — A Régua

cole no Claude Code · ele entrevista e constrói
Você é meu engenheiro. Vamos construir do zero um sistema de mensagens automáticas no WhatsApp (meu próprio "botconversa"), que eu vou hospedar na Vercel. Antes de escrever qualquer código, me ENTREVISTE fazendo as perguntas abaixo, UMA POR VEZ, esperando minha resposta antes da próxima: 1. Qual o nome do meu negócio e o que eu vendo? 2. Quais desses 4 fluxos você quer ligar agora? (a) aquecer lead até matrícula, (b) boas-vindas pós-compra com link do grupo, (c) upsell dias depois, (d) carrinho abandonado (Pix não pago). 3. Para cada fluxo escolhido: quantas mensagens e com quais intervalos? (ex: 5min, 20min, 5h, 24h) 4. Qual o tom da minha copy? (ex: próximo e informal / formal / bem-humorado) 5. Qual o link do meu grupo de alunos e qual a oferta de upsell? 6. Você já tem conta na Z-API, Supabase e vende pela Hotmart? (sim/não pra cada) Depois da entrevista, construa nesta arquitetura (é um projeto de funções serverless da Vercel, JavaScript puro, sem framework pesado): - lib/supabase.js: client do Supabase com SUPABASE_URL + SUPABASE_SERVICE_ROLE_KEY (service_role, roda só no servidor). - lib/whatsapp.js: adapter Z-API que manda texto via POST https://api.z-api.io/instances/{ZAPI_INSTANCE_ID}/token/{ZAPI_INSTANCE_TOKEN}/send-text com header Client-Token; função normalizePhone que prefixa 55 em número BR. - lib/flows.js: define os 4 fluxos como dados — cada fluxo tem um id, um gatilho e uma lista de passos {step, delayMin, texto} com variáveis {nome},{produto},{valor},{link}. Função buildMessage(flowId, step, contato). - supabase/schema.sql: tabela `contatos` (id, nome, telefone, flow_id, ref, status) e tabela `mensagens` (id, contato_id, step, send_at, status pending|sending|sent|skipped|failed, texto, sent_at). Índice em (status, send_at). RLS LIGADO e SEM policies (só o service_role acessa — protege os telefones). - api/enter.js: endpoint que recebe {nome, telefone, flow_id, ref} (de um formulário/gatilho), cria o contato e agenda as mensagens daquele fluxo (send_at = agora + delayMin de cada passo). - api/hotmart.js: webhook da Hotmart. Valida o header x-hotmart-hottok contra HOTMART_HOTTOK. Compra APROVADA → dispara o fluxo de boas-vindas (e agenda o upsell). Pix gerado/WAITING_PAYMENT → dispara o fluxo de carrinho abandonado. Compra paga/cancelada → marca as mensagens pendentes daquele contato como 'skipped'. - api/dispatch.js: roda no cron. Pega mensagens com status 'pending' e send_at <= agora (limit 50), faz um "claim" otimista (update status='sending' where status='pending') pra não enviar duplicado, monta o texto com buildMessage, envia pela Z-API, marca 'sent'. Se o contato mudou de status (ex: pagou), marca 'skipped'. - vercel.json: bloco "crons" chamando /api/dispatch a cada minuto ("* * * * *"). Proteja o dispatch com CRON_SECRET (header Authorization: Bearer). - Um painel simples em / (index.html ou api) que lista contatos e o status das mensagens, pra eu acompanhar. Regras: nunca exponha a SERVICE_ROLE_KEY nem os tokens da Z-API no front-end. Comece a entrevista agora.
05 · Prompts de apoio

Depois que estiver de pé.

Máquina rodando, é hora de mexer. Esses prompts menores fazem o Claude ajustar tudo sem você tocar em código.

Trocar a copy de um fluxo

Reescreve as mensagens de um fluxo mantendo os intervalos e as variáveis.
Abra lib/flows.js. Quero reescrever as mensagens do fluxo "[carrinho abandonado]". Mantenha os mesmos passos e delayMin, e as variáveis {nome} {produto} {valor} {link}. Deixe o tom [mais próximo e informal, com no máximo 3 linhas por mensagem]. Me mostre o antes e o depois de cada passo antes de salvar.

Adicionar um 5º fluxo

Cria um fluxo novo do zero seguindo o mesmo padrão dos outros.
Quero um 5º fluxo chamado "[reativação de aluno sumido]". Gatilho: [entra pelo /api/enter com flow_id "reativacao"]. Adicione ele em lib/flows.js no mesmo formato dos outros (id, gatilho, passos com step/delayMin/texto). Sugira 4 mensagens com bons intervalos. Não quebre os fluxos que já existem.

Testar o envio agora

Cria um endpoint de teste pra você receber uma mensagem no seu número na hora.
Crie um endpoint /api/test que, ao ser chamado, usa lib/whatsapp.js pra mandar UMA mensagem de teste ("Régua funcionando ✅") pro meu número [55DDDNUMERO]. Proteja com o mesmo CRON_SECRET (header Authorization: Bearer). Me diga a URL exata pra chamar e como testar pelo navegador.

Ligar a IA na copy

Usa o Claude pra personalizar cada mensagem pelo histórico do contato antes de disparar.
No api/dispatch.js, antes de enviar, quero passar a mensagem base pela API da Anthropic (ANTHROPIC_API_KEY) pra personalizar pelo {nome} e pelo histórico do contato (campo "notas" em contatos). Use um modelo barato, prompt curto, e se a IA falhar, caia de volta na mensagem base (nunca deixe de enviar). Mantenha o "claim" otimista.
06 · Colinha de erros

Travou? Acha aqui.

Os problemas que aparecem 90% das vezes, com o motivo e o conserto. Bate o sintoma na tabela e resolve.

SintomaCausa provávelSolução
Z-API dá 401 ou não conecta Client-Token faltando ou instância desconectada do celular. Confira ZAPI_CLIENT_TOKEN na Vercel e reconecte o QR na Z-API. O celular precisa estar com o WhatsApp aberto e online.
A mensagem não sai Telefone salvo sem o 55 na frente ou número digitado errado. A normalizePhone prefixa 55 em número BR. Cheque se o número no banco tem DDD certo e 11 dígitos.
Webhook não dispara nada HotTok errado ou URL cadastrada errada na Hotmart. Confira HOTMART_HOTTOK igual ao da Hotmart e a URL apontando pra /api/hotmart. Veja os logs da função na Vercel.
O cron não roda vercel.json sem o bloco "crons" ou CRON_SECRET bloqueando. Garanta o bloco crons com * * * * * e que o CRON_SECRET na env é o mesmo que o dispatch espera.
Mensagem chega duplicada Faltou o "claim" otimista, dois crons pegaram a mesma linha. O update pra status='sending' só onde status='pending' tem que estar lá. Quem não conseguir o claim, pula.
RLS bloqueando tudo Usou a chave anon (pública) em vez da service_role. O servidor tem que usar a SUPABASE_SERVICE_ROLE_KEY. Com RLS ligado e sem policies, só ela enxerga as tabelas.
Travou de vez? Manda no grupo.

Cola o erro no grupo da Dinastia que a gente destrava com você.

Copiado!