Pregled spletnih kavljev
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, zaključi se postopek
ocenjevanja, sproži se opozorilo in podobno. Na voljo sta 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. Upravljate ga 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
podedovani webhook z enim URL-jem — če imate podedovani URL in ujemajočo se
končno točko, dogodek prejmete po obeh poteh. Blokirajoče
vedenje (izmenjava konfiguracije telephony.incoming / web.incoming
in pošiljanje orodij v
načinu webhook) je na voljo
izključno na podedovani poti; vsaka dostava na končno točko je obvestilo brez
čakanja na odgovor.
Oblika koristnega tovora
Dostave na 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 enoličen za vsak oddani dogodek. Pri ponovnih poskusih je enak
in enak na vseh končnih točkah, ki prejmejo dogodek — podvajanja odstranjujte na njegovi podlagi.
Podedovani 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 kanonično serializirano — ključi so razvrščeni po abecedi, brez presledkov, v UTF-8. Primeri v tej dokumentaciji so oblikovani za boljšo berljivost.
Za celoten seznam vrst dogodkov in polj koristnega tovora glejte katalog dogodkov.
Preverjanje podpisa
Vsaka zahteva vsebuje podpis HMAC-SHA256 nad neobdelanim telesom
zahteve v glavi X-ThunderPhone-Signature. Ključ za podpisovanje je
secret končne točke (ali secret spletnega kavlja na ravni vaše organizacije za podedovane
dostave).
Koraki
- Preberite neobdelano 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 z neobdelanim telesom vedno deluje — in če vam ogrodje posreduje le 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 "", 204
import 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čne točke. Podedovani webhook z enim URL-jem je en sam sinhron poskus brez ponovnih poskusov.
Ponovni poskusi
Vsak dogodek se takoj poskusi dostaviti enkrat. Vsak odgovor 2xx
potrdi dostavo. Ob katerem koli drugem izidu (ki ni 2xx,
napaka povezave, časovna omejitev) ponovno poskusimo po 1 min, 5 min, 30 min, 2 h, 6 h,
12 h in 24 h od prvega poskusa — 8 poskusov v obdobju
24 ur. Če vsi poskusi ne uspejo, se dostava ustavi in končna točka
v končnih točkah webhookov dobi oznako
status="failing". Čim prej vrnite 2xx, 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 oddajanja dogodkov, vendar lahko ponovni poskusi ob neuspehu 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 je
prav tako skupen 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 za vsak poskus časovno omejitev 30 s. Na
podedovani poti se blokirajoče zahteve, ki določajo vedenje klicev v živo — izmenjava
konfiguracije telephony.incoming / web.incoming —
prekinejo po 10 s, vendar počasen odgovor zakasni prevzem klica, zato
odgovorite v nekaj sekundah. Odpošiljanje orodij v načinu webhookov
orodij omogoča 20 s.
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 podedovanimi webhooki in webhooki na podlagi končnih točk
| Funkcija | Podedovani (/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 | — | Za posamezno končno točko |
| Ponovni poskusi | Brez | 8 poskusov v 24 h |
| Ovojnica | type + data | type + data + event_id |
| Rotacija skrivnosti | Zamenja eno skrivnost | Skrivnost za posamezno končno točko |
| Onemogočanje brez brisanja | — | 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. Podedovani URL obdržite (ali ga dodajte) le, če klice dinamično konfigurirate ob prevzemu ali uporabljate odpošiljanje orodij v načinu webhookov — te izmenjave zahtev in odgovorov se izvajajo samo po podedovani poti.
Sorodno
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.