Skip to main content
Fiecare solicitare pe care o trimitem către serverul dumneavoastră — livrările de webhook și invocările endpointurilor de instrumente — include o semnătură HMAC-SHA256 în antetul X-ThunderPhone-Signature. Configurați verificarea corect o singură dată și utilizați același ajutor în fiecare handler.

Algoritmul

  1. Citiți corpul brut al solicitării — octeții exacți pe care vi i-am trimis prin POST.
  2. Calculați hmac_sha256(secret, body).hexdigest().
  3. Comparați în timp constant cu X-ThunderPhone-Signature. (Compararea naivă a șirurilor dezvăluie informații de temporizare.)
Semnăm exact octeții pe care îi transmitem, astfel încât verificarea corpului brut funcționează întotdeauna. Acei octeți reprezintă și serializarea JSON canonică a payloadului — chei sortate alfabetic, separatori compacți (, și : fără spații), UTF-8. Astfel aveți o a doua metodă, complet echivalentă, atunci când frameworkul dumneavoastră expune doar JSON analizat: reserializați canonic și calculați HMAC pentru acesta.
Preferați corpul brut — este cu un pas mai puțin și este imun la particularitățile conversiei dus-întors a numerelor JSON în unele limbaje.

Care secret?

Stocați secretul în managerul dumneavoastră de secrete sau într-o variabilă de mediu — nu îl comiteți niciodată.

Implementări de referință

Toate cele patru verifică corpul brut al solicitării:

Configurare specifică frameworkului

Verificarea apelurilor de instrumente

Când agentul invocă direct unul dintre instrumentele de funcții (instrumentul are un endpoint), solicitarea include două antete ThunderPhone pe lângă endpoint.headers configurat:
  • X-ThunderPhone-Call-ID — ID-ul numeric al apelului în desfășurare.
  • X-ThunderPhone-Signature — HMAC-SHA256, cu cheia reprezentată de secretul webhook la nivel de organizație, calculat peste octeții exacți ai corpului solicitării.
Același ajutor verify() funcționează fără modificări, cu două particularități:
  1. Instrumentele GET / DELETE nu au corp. Argumentele sunt transmise ca parametri de interogare, iar semnătura este calculată peste șirul de octeți gol — deci verify(b"", sig, secret) (Python) sau verify(Buffer.alloc(0), sig, secret) (Node). Nu calculați hash-ul șirului de interogare.
  2. Organizațiile fără un webhook moștenit configurat nu au un secret de organizație. În acest caz, apelurile de instrumente includ doar X-ThunderPhone-Call-ID și niciun antet de semnătură. Configurați webhookul moștenit (PUT /v1/webhook) pentru a obține un secret de semnare sau autentificați apelurile de instrumente cu propriul antet prin endpoint.headers.
Dispecerizarea instrumentelor în modul webhook (instrumente fără un endpoint, livrate către webhookul organizației dumneavoastră ca telephony.tool / web.tool) este un webhook semnat obișnuit — se aplică procedura standard de mai sus. Consultați Instrumente de funcții pentru ambele forme de solicitare.

Capcane frecvente

Analizarea corpului și serializarea lui din nou cu setările implicite ale bibliotecii JSON (spații după , / :, chei în ordinea inserării) produce octeți diferiți și invalidează HMAC-ul. Verificați corpul brut — sau, dacă trebuie să îl reserializați, respectați exact forma noastră canonică: chei sortate, separatori compacți, UTF-8.
Middleware-ul express.json() din Express consumă fluxul corpului și pierdeți octeții bruti. Utilizați express.raw() specific pe ruta webhookului sau stocați corpul brut într-un pre-middleware. La fel și pentru NestJS / Koa — consultați documentația lor despre „raw body”.
expected === signature în JS sau expected == signature în Python sunt comparații cu durată variabilă. Utilizați crypto.timingSafeEqual sau, respectiv, hmac.compare_digest. Diferența de performanță este nulă.
Apelurile directe către endpointurile de instrumente sunt semnate cu secretul webhook la nivel de organizație (GET /v1/webhook) — nu cu un secret per-endpoint din /v1/developer/webhook-endpoints. Reutilizați aceeași funcție verify(), dar asigurați-vă că îi transmiteți secretul organizației pe rutele instrumentelor.
Pentru metodele de instrumente fără corp, semnătura acoperă șirul gol de octeți, păstrând o singură rețetă universală: calculați HMAC-ul pentru corpul brut al solicitării, indiferent care este acesta. Hash-uirea URL-ului sau a șirului de interogare nu se va potrivi niciodată.
Returnarea codului 200 când verificarea eșuează transformă handlerul într-o țintă pentru reluarea solicitărilor. Răspundeți întotdeauna cu un cod diferit de 2xx dacă verificarea eșuează.

Pașii următori

Prezentare generală a webhookurilor

Semantica livrării, reîncercări, IP-uri sursă.

Endpointuri webhook

Gestionați mai multe URL-uri, rotiți secretele.

Instrumente pentru funcții

Cele două căi de invocare a instrumentelor și formatele solicitărilor lor.

Integrări de instrumente

Creați o integrare completă bazată pe instrumente, de la un capăt la altul.