Puneți un agent OpenAI Agents SDK pe WhatsApp
Setați destinația webhook-ului numărului către o rută din aplicația dumneavoastră Python. Pentru fiecare mesaj primit, rulați agentul cu Runner.run și o sesiune identificată prin numărul expeditorului, apoi trimiteți result.final_output înapoi prin Cloud API, cu token-ul numărului și ID-ul numărului de telefon. Aplicația WhatsApp Business continuă să funcționeze pe același număr.
Sesiunea integrată a SDK-ului, pe fișier sau în memorie, care reține turele anterioare sub un ID de sesiune.
MCPServerStreamableHttp acceptă aici un httpx.Auth sau un header Authorization pentru autentificarea serverului.
Versiunea Graph API folosită în exemplele actuale de trimitere a mesajelor din documentația Meta.
Cum devine un mesaj WhatsApp o rulare a agentului?
Printr-o rută din propria aplicație, pe care o apelează Meta. Setați destinația webhook-ului numărului către ea, cu un secret lung și aleatoriu în cale. Ruta răspunde la GET-ul de verificare al Meta returnând hub.challenge ca text simplu, acceptă fiecare POST, răspunde imediat cu 200 și pune lucrul în coadă, pentru că Meta reîncearcă răspunsurile lente și ați rula agentul de două ori.
Un worker citește apoi expeditorul și textul din payload și apelează Runner.run. Transmiteți o sesiune al cărei ID este numărul expeditorului: SDK-ul stochează conversația sub acel ID, așa că următorul mesaj de la același client continuă de unde s-a oprit ultimul, iar doi clienți nu împart niciodată același istoric. SQLiteSession este suficient pentru început; SDK-ul include și sesiuni Redis și SQLAlchemy pentru mai mulți workeri.
Secretul din URL este autentificarea aici. Meta semnează livrările cu secretul aplicației Tech Provider, deci clientul nu poate valida antetul semnăturii.
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}},
)De ce ar trebui codul dumneavoastră să trimită răspunsul, nu agentul?
Pentru că singura regulă care nu trebuie încălcată este una de timp, iar codul o impune mai bine decât un prompt. Meta deschide o fereastră de 24 de ore pentru suportul clienților când un client scrie. În interiorul ei, textul liber trece. În afara ei, trece doar un template aprobat, iar textul liber întoarce eroarea 131047.
Un worker care răspunde mesajului tocmai sosit se află mereu în fereastră, deci trimiterea lui result.final_output ca text este sigură prin construcție. Lucrul care se petrece mai târziu, o urmărire a doua zi dimineață sau o reamintire, trebuie să treacă printr-o cale separată, care trimite un template și niciodată text liber.
Agentul poate avea totuși unelte. Dați-i function tools pentru consultări, de exemplu o comandă sau o rezervare, și păstrați trimiterea pe WhatsApp în worker. Astfel token-ul de acces rămâne departe de orice poate apela modelul cu argumente arbitrare.
Poate agentul să folosească serverul MCP EasyCoexistence?
Poate, prin MCPServerStreamableHttp, cu mai multă configurare decât un simplu header. SDK-ul acceptă fie un header Authorization, fie un httpx.Auth în params["auth"]. Serverul MCP EasyCoexistence emite propriile token-uri OAuth după o autentificare în browser, cu înregistrare dinamică a clientului și PKCE, deci nu există o cheie statică. SDK-ul MCP Python include OAuthClientProvider, un handler de autentificare HTTP care rulează acel flux cu PKCE și reînnoirea token-ului, iar acesta este cel care se pune în params["auth"].
Merită când agentul trebuie să decidă singur: să verifice starea unui număr, să citească statusul template-urilor sau să aleagă între send_message și send_template după regulile din descrierile uneltelor. Pentru o recepție care doar răspunde, worker-ul de mai sus este mai scurt și are mai puține lucruri care pot merge prost.
Oricum, webhook-ul rămâne. MCP funcționează pe model cerere și răspuns, iar mesajul unui client poate ajunge la agent doar prin ruta pe care o apelează Meta.
Greșeli frecvente
- Rularea agentului înainte de a returna 200 către Meta. Un răspuns lent este reîncercat, iar clientul primește două răspunsuri.
- Folosirea unei singure sesiuni pentru toți clienții. Identificați-o prin numărul expeditorului, altfel istoricurile se amestecă.
- Lăsarea unei urmăriri întârziate să trimită text liber. După 24 de ore eșuează cu eroarea 131047; trimiteți în schimb un template.
Conectați numărul la easycoexistence.com, setați destinația webhook-ului către ruta dumneavoastră și citiți token-ul și ID-ul numărului de telefon din dashboard. De la US$ 9 per număr pe lună, scăzând la US$ 1 pe măsură ce adăugați numere, cu primele 3 zile gratuite.
Întrebări frecvente
Este nevoie de unealta MCP găzduită din OpenAI Responses API?
Nu. Worker-ul rulează agentul local cu Runner.run, iar partea WhatsApp este un apel HTTPS simplu, făcut de codul dumneavoastră.
Ce versiune de Graph API ar trebui să folosesc?
Exemplele actuale ale Meta folosesc v25.0. Fixați o versiune într-un singur loc din cod, ca o actualizare să fie o schimbare de o linie.
Poate o persoană să preia conversația de pe telefon?
Da. Coexistence păstrează aplicația WhatsApp Business funcțională, iar un răspuns de pe telefon ajunge la ruta dumneavoastră ca eveniment echo, pe care worker-ul îl poate folosi pentru a opri agentul.
Stochează EasyCoexistence conversația?
Nu. Meta livrează direct la ruta dumneavoastră. Tot ce stochează sesiunea se află în propria bază de date.
Continuați să citiți
Gata să începeți?
Configurați WhatsApp Coexistence în câteva minute, nu luni. Aplicația continuă să funcționeze pe telefon.
Începeți perioada de probă gratuităVerificat la