Coloque um agente do OpenAI Agents SDK no WhatsApp
Defina o destino do webhook do número como uma rota no seu app Python. A cada mensagem recebida, rode o agente com Runner.run e uma sessão com chave no número do remetente, depois envie result.final_output de volta pela Cloud API com o token do número e o ID do número de telefone. O app do WhatsApp Business continua funcionando no mesmo número.
A sessão nativa do SDK, em arquivo ou em memória, que lembra os turnos anteriores sob um id de sessão.
MCPServerStreamableHttp aceita aqui um httpx.Auth, ou um header Authorization, para autenticar o servidor.
A versão da Graph API usada nos exemplos atuais de envio de mensagem da Meta.
Como uma mensagem do WhatsApp vira uma execução do agente?
Por uma rota no seu próprio app que a Meta chama. Defina o destino do webhook do número para ela, com um segredo longo e aleatório no caminho. A rota responde ao GET de verificação da Meta devolvendo hub.challenge como texto simples, aceita cada POST, responde 200 imediatamente e enfileira o trabalho, porque a Meta repete respostas lentas e você rodaria o agente duas vezes.
Um worker então lê o remetente e o texto do payload e chama Runner.run. Passe uma sessão cujo id seja o número do remetente: o SDK guarda a conversa sob esse id, então a próxima mensagem do mesmo cliente continua de onde a anterior parou, e dois clientes nunca compartilham um histórico. SQLiteSession basta para começar; o SDK também traz sessões Redis e SQLAlchemy para vários workers.
O segredo na URL é a autenticação aqui. A Meta assina as entregas com o app secret do Tech Provider, então o cliente não consegue validar o header de assinatura.
import os, httpx
from agents import Agent, Runner, SQLiteSession
agent = Agent(name="Front desk", instructions="Answer briefly and politely.")
URL = f"https://graph.facebook.com/v25.0/{os.environ['PHONE_NUMBER_ID']}/messages"
async def handle(sender: str, text: str) -> None:
session = SQLiteSession(sender, "whatsapp.db")
result = await Runner.run(agent, text, session=session)
async with httpx.AsyncClient() as http:
await http.post(
URL,
headers={"Authorization": f"Bearer {os.environ['WA_TOKEN']}"},
json={"messaging_product": "whatsapp", "to": sender,
"type": "text", "text": {"body": result.final_output}},
)Por que o seu código deve enviar a resposta, e não o agente?
Porque a única regra que nunca pode ser quebrada é uma regra de tempo, e o código a garante melhor que um prompt. A Meta abre uma janela de atendimento de 24 horas quando um cliente escreve. Dentro dela, texto livre passa. Fora dela, só um template aprovado passa, e o texto livre volta com o erro 131047.
Um worker que responde à mensagem que acabou de chegar está sempre dentro da janela, então enviar result.final_output como texto é seguro por construção. O trabalho que acontece depois, um acompanhamento na manhã seguinte ou um lembrete, deve passar por um caminho separado que envia um template e nunca texto livre.
O agente ainda pode ter ferramentas. Dê a ele function tools para consultar coisas, como um pedido ou uma reserva, e mantenha o envio do WhatsApp no worker. Isso também mantém o token de acesso fora de qualquer coisa que o modelo possa chamar com argumentos arbitrários.
O agente pode usar o servidor MCP do EasyCoexistence?
Pode, por MCPServerStreamableHttp, com mais configuração do que um header. O SDK aceita um header Authorization ou um httpx.Auth em params["auth"]. O servidor MCP do EasyCoexistence emite os próprios tokens OAuth após um login no navegador, com registro dinâmico de cliente e PKCE, então não existe uma chave estática. O SDK Python do MCP traz OAuthClientProvider, um handler de autenticação HTTP que executa esse fluxo com PKCE e renovação de token, e é isso que vai em params["auth"].
Vale a pena quando o agente deve decidir por conta própria: verificar a saúde de um número, ler o status de um template ou escolher entre send_message e send_template usando as regras nas descrições das ferramentas. Para uma recepção que só responde, o worker acima é mais curto e tem menos o que dar errado.
De qualquer forma, o webhook continua. O MCP é requisição e resposta, e a mensagem de um cliente só chega ao agente pela rota que a Meta chama.
Erros comuns
- Rodar o agente antes de devolver 200 à Meta. Uma resposta lenta é repetida, e o cliente recebe duas respostas.
- Usar uma sessão para todos os clientes. Use o número do remetente como chave, ou os históricos se misturam.
- Deixar um acompanhamento atrasado enviar texto livre. Depois de 24 horas ele falha com 131047; envie um template.
Conecte o número em easycoexistence.com, defina o destino do webhook para a sua rota e leia o token e o ID do número de telefone no painel. A partir de US$ 9 por número conectado por mês, caindo para US$ 1 conforme você adiciona números, com os 3 primeiros dias grátis.
Perguntas frequentes
Isso exige a ferramenta MCP hospedada da OpenAI Responses API?
Não. O worker roda o agente localmente com Runner.run, e o lado do WhatsApp é uma chamada HTTPS simples feita pelo seu código.
Qual versão da Graph API devo usar?
Os exemplos atuais da Meta usam v25.0. Fixe a versão em um único lugar do código, para que atualizar seja uma mudança de uma linha.
Uma pessoa pode assumir pelo celular?
Sim. A Coexistência mantém o app do WhatsApp Business funcionando, e uma resposta pelo celular chega à sua rota como um evento de echo que o worker pode usar para pausar o agente.
O EasyCoexistence armazena a conversa?
Não. A Meta entrega direto na sua rota. O que a sessão guardar fica no seu próprio banco de dados.
Continue lendo
Pronto para começar?
Configure o WhatsApp Coexistence em minutos, não em meses. O aplicativo continua funcionando no celular.
Começar teste grátisVerificado em