Open in
Pregled spletnih kljuk
Kako ThunderPhone dostavlja dogodke v realnem času, kako preveriti podpise ter kako se primerjata zastareli model dostave in model dostave, ki temelji na končnih točkah.
ThunderPhone pošlje zahteve HTTP POST vašemu strežniku, ko se med
klicem nekaj zgodi — začne se dohodni klic, klic se konča, ocenjevanje
se zaključi, sproži se opozorilo in podobno. Obstajata dva modela
dostave:
Več URL-jev, skrivnosti za posamezne končne točke, filtri dogodkov za posamezne končne točke
in samodejni ponovni poskusi.
Upravljajte prek GET/POST/PATCH/DELETE /v1/developer/webhook-endpoints.
En URL na organizacijo. Vsebuje dogodke življenjskega cikla klica, vključno z
blokirajočimi izmenjavami konfiguracije. Upravljajte prek GET/PUT /v1/webhook.
Vseh deset vrst dogodkov v katalogu dogodkov je
dostavljenih prek končnih točk webhookov. Šest dogodkov življenjskega cikla klica
(telephony.incoming, telephony.complete, telephony.tool,
web.incoming, web.complete, web.tool) je prav tako poslanih v
zastareli webhook z enim URL-jem — če imate zastareli URL in ujemajočo se
končno točko, dogodek prejmete po obeh poteh. Blokirajoče
vedenje ( izmenjava konfiguracije telephony.incoming / web.incoming in
odpošiljanje orodij v načinu webhook)
je na voljo izključno na zastareli poti; vsaka dostava v končno točko je
obvestilo brez čakanja na odgovor.
Oblika koristnega tovora
Dostave v končne točke so objekt JSON s polji data, event_id in
type:
{
"data": {
"call_id": 987654321,
"from_number": "+14155550199",
"to_number": "+15551234567"
},
"event_id": "3f6b2ad0-1c9e-4a57-9f2b-8f6f0f9d2f11",
"type": "telephony.incoming"
}event_id je edinstven za vsak poslan dogodek. Med ponovnimi poskusi je enak
in enak je za vsako končno točko, ki prejme dogodek — uporabite ga za
odstranjevanje dvojnikov.
Zastareli webhook z enim URL-jem pošlje enaka type in data, vendar
brez event_id:
{
"type": "telephony.incoming",
"data": { "call_id": 987654321, "from_number": "+14155550199", "to_number": "+15551234567" }
}Pri prenosu je vsako telo serijsko zapisano kanonično — ključi so razvrščeni po abecedi, brez presledkov, v UTF-8. Lepo oblikovani primeri v tej dokumentaciji so namenjeni zgolj berljivosti.
Za celoten seznam vrst dogodkov in polj koristnega tovora glejte katalog dogodkov.
Preverjanje podpisa
Vsaka zahteva vsebuje podpis HMAC-SHA256 nad surovim telesom
zahteve v glavi X-ThunderPhone-Signature. Podpisni ključ je secret
končne točke (ali secret spletnega kavlja na ravni vaše organizacije za
podedovane dostave).
Koraki
- Preberite surovo telo zahteve pred kakršnim koli razčlenjevanjem.
- Izračunajte
hmac_sha256(secret, body).hexdigest(). - V konstantnem času primerjajte z glavo
X-ThunderPhone-Signature.
Podpišemo natanko bajte, ki jih pošljemo, ti bajti pa so kanonična serializacija JSON (razvrščeni ključi, strnjena ločila). Zato preverjanje surovega telesa vedno deluje — in če vam vaše ogrodje posreduje samo razčlenjeni JSON, ponovna serializacija z razvrščenimi ključi in strnjenimi ločili ustvari enake bajte. Oba postopka sta opisana v vodniku za preverjanje.
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);
},
);Semantika dostave
Ta semantika velja za dostave v končno točko. Zastareli webhook z enim URL-jem je en sam sinhroni poskus brez ponovnih poskusov.
Ponovni poskusi
Vsak dogodek se takoj poskusi dostaviti enkrat. Vsak odgovor 2xx
potrdi dostavo. Pri katerem koli drugem izidu (ki ni 2xx,
napaka povezave, časovna omejitev) ponovno poskusimo 1 min, 5 min, 30 min, 2 h, 6 h,
12 h in 24 h po prvem poskusu — 8 poskusov v
24 urah. Če vsi poskusi ne uspejo, se dostava ustavi, končna točka
pa je v končnih točkah webhookov označena s
status="failing". Vrnite 2xx, takoj ko je koristni tovor
trajno sprejet; obdelajte ga asinhrono.
Vrstni red
Vrstni red dostave temelji na najboljšem možnem prizadevanju. V praksi dostavljamo v
vrstnem redu, v katerem so dogodki poslani, vendar lahko ponovni poskusi ob napaki
spremenijo vrstni red. Vedno odstranite podvojitve in uskladite podatke po call_id / ID-ju objekta.
Podvojitve
Dostava je vsaj enkratna: ponovni poskus po odgovoru, ki ga nismo
prejeli, lahko podvoji dogodek. Vsak ponovni poskus vsebuje isti
event_id, zato shranite obdelane ID-je in preskočite ponovitve. event_id se
deli tudi med končnimi točkami — dve končni točki, naročeni na isti
dogodek, prejmeta isti event_id.
Časovne omejitve
Dostave v končne točke imajo časovno omejitev 30 s za posamezen poskus. Na
zastareli poti se blokirajoče zahteve, ki usmerjajo vedenje klica v živo —
izmenjava konfiguracije telephony.incoming / web.incoming —
časovno omejijo po 10 s, vendar počasen odgovor zamakne prevzem klica,
zato si prizadevajte odgovoriti v nekaj sekundah. Odprema orodij v načinu webhook
privzeto omogoča 20 s, deklaracije orodij pa lahko nastavijo timeout na najvišji ravni.
Izvorni IP-naslovi
Odhodni webhooki izvirajo iz obsega IP-naslovov v oblaku ThunderPhone. Če vaš požarni zid zahteva seznam dovoljenih naslovov, se obrnite na podporo in posredovali vam bomo trenutne obsege.
Izbira med zastarelimi webhooki in webhooki na podlagi končnih točk
| Značilnost | Zastareli (/v1/webhook) | Končne točke (/v1/developer/webhook-endpoints) |
|---|---|---|
| Število URL-jev | 1 na organizacijo | Več na organizacijo |
| Pokritost dogodkov | Samo telephony.* / web.* | Vseh 10 vrst dogodkov |
| Filter dogodkov | — | Po končni točki |
| Ponovni poskusi | Brez | 8 poskusov v 24 h |
| Ovojnica | type + data | type + data + event_id |
| Menjava skrivnosti | Zamenja eno skrivnost | Skrivnost za posamezno končno točko |
| Onemogočanje brez brisanja | PUT /v1/webhook z {"url": ""} | status=disabled |
| Vidnost stanja | — | active / disabled / failing |
| Blokirajoča izmenjava konfiguracije | Da (telephony.incoming / web.incoming) | Nikoli — samo obvestila |
| Najprimernejše za | Dinamično konfiguracijo klicev | Prejemanje dogodkov v produkciji |
Nove integracije naj prejemajo dogodke prek webhookov na podlagi končnih točk. Zastareli URL obdržite (ali ga dodajte) samo, če klice dinamično konfigurirate ob prevzemu ali uporabljate odpošiljanje orodij v načinu webhook — te izmenjave zahtev in odgovorov se izvajajo samo na zastareli poti.
Povezano
Vse vrste dogodkov in njihovi koristni tovori.
Upravljajte več končnih točk, filtre dogodkov in skrivnosti.
Blokirajoča zahteva, na katero mora vaš strežnik odgovoriti za konfiguracijo klicev.
Koristni tovor po klicu s prepisom, posnetkom in meritvami.