ThunderPhone 2.0 je tu.Začnite sami, už od 2 ¢/min.Prečítať oznámenie

Webhooks

Prehľad webhookov

Ako ThunderPhone doručuje udalosti v reálnom čase, ako overovať podpisy a ako sa porovnávajú starší model doručovania a model založený na koncových bodoch.

ThunderPhone odosiela požiadavky HTTP POST na váš server, keď počas hovoru dôjde k udalostiam — začne sa prichádzajúci hovor, hovor sa skončí, dokončí sa spustenie hodnotenia, aktivuje sa upozornenie a podobne. K dispozícii sú dva modely doručovania:

Všetky uvedené typy udalostí v katalógu udalostí sa doručujú prostredníctvom koncových bodov webhookov. Šesť udalostí životného cyklu hovoru (telephony.incoming, telephony.complete, telephony.tool, web.incoming, web.complete, web.tool) sa tiež odosiela do staršieho webhooku s jednou adresou URL — ak máte staršiu adresu URL aj zodpovedajúci koncový bod, udalosť prijmete na oboch cestách. Blokujúce správanie (výmena konfigurácie telephony.incoming / web.incoming a odosielanie nástrojov v režime webhooku) je dostupné výlučne cez staršiu cestu; každé doručenie na koncový bod je oznámenie typu fire-and-forget.

Formát údajov

Doručenia na koncové body sú objektom JSON s položkami data, event_id a type:

{
  "data": {
    "call_id": 987654321,
    "from_number": "+14155550199",
    "to_number": "+15551234567"
  },
  "event_id": "3f6b2ad0-1c9e-4a57-9f2b-8f6f0f9d2f11",
  "type": "telephony.incoming"
}

event_id je jedinečné pre každú odoslanú udalosť. Je rovnaké pri opakovaných pokusoch aj na každom koncovom bode, ktorý udalosť prijme — odstraňujte duplicity podľa neho.

Starší webhook s jednou adresou URL odosiela rovnaké type a data, ale bez event_id:

{
  "type": "telephony.incoming",
  "data": { "call_id": 987654321, "from_number": "+14155550199", "to_number": "+15551234567" }
}

Pri prenose je každé telo serializované kanonicky — kľúče sú zoradené abecedne, bez bielych znakov, v kódovaní UTF-8. Príklady s formátovaním v tejto dokumentácii slúžia len na lepšiu čitateľnosť.

Úplný zoznam typov udalostí a polí údajov nájdete v katalógu udalostí.

Overenie podpisu

Každá požiadavka obsahuje dva podpisy, oba HMAC-SHA256 s kľúčom secret koncového bodu (alebo vaším secret webhooku na úrovni organizácie pre staršie doručenia):

  • X-ThunderPhone-Signature-V2: t=<unix seconds>,v1=<hex> podpisuje časovú pečiatku, metódu, cestu a dopyt aj nespracované telo. Overte tento podpis a odmietnite požiadavky, ktorých t sa od vášho času líši o viac než 5 minút, aby zachytenú požiadavku nebolo možné neskôr znovu prehrať. Opakované pokusy sa pri odoslaní podpisujú znova.
  • X-ThunderPhone-Signature podpisuje iba nespracované telo. Stále sa odosiela nezmenený, aby existujúce overovače naďalej fungovali.

Kroky

  1. Prečítajte hlavičku, metódu, nespracovanú cestu a dopyt aj nespracované telo pred akýmkoľvek spracovaním.
  2. Vypočítajte hexadecimálny HMAC-SHA256 hodnoty <t>\n<METHOD>\n<path and query>\n<body> pomocou svojho tajného kľúča.
  3. Zamietnite požiadavku, ak sa t líši o viac než 300 sekúnd alebo ak sa výsledok nezhoduje s v1 pri porovnaní v konštantnom čase.

Telá sú kanonickou serializáciou JSON (zoradené kľúče, kompaktné oddeľovače) a podpisujeme presne tie bajty, ktoré prenášame. Sprievodca overením obsahuje presný podpisovaný reťazec, spracovaný príklad, kód bez SDK a staršiu hlavičku.

Python (Flask)
from flask import Flask, abort, request
from thunderphone import verify_signature
 
app = Flask(__name__)
 
@app.post("/thunderphone-webhook")
def handle():
    query = request.query_string.decode()
    if not verify_signature(
        request.headers.get("X-ThunderPhone-Signature-V2"),
        secret=WEBHOOK_SECRET,
        method=request.method,
        path=request.path + (f"?{query}" if query else ""),
        body=request.get_data(),  # raw bytes
    ):
        abort(401)
    event = request.get_json()
    # dispatch on event["type"] …
    return "", 204
Node.js (Express)
import express from "express";
import { verifySignature } from "@thunderphone/sdk";
 
const app = express();
app.post(
  "/thunderphone-webhook",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const ok = verifySignature({
      header: req.header("X-ThunderPhone-Signature-V2"),
      secret: process.env.WEBHOOK_SECRET,
      method: req.method,
      path: req.originalUrl,
      body: req.body,
    });
    if (!ok) return res.sendStatus(401);
    const event = JSON.parse(req.body.toString("utf8"));
    // dispatch on event.type …
    res.sendStatus(204);
  },
);

Sémantika doručovania

Tieto sémantiky sa vzťahujú na doručenia do koncového bodu. Starší webhook s jednou URL je jeden synchrónny pokus bez opakovaní, okrem výmeny konfigurácie telefonátu telephony.incoming, ktorá sa opakuje raz.

Opakovania

Každá udalosť sa ihneď odošle raz. Každá odpoveď 2xx potvrdzuje doručenie. Pri akomkoľvek inom výsledku (nie-2xx, chyba pripojenia, časový limit) pokus zopakujeme 1 m, 5 m, 30 m, 2 h, 6 h, 12 h a 24 h po prvom pokuse — celkovo 8 pokusov počas 24 hodín. Ak zlyhajú všetky pokusy, doručovanie sa zastaví a koncový bod sa vo webhookových koncových bodoch označí ako status="failing"; vlastníkom a správcom vašej organizácie odošleme e-mail a zobrazíme to na paneli. Vráťte 2xx hneď, ako je payload trvalo prijatý; spracujte ho asynchrónne. Testovacie odoslania z testovacieho API koncového bodu sa zopakujú raz približne minútu po prvom pokuse a nikdy nemenia stav koncového bodu.

Poradie

Poradie doručovania je založené na najlepšom úsilí. V praxi doručujeme udalosti v poradí, v akom sú emitované, ale opakovania môžu pri zlyhaní poradie zmeniť. Vždy deduplikujte a zosúlaďujte podľa call_id / id objektu.

Duplikáty

Doručovanie je aspoň raz: opakovanie po odpovedi, ktorú sme nevideli, môže udalosť duplikovať. Každé opakovanie obsahuje rovnaké event_id, preto ukladajte spracované identifikátory a preskakujte opakovania. event_id sa zdieľa aj medzi koncovými bodmi — dva koncové body prihlásené na odber rovnakej udalosti dostanú rovnaké event_id.

Časové limity

Doručenia do koncového bodu majú časový limit 30 s na každý pokus. V staršej ceste sú blokujúce požiadavky, ktoré riadia správanie prebiehajúceho hovoru — výmena konfigurácie telephony.incoming / web.incoming — obmedzené na 10 s pre prvý pokus telefonátu a 13 s pre celú výmenu vrátane jej jedného opakovania a na 10 s pre reláciu widgetu. Pomalá odpoveď oneskoruje prijatie hovoru, preto sa snažte odpovedať do niekoľkých sekúnd. V režime webhookov odosielanie nástrojov predvolene umožňuje 20 s a deklarácie nástrojov môžu nastaviť timeout na najvyššej úrovni.

Zdrojové IP adresy

Odchádzajúce webhooky pochádzajú z rozsahu cloudových IP adries ThunderPhone. Ak váš firewall vyžaduje zoznam povolených adries, kontaktujte podporu a poskytneme vám aktuálne rozsahy.

Výber medzi staršími webhookmi a webhookmi založenými na koncových bodoch

FunkciaStaršie (/v1/webhook)Koncové body (/v1/developer/webhook-endpoints)
Počet URL1 na organizáciuViac na organizáciu
Pokrytie udalostíIba telephony.* / web.*Všetkých 10 typov udalostí
Filter udalostí—Pre každý koncový bod
OpakovaniaŽiadne, okrem jedného pre výmenu konfigurácie telefonického hovoru8 pokusov počas 24 h
Obálkatype + datatype + data + event_id
Rotácia tajného kľúčaNahrádza jeden tajný kľúčTajný kľúč pre každý koncový bod
Zakázanie bez odstráneniaPUT /v1/webhook s {"url": ""}status=disabled
Viditeľnosť stavu—active / disabled / failing
Blokujúca výmena konfigurácieÁno (telephony.incoming / web.incoming)Nikdy — iba oznámenia
Najvhodnejšie preDynamickú konfiguráciu hovorovSpracovanie udalostí v produkcii

Nové integrácie by mali prijímať udalosti prostredníctvom webhookov založených na koncových bodoch. Staršiu adresu URL ponechajte (alebo pridajte) iba vtedy, ak konfigurujete hovory dynamicky pri ich prijatí alebo používate spúšťanie nástrojov v režime webhookov — tieto výmeny požiadaviek a odpovedí fungujú iba v staršej ceste.


Súvisiace