@gabrielonrails/whatsapp-flows
v0.2.0
Published
Tap independente da Meta para monitorar WhatsApp Flows na Axon — envolva seu Flow endpoint e seu webhook e receba boletins de qualidade A–F por sessão de Flow.
Maintainers
Readme
@gabrielonrails/whatsapp-flows
Tap independente da Meta para monitorar WhatsApp Flows na Axon — a camada de qualidade para agentes de IA.
Por que independente da Meta
O WhatsApp Flows usa criptografia assimétrica em que a sua empresa detém a chave privada e a Meta só a pública. Logo, o seu Flow endpoint é o único lugar (fora do device do usuário) onde os dados do Flow existem em claro. Este SDK tapeia esse endpoint (e o seu webhook de conclusão) e envia a trajetória para a Axon — você não depende do "Flows Insights" da Meta para saber onde os usuários abandonam, qual campo gera fricção ou se a automação usou os dados de volta corretamente.
Visibilidade tela-a-tela exige Flows endpoint-driven (
data_exchange). Flows estáticos (sem endpoint) só expõem envio + conclusão via webhook; o abandono intermediário só existe no painel da Meta.
Instalação
npm i @gabrielonrails/whatsapp-flowsNode 18+. Sem dependências (usa node:crypto).
Uso
import { AxonFlows } from "@gabrielonrails/whatsapp-flows";
const flows = new AxonFlows({
apiKey: process.env.AXON_API_KEY!, // axon_sk_... (Configurações → Integração)
agent: "atendimento", // slug do agente (criado se não existir)
});1) Ao disparar o Flow (send)
Gere um flowToken e registre o envio quando seu bot manda o Flow (via Cloud API ou BSP):
const flowToken = flows.generateFlowToken();
await sendFlowViaCloudApi({ flowToken, /* ... */ });
await flows.flowSent({ flowToken, flowId: "123", flowName: "Agendamento", cta: "Agendar", waId });2) No seu Flow endpoint (turnkey: decifra + monitora)
flowEndpoint decifra a requisição da Meta, chama a sua lógica de negócio, cifra a resposta e emite a trajetória para a Axon — sem bloquear (best-effort):
const handleFlow = flows.flowEndpoint({
privateKey: process.env.FLOW_PRIVATE_KEY!,
passphrase: process.env.FLOW_PRIVATE_KEY_PASSPHRASE,
handler: async (req) => {
// req já vem DECIFRADO: { action, screen, data, flow_token }
return nextScreenFor(req); // sua lógica de sempre
},
});
// Next.js (App Router):
export async function POST(request: Request) {
const body = await request.json();
const encrypted = await handleFlow(body); // string base64
return new Response(encrypted, { headers: { "content-type": "text/plain" } });
}Já tem seu próprio decifrador? Use os helpers avulsos:
import { decryptFlowRequest, encryptFlowResponse } from "@gabrielonrails/whatsapp-flows";3) No seu webhook de mensagens (conclusão)
A conclusão do Flow chega como nfm_reply no webhook do Cloud API. trackWebhook extrai o response_json + flow_token e fecha a sessão na Axon:
export async function POST(request: Request) {
const body = await request.json();
await flows.trackWebhook(body); // best-effort
return new Response("OK");
}O que a Axon faz com isso
Costura os eventos por flow_token numa sessão, materializa numa conversa (canal whatsapp) e roda o juiz LLM (BYOK). O boletim inclui um bloco Flow: adequação do disparo, conclusão, uso dos dados no downstream e fricção — além do funil por tela (onde caem os usuários). Sessões sem conclusão na janela viram abandono automaticamente.
PII (CPF, nome, endereço no response_json) é redigida no ingest — nada sensível é persistido em claro.
Licença
MIT
