Webhookok áttekintése
Megtudhatja, hogyan kézbesíti a ThunderPhone a valós idejű eseményeket, hogyan ellenőrizheti az aláírásokat, és hogyan hasonlíthatók össze a régi és a végpont-alapú kézbesítési modellek.
ThunderPhone HTTP POST kéréseket küld az Ön szerverére, amikor egy hívás során
esemény történik — bejövő hívás indul, hívás ér véget, értékelési
futtatás fejeződik be, riasztás aktiválódik stb. Két kézbesítési
modell áll rendelkezésre:
Több URL, végpontonkénti titkok, végpontonkénti eseményszűrők
és automatikus újrapróbálkozások.
Kezelés: GET/POST/PATCH/DELETE /v1/developer/webhook-endpoints.
Szervezetenként egy URL. A hívás-életciklus eseményeit tartalmazza,
beleértve a blokkoló konfigurációs adatcseréket is. Kezelése:
GET/PUT /v1/webhook.
Az eseménykatalógusban szereplő mind a tíz eseménytípus
webhook-végpontokon keresztül kerül kézbesítésre. A hat hívás-életciklus
esemény (telephony.incoming, telephony.complete, telephony.tool,
web.incoming, web.complete, web.tool) szintén elküldésre kerül
a régi, egy URL-es webhooknak — ha régi URL-je és egyező végpontja is
van, az eseményt mindkét útvonalon megkapja. A blokkoló működés (a
telephony.incoming / web.incoming konfigurációs
adatcsere és a webhook módú
eszközindítás) kizárólag a régi
útvonalon érhető el; minden végpontkézbesítés küldés és továbblépés típusú
értesítés.
Hasznos teher formátuma
A végpontkézbesítések data, event_id és type mezőket tartalmazó
JSON-objektumok:
{
"data": {
"call_id": 987654321,
"from_number": "+14155550199",
"to_number": "+15551234567"
},
"event_id": "3f6b2ad0-1c9e-4a57-9f2b-8f6f0f9d2f11",
"type": "telephony.incoming"
}Az event_id minden kibocsátott eseményhez egyedi. Azonos az újrapróbálkozások
során és minden, az eseményt fogadó végponton — ennek alapján végezzen
duplikációszűrést.
A régi, egy URL-es webhook ugyanazt a type és data értéket küldi,
de event_id nélkül:
{
"type": "telephony.incoming",
"data": { "call_id": 987654321, "from_number": "+14155550199", "to_number": "+15551234567" }
}Átvitelkor minden törzs kanonikusan van szerializálva — a kulcsok ábécérendben szerepelnek, nincs szóköz, a kódolás UTF-8. A dokumentációban látható, formázott példák kizárólag az olvashatóságot szolgálják.
Az eseménytípusok és a hasznos teher mezőinek teljes listáját az Eseménykatalógusban találja.
Aláírás-ellenőrzés
Minden kérés HMAC-SHA256-aláírást tartalmaz a nyers kéréstörzsön
a X-ThunderPhone-Signature fejlécben. Az aláírókulcs a végpont
secret értéke (vagy régi kézbesítések esetén a szervezeti szintű webhook
secret értéke).
Lépések
- Bármilyen feldolgozás előtt olvassa be a nyers kéréstörzset.
- Számítsa ki a
hmac_sha256(secret, body).hexdigest()értékét. - Hasonlítsa össze konstans időben a
X-ThunderPhone-Signaturefejléccel.
Pontosan azokat a bájtokat írjuk alá, amelyeket továbbítunk, és ezek a kanonikus JSON-sorosítás bájtjai (rendezett kulcsok, tömör elválasztók). Ezért a nyers törzshöz viszonyított ellenőrzés mindig működik — és ha a keretrendszere csak feldolgozott JSON-t ad át, annak rendezett kulcsokkal és tömör elválasztókkal történő újrasorosítása azonos bájtokat eredményez. Mindkét módszert ismerteti az ellenőrzési útmutató.
import hmac
import hashlib
def verify_signature(body: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode("utf-8"),
body,
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(expected, signature or "")
# Example Flask handler
from flask import Flask, request, abort
app = Flask(__name__)
@app.post("/thunderphone-webhook")
def handle():
body = request.get_data()
sig = request.headers.get("X-ThunderPhone-Signature", "")
if not verify_signature(body, sig, WEBHOOK_SECRET):
abort(401)
event = request.get_json()
# dispatch on event["type"] …
return "", 204import crypto from "node:crypto";
import express from "express";
function verifySignature(body, signature, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(body)
.digest("hex");
if (!signature || expected.length !== signature.length) return false;
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature),
);
}
const app = express();
app.post(
"/thunderphone-webhook",
express.raw({ type: "application/json" }),
(req, res) => {
const sig = req.header("X-ThunderPhone-Signature") || "";
if (!verifySignature(req.body, sig, process.env.WEBHOOK_SECRET)) {
return res.sendStatus(401);
}
const event = JSON.parse(req.body.toString("utf8"));
// dispatch on event.type …
res.sendStatus(204);
},
);Kézbesítési szemantika
Ezek a szemantikák a végpontokra történő kézbesítésekre vonatkoznak. Az örökölt, egyetlen URL-es webhook egyetlen szinkron kísérletet használ, újrapróbálkozás nélkül.
Újrapróbálkozások
Minden eseményt azonnal egyszer megkísérlünk kézbesíteni. Bármely 2xx válasz
nyugtázza a kézbesítést. Minden egyéb esetben (nem 2xx,
kapcsolati hiba, időtúllépés) újrapróbálkozunk az első kísérlet után 1 perc, 5 perc, 30 perc, 2 óra, 6 óra,
12 óra és 24 óra elteltével — ez 8 kísérlet
24 órán belül. Ha minden kísérlet sikertelen, a kézbesítés leáll, és a végpont
status="failing" jelölést kap a
webhook-végpontoknál. Adjon vissza 2xx választ, amint
a hasznos adat tartósan fogadásra került; dolgozza fel aszinkron módon.
Sorrendiség
A kézbesítési sorrend csak legjobb szándék szerinti. A gyakorlatban az eseményeket
a kibocsátásuk sorrendjében kézbesítjük, de hibák esetén az újrapróbálkozások
megváltoztathatják a sorrendet. Mindig végezzen deduplikációt és egyeztetést call_id / objektumazonosító alapján.
Duplikátumok
A kézbesítés legalább egyszeri: egy általunk nem észlelt válasz utáni
újrapróbálkozás duplikálhat egy eseményt. Minden újrapróbálkozás ugyanazt az
event_id azonosítót tartalmazza, ezért tárolja a feldolgozott azonosítókat, és hagyja ki az ismétlődéseket. Az event_id
a végpontok között is megosztott — két, ugyanarra az
eseményre feliratkozott végpont ugyanazt az event_id azonosítót kapja.
Időtúllépések
A végpontokra történő kézbesítések időtúllépése kísérletenként 30 s. Az
örökölt útvonalon az élő hívási viselkedést vezérlő blokkoló kérések — a
telephony.incoming / web.incoming
konfigurációs adatcsere — 10 s után időtúllépnek, de a lassú
válasz késlelteti a hívás fogadását, ezért törekedjen néhány másodpercen
belüli válaszadásra. A webhook módú eszközhívás alapértelmezés szerint 20 s-ot
engedélyez, és az eszközdeklarációk felső szintű timeout értéket is megadhatnak.
Forrás IP-címek
A kimenő webhookok a ThunderPhone felhőbeli IP-tartományából származnak. Ha a tűzfala engedélyezési listát igényel, lépjen kapcsolatba a támogatással, és megosztjuk az aktuális tartományokat.
Választás az örökölt és a végpont-alapú webhookok között
| Funkció | Örökölt (/v1/webhook) | Végpontok (/v1/developer/webhook-endpoints) |
|---|---|---|
| URL-ek száma | 1 szervezetenként | Több szervezetenként |
| Eseménylefedettség | Csak telephony.* / web.* | Mind a 10 eseménytípus |
| Eseményszűrő | — | Végpontonként |
| Újrapróbálkozások | Nincs | 8 kísérlet 24 óra alatt |
| Boríték | type + data | type + data + event_id |
| Titok rotációja | Egyetlen titkot cserél | Végpontonkénti titok |
| Letiltás törlés nélkül | — | status=disabled |
| Állapot láthatósága | — | active / disabled / failing |
| Blokkoló konfigurációs adatcsere | Igen (telephony.incoming / web.incoming) | Soha — csak értesítések |
| Legjobb felhasználás | Dinamikus híváskonfiguráció | Események feldolgozása éles környezetben |
Az új integrációknak végpont-alapú webhookokon keresztül kell feldolgozniuk az eseményeket. Csak akkor tartson meg (vagy adjon hozzá) örökölt URL-t, ha a hívásokat dinamikusan konfigurálja a fogadáskor, vagy webhook módú eszközhívást használ — ezek a kérés/válasz adatcserék csak az örökölt útvonalon futnak.
Kapcsolódó tartalom
Az összes eseménytípus és hasznos adatuk.
Több végpont, eseményszűrő és titok kezelése.
A blokkoló kérés, amelyre a szerverének válaszolnia kell a hívások konfigurálásához.
Hívás utáni hasznos adat átirattal, felvétellel és mérőszámokkal.