← Blog

·

Como conectar o ChatGPT à API oficial do WhatsApp (tutorial com código)

Atualizado em 28/10/2026

Para conectar o ChatGPT à API oficial do WhatsApp, você recebe a mensagem do cliente pelo webhook, envia o histórico daquela conversa para a Responses API da OpenAI (POST https://api.openai.com/v1/responses) e devolve o texto gerado com uma chamada de envio da Cloud API. A resposta livre só pode sair dentro da janela de 24 horas aberta pelo cliente, e a política da Meta exige um caminho claro para atendimento humano. O uso permitido é a IA como apoio ao atendimento da sua empresa; oferecer um “ChatGPT de uso geral” como produto no WhatsApp tem regras próprias nos termos da Meta.

Este tutorial é a parte prática: código Node.js completo, histórico por contato, controle da janela, passagem para humano e custo. A arquitetura em geral (fila, deduplicação, estados) está em Chatbot com IA no WhatsApp pela API oficial, que vale ler antes.

O que você precisa antes de começar

  • Um número conectado à API oficial, com webhook configurado. Se ainda não tem, o guia da API oficial do WhatsApp explica o caminho.
  • Uma chave da API da OpenAI (OPENAI_API_KEY), criada no painel da OpenAI.
  • Node.js 18 ou superior (o exemplo usa fetch nativo e o SDK oficial openai).
  • Um banco para guardar histórico e estado da conversa. No exemplo usamos memória para simplificar.

Nada no WhatsApp muda por você usar o ChatGPT: a Cloud API não sabe qual modelo gera o texto. Quem regula o uso são os termos da Meta, que veremos adiante.

O fluxo em 5 passos

PassoO que aconteceOnde
1O cliente manda mensagem e a Meta dispara o webhookMeta → seu servidor (direto ou via provedor)
2Seu servidor responde 200 na hora e enfileira o eventoWebhook
3O worker carrega o histórico daquele wa_id e decide se o bot respondeBanco + roteador
4O worker chama a Responses API com instruções e históricoOpenAI
5O texto volta ao cliente por POST /messagesCloud API

O ponto que mais derruba integrações feitas às pressas é o passo 2. O modelo pode levar alguns segundos para responder, e o webhook não pode esperar. Na Vectalk, por exemplo, o endpoint precisa devolver HTTP 200 em até 20 segundos, ou o evento é reenviado, segundo a documentação de webhooks. Reenvio sem deduplicação vira resposta duplicada e custo dobrado.

Quer testar enquanto lê? Crie sua conta na Vectalk e envie a primeira mensagem pela API oficial. Criar conta grátis →

Responses API ou Chat Completions?

A OpenAI tem duas APIs para gerar texto. A documentação de geração de texto recomenda a Responses API para aplicações novas, e é ela que usamos aqui. A chamada mínima é:

curl https://api.openai.com/v1/responses \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "SEU_MODELO",
    "instructions": "Você é o assistente da Loja Exemplo. Responda em até 3 frases.",
    "input": "Qual o prazo de entrega para Natal/RN?"
  }'

Três parâmetros importam para um bot de WhatsApp:

  • instructions: o comportamento do bot (tom, escopo, o que ele não faz). Vale só para a requisição atual, então envie sempre.
  • input: a pergunta, ou uma lista de mensagens user e assistant com o histórico.
  • model: escolha na página de modelos da OpenAI. Deixe numa variável de ambiente para trocar sem mexer no código.

Nos SDKs oficiais, o texto final fica em response.output_text. Não leia output[0] direto: a saída pode conter outros itens antes do texto, como chamadas de ferramenta.

Histórico por contato: três jeitos

O ChatGPT não lembra da conversa sozinho. A cada mensagem, você precisa dizer qual é o contexto. A documentação de estado da conversa descreve três opções:

OpçãoComo funcionaOnde o histórico ficaQuando usar
Histórico manualVocê envia as últimas mensagens no inputNo seu bancoPadrão recomendado para atendimento: você controla tamanho, retenção e auditoria
previous_response_idVocê envia só a mensagem nova e o ID da resposta anteriorNa OpenAI (objetos de resposta são guardados por 30 dias por padrão)Protótipos; os tokens das respostas anteriores continuam cobrados como entrada
Conversations APIVocê cria uma conversa e passa o ID em conversationNa OpenAI, sem o limite de 30 diasQuando quer um estado durável do lado da OpenAI

Para atendimento no Brasil, o histórico manual costuma ser a escolha mais simples de justificar: os dados ficam no seu banco, você define por quanto tempo guarda e pode usar store: false para pedir que a OpenAI não salve a resposta. A chave do histórico é o wa_id do cliente (o campo from da mensagem recebida).

Se a conversa envolve dados pessoais, a LGPD se aplica ao que você envia ao provedor de IA. Este artigo não substitui orientação jurídica; veja também LGPD e WhatsApp.

Código completo em Node.js

O exemplo usa Express, o SDK openai e o envio pela Vectalk, que aceita o mesmo payload da Cloud API. Com token de instância, o número de origem é resolvido automaticamente; com token de organização, inclua phone_number_id no corpo, conforme a referência de envio. Se você integra direto com a Meta, troque a URL por https://graph.facebook.com/<versão>/<PHONE_NUMBER_ID>/messages e use o seu token da Meta.

npm install express openai
import express from 'express';
import OpenAI from 'openai';

const openai = new OpenAI(); // lê OPENAI_API_KEY do ambiente
const MODELO = process.env.OPENAI_MODEL;
const ENVIO_URL = 'https://apis.vectalk.com.br/api/messages';
const TOKEN = process.env.VECTALK_TOKEN; // token de instância
const JANELA_MS = 24 * 60 * 60 * 1000;
const MAX_TURNOS = 20;

const INSTRUCOES = `Você é o assistente virtual da Loja Exemplo no WhatsApp.
- Responda em português, em no máximo 3 frases curtas.
- Fale só sobre pedidos, entregas, trocas e produtos da loja.
- Não invente preços, prazos ou políticas: use apenas os dados fornecidos.
- Se não souber, se o cliente pedir uma pessoa ou o assunto for reclamação,
  cancelamento ou cobrança, responda exatamente: HANDOFF`;

const app = express();
app.use(express.json());

const fila = [];
const processados = new Set();  // wamid já tratados (use Redis/banco em produção)
const conversas = new Map();    // wa_id -> { estado, historico, ultimaEntrada }

// 1. Webhook: enfileira e responde 200 imediatamente
app.post('/webhook', (req, res) => {
  for (const entry of req.body.entry ?? []) {
    for (const change of entry.changes ?? []) {
      for (const msg of change.value?.messages ?? []) fila.push(msg);
    }
  }
  res.sendStatus(200);
});

// 2. Envio para o WhatsApp
async function enviar(corpo) {
  const r = await fetch(ENVIO_URL, {
    method: 'POST',
    headers: { Authorization: `Bearer ${TOKEN}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ messaging_product: 'whatsapp', ...corpo }),
  });
  if (!r.ok) throw new Error(`Envio falhou: ${r.status} ${await r.text()}`);
  return r.json();
}

// 3. Chamada à OpenAI (Responses API)
async function perguntarAoModelo(historico) {
  const resposta = await openai.responses.create(
    {
      model: MODELO,
      instructions: INSTRUCOES,
      input: historico,          // [{ role: 'user' | 'assistant', content: '...' }]
      max_output_tokens: 300,    // respostas curtas custam menos
      store: false,              // não guardar a resposta na OpenAI
    },
    { timeout: 15000 },
  );
  return resposta.output_text.trim();
}

// 4. Worker
async function processar(msg) {
  if (processados.has(msg.id)) return;
  processados.add(msg.id);

  const c = conversas.get(msg.from) ?? { estado: 'bot', historico: [], ultimaEntrada: 0 };
  c.ultimaEntrada = Number(msg.timestamp) * 1000;
  conversas.set(msg.from, c);

  if (c.estado !== 'bot') return; // um humano assumiu: o bot não responde

  if (msg.type !== 'text') {
    await enviar({ to: msg.from, type: 'text', text: { body: 'Por aqui eu entendo só texto. Pode escrever sua dúvida?' } });
    return;
  }

  await enviar({ status: 'read', message_id: msg.id }); // marca como lida

  c.historico.push({ role: 'user', content: msg.text.body });
  c.historico = c.historico.slice(-MAX_TURNOS);

  let texto;
  try {
    texto = await perguntarAoModelo(c.historico);
  } catch (e) {
    console.error('OpenAI falhou', e);
    texto = 'HANDOFF'; // na dúvida, passa para uma pessoa
  }

  if (texto === 'HANDOFF') return transferir(msg.from, c);
  if (Date.now() - c.ultimaEntrada > JANELA_MS) return; // janela fechou: só template

  await enviar({ to: msg.from, type: 'text', text: { body: texto } });
  c.historico.push({ role: 'assistant', content: texto });
}

async function transferir(waId, c) {
  c.estado = 'humano';
  await enviar({ to: waId, type: 'text', text: { body: 'Vou chamar uma pessoa do nosso time. Já já alguém continua por aqui.' } });
  // Avise a ferramenta de atendimento (fila de tickets, CRM, Slack).
}

setInterval(async () => {
  const msg = fila.shift();
  if (!msg) return;
  try { await processar(msg); } catch (e) { console.error(e); }
}, 50);

app.listen(3000, () => console.log('Bot no ar na porta 3000'));

Para rodar:

export OPENAI_API_KEY="sk-..."
export OPENAI_MODEL="modelo-escolhido-na-pagina-de-modelos"
export VECTALK_TOKEN="seu-token-de-instancia"
node bot.mjs

Para testar localmente, exponha a porta 3000 com um túnel e cadastre a URL como webhook; o passo a passo está em como testar o webhook localmente. Se o seu webhook recebe direto da Meta, valide a assinatura de cada requisição antes de processar: veja como validar o X-Hub-Signature-256.

Enquanto o modelo pensa, a Cloud API permite mostrar “digitando…” na mesma chamada que marca a mensagem como lida, acrescentando "typing_indicator": { "type": "text" }. Segundo a documentação de indicadores de digitação, ele some quando você responde ou depois de 25 segundos, o que vier primeiro, e a Meta recomenda usá-lo só quando você realmente vai responder.

O que o exemplo resolve e o que falta

  • Resolve: resposta imediata ao webhook, deduplicação por wamid, histórico por contato com limite de tamanho, timeout na OpenAI, checagem da janela e estado de handoff.
  • Falta para produção: fila persistente com novas tentativas, banco para histórico e estado, controle de ritmo de envio (throughput), registro de custo por conversa e um painel para o atendente devolver a conversa ao bot.

Versões completas de bot, sem a parte de IA, estão em bot com Node.js e bot com Python.

Janela de 24 horas: o ChatGPT não puxa conversa

A resposta gerada pelo modelo é uma mensagem livre. A Política de Mensagens do WhatsApp Business permite responder sem template só dentro da janela de atendimento de 24 horas, aberta e renovada a cada mensagem do cliente. Fora dela, só templates aprovados.

Na prática:

  • O bot é reativo. Ele não pode mandar “Oi, ainda está interessado?” dois dias depois com texto gerado pelo ChatGPT. Para isso existe template.
  • Cheque a janela antes de enviar, não só quando a mensagem chega. Se o modelo travou, a fila atrasou ou o worker caiu, a janela pode fechar no meio do caminho.
  • Não use o modelo para “preencher” um template. Templates têm texto aprovado e variáveis; o conteúdo das variáveis deve vir de dados do seu sistema.

As regras de abertura e renovação estão em janela de 24 horas do WhatsApp.

Passar para humano

A política da Meta permite automação dentro da janela, mas exige caminhos de escalonamento claros, como a transferência para um atendente humano na conversa, telefone, e-mail, suporte no site ou formulário. No código acima, três situações levam ao handoff:

  1. O modelo responde HANDOFF porque não sabe, o cliente pediu uma pessoa ou o assunto é sensível (as instruções dizem isso).
  2. A chamada à OpenAI falha ou passa do tempo.
  3. Você pode somar gatilhos próprios, como palavras-chave ou um botão “Falar com atendente”.

Depois do handoff, o estado da conversa vira humano e o bot fica em silêncio até o atendente devolver. Se o número usa coexistência, o atendente pode responder pelo app WhatsApp Business, e as mensagens enviadas pelo app chegam ao seu sistema como eventos de eco; dá para usá-los para marcar a conversa como humano automaticamente.

Quanto custa: Meta + OpenAI

São duas contas separadas.

WhatsApp (Meta). As respostas do bot dentro da janela são mensagens de serviço. Desde 1º/10/2026, cada número tem 1.000 mensagens de serviço gratuitas por mês, e a cobrança começa na 1.001ª. Para destinatários no Brasil, a tarifa de serviço é R$ 0,0350 por mensagem entregue, segundo a página de preços da Meta. Templates são cobrados pela tarifa da categoria, dentro ou fora da janela (marketing R$ 0,3217; utilidade e autenticação R$ 0,0350); desde 1º/10/2026, isso inclui templates de utilidade enviados dentro da janela.

OpenAI. A cobrança é por tokens de entrada e de saída, com preço que depende do modelo. Consulte a página de preços da OpenAI antes de estimar.

Três ajustes reduzem as duas contas ao mesmo tempo:

  • Uma resposta por pergunta. Três mensagens curtas custam três mensagens de serviço depois da franquia. Peça ao modelo uma resposta única.
  • Histórico curto. Cada mensagem antiga enviada no input é token de entrada cobrado de novo. Mantenha as últimas trocas e, se precisar, um resumo.
  • max_output_tokens. Limita o tamanho da resposta e evita textos longos que ninguém lê no celular.

Para simular o lado do WhatsApp, veja quanto custa uma campanha no WhatsApp.

O que a Meta permite: “ChatGPT de uso geral” é outro caso

Os Termos da Meta para a Plataforma do WhatsApp Business, atualizados em 23/09/2026, tratam de “Provedores de IA” na seção 4.7: fornecedores e desenvolvedores de tecnologias de IA ou machine learning, como grandes modelos de linguagem, plataformas de IA generativa e assistentes de IA de uso geral. Eles são proibidos de usar a plataforma para oferecer essas tecnologias quando elas são a funcionalidade principal, e não incidental ou auxiliar, a critério da Meta. Os termos preveem exceções para determinados países.

CenárioLeitura dos termos
Loja usa um modelo da OpenAI para responder dúvidas sobre pedidosIA como apoio ao atendimento da empresa; não é o caso que a cláusula mira
Clínica usa IA para agendar e confirmar consultasIdem: a IA é ferramenta do serviço, não o produto
Empresa oferece “converse com uma IA sobre qualquer assunto” no WhatsAppÉ o caso de Provedor de IA; depende das regras por país

O Brasil é um desses países. A página de preços para Provedores de IA, atualizada em 15/10/2026, informa que desde 11/03/2026 Provedores de IA podem enviar mensagens de serviço a usuários com número +55, com cobrança própria, sempre em resposta ao usuário (a janela de atendimento continua valendo). Nessas mensagens, o webhook de status traz a categoria general_purpose_ai. A regra vale só para Provedores de IA; o preço das demais empresas não muda.

Os termos também proíbem usar dados da plataforma para criar, treinar ou melhorar modelos de IA, com exceção para ajustar um modelo de uso exclusivo da empresa que não sirva para outros modelos. Na prática: revise como o seu provedor de IA trata retenção e treino, e não reaproveite conversas do WhatsApp para treinar modelos de terceiros.

Como fazer isso com a Vectalk

A Vectalk é um proxy da Cloud API oficial: seu bot recebe os mesmos webhooks da Meta e envia com os mesmos payloads, trocando apenas a URL base e o token. No código acima, isso é a constante ENVIO_URL e o VECTALK_TOKEN. Você registra a URL do bot com POST /api/webhooks e pode cadastrar mais de uma URL por instância, por exemplo uma para o bot e outra para o seu sistema de atendimento. Você não cadastra cartão na Meta: cada mensagem entregue é descontada do saldo pré-pago da sua conta Vectalk, e a coexistência deixa o time humano responder pelo app quando o bot passa a conversa. Comece em apps.vectalk.com.br/register e veja o guia rápido.

Perguntas frequentes

Preciso de autorização da Meta para usar o ChatGPT no WhatsApp?

Para um bot de atendimento da própria empresa, a documentação consultada não descreve cadastro adicional: você usa a API oficial normalmente. Se o seu produto é um assistente de IA de uso geral, leia a seção 4.7 dos termos e a página de Provedores de IA antes de lançar.

Posso usar o app do ChatGPT ou um “ChatGPT para WhatsApp” pronto?

Este tutorial usa a API da OpenAI no seu servidor, ligada à API oficial do WhatsApp. Ferramentas que conectam o WhatsApp lendo QR Code usam canais não oficiais, com risco de banimento; veja API oficial x não oficial.

O bot pode mandar a primeira mensagem?

Não com texto gerado pelo modelo. Para iniciar ou retomar contato fora da janela de 24 horas, é preciso um template aprovado.

Como faço o ChatGPT responder áudio?

O webhook entrega o ID da mídia. Você baixa o arquivo pela API de mídia, transcreve com o serviço que preferir e envia o texto ao modelo. O download está em como baixar a mídia que o cliente envia.

Uso Responses API ou Chat Completions?

As duas funcionam com o WhatsApp, porque a integração é só HTTP. A OpenAI recomenda a Responses API para aplicações novas, e é ela que o exemplo usa.


Fontes oficiais consultadas em 28/10/2026: OpenAI: geração de texto, OpenAI: estado da conversa, Termos da Meta para a Plataforma do WhatsApp Business (atualizados em 23/09/2026), Política de Mensagens do WhatsApp Business (atualizada em 23/09/2026), Preços para Provedores de IA (atualizada em 15/10/2026), Preços da plataforma do WhatsApp Business, Indicadores de digitação e leitura, Vectalk: webhooks, Vectalk: envio de mensagens, Lei nº 13.709/2018 (LGPD).

Teste a API oficial do WhatsApp hoje

Crie sua conta, gere o token e envie a primeira mensagem seguindo o guia da documentação. Mesmos payloads e webhooks da Cloud API da Meta.