Open in
Pregled webhookova
Kako ThunderPhone isporučuje događaje u stvarnom vremenu, kako provjeriti potpise i kako se uspoređuju naslijeđeni modeli isporuke i modeli isporuke temeljeni na krajnjim točkama.
ThunderPhone šalje HTTP POST zahtjeve na Vaš poslužitelj kada se tijekom poziva
dogode određene radnje — započne dolazni poziv, poziv završi, dovrši se
pokretanje ocjenjivanja, aktivira se upozorenje i slično. Postoje dva modela
isporuke:
Više URL-ova, tajne po krajnjoj točki, filtri događaja po krajnjoj točki
i automatski ponovni pokušaji.
Upravljajte putem GET/POST/PATCH/DELETE /v1/developer/webhook-endpoints.
Jedan URL po organizaciji. Prenosi događaje životnog ciklusa poziva, uključujući
blokirajuće razmjene konfiguracije. Njime se upravlja putem GET/PUT /v1/webhook.
Sve navedene vrste događaja u katalogu događaja
isporučuju se putem krajnjih točaka webhooka. Šest događaja životnog ciklusa poziva
(telephony.incoming, telephony.complete, telephony.tool,
web.incoming, web.complete, web.tool) također se šalje na
zastarjeli webhook s jednim URL-om — ako imate i zastarjeli URL i
odgovarajuću krajnju točku, događaj primate na obje putanje. Blokirajuće
ponašanje (razmjena konfiguracije za telephony.incoming / web.incoming
i otprema alata u načinu rada webhooka)
dostupno je isključivo na zastarjeloj putanji; svaka isporuka na krajnju točku
obavijest je bez čekanja odgovora.
Format sadržaja
Isporuke na krajnju točku JSON su objekt s poljima data, event_id i
type:
{
"data": {
"call_id": 987654321,
"from_number": "+14155550199",
"to_number": "+15551234567"
},
"event_id": "3f6b2ad0-1c9e-4a57-9f2b-8f6f0f9d2f11",
"type": "telephony.incoming"
}event_id je jedinstven za svaki emitirani događaj. Jednak je pri ponovnim pokušajima
i na svakoj krajnjoj točki koja primi događaj — upotrijebite ga za uklanjanje duplikata.
Zastarjeli webhook s jednim URL-om šalje isti type i data, ali
bez polja event_id:
{
"type": "telephony.incoming",
"data": { "call_id": 987654321, "from_number": "+14155550199", "to_number": "+15551234567" }
}Pri prijenosu se svako tijelo kanonski serijalizira — ključevi su poredani abecedno, bez razmaka, u UTF-8 formatu. Primjeri s uvlačenjem u ovoj dokumentaciji služe samo radi čitljivosti.
Pogledajte Katalog događaja za potpuni popis vrsta događaja i polja sadržaja.
Provjera potpisa
Svaki zahtjev sadrži dva potpisa, oba HMAC-SHA256 s ključem secret
krajnje točke (ili vašim secret ključem webhooka na razini organizacije za naslijeđene
isporuke):
X-ThunderPhone-Signature-V2: t=<unix seconds>,v1=<hex>potpisuje vremensku oznaku, metodu, putanju i upit te sirovo tijelo. Provjerite ovaj potpis i odbijte zahtjeve čiji jetudaljen više od 5 minuta od vašeg sata kako se presretnuti zahtjev kasnije ne bi mogao ponovno poslati. Ponovni pokušaji ponovno se potpisuju kada se pošalju.X-ThunderPhone-Signaturepotpisuje samo sirovo tijelo. I dalje se šalje nepromijenjen kako bi postojeći alati za provjeru nastavili raditi.
Koraci
- Pročitajte zaglavlje, metodu, neobrađenu putanju i upit te neobrađeno tijelo prije bilo kakve obrade.
- Izračunajte heksadecimalni HMAC-SHA256 za
<t>\n<METHOD>\n<path and query>\n<body>pomoću svoje tajne. - Odbijte zahtjev ako
todstupa više od 300 sekundi ili ako se rezultat ne podudara sv1pri usporedbi u konstantnom vremenu.
Tijela su kanonska JSON serializacija (sortirani ključevi, sažeti razdjelnici), a potpisujemo točno bajtove koje prenosimo. Vodič za provjeru sadrži točan potpisani niz, obrađeni primjer, kôd bez SDK-a i naslijeđeno zaglavlje.
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 "", 204import 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);
},
);Semantika isporuke
Ova se semantika primjenjuje na isporuke krajnjim točkama. Naslijeđeni
webhook s jednim URL-om jedan je sinkroni pokušaj bez ponovnih pokušaja, osim
razmjene konfiguracije za telefonski poziv
telephony.incoming,
koja se ponavlja jednom.
Ponovni pokušaji
Svaki se događaj odmah pokušava isporučiti jednom. Svaki odgovor 2xx
potvrđuje isporuku. U svakom drugom slučaju (odgovor koji nije 2xx,
pogreška veze, istek vremena) ponavljamo pokušaj 1 m, 5 m, 30 m, 2 h, 6 h,
12 h i 24 h nakon prvog pokušaja — ukupno 8 pokušaja tijekom
24 sata. Ako svaki pokušaj ne uspije, isporuka se zaustavlja, a krajnja točka
označava se s status="failing" u
webhook krajnjim točkama; e-poštom obavještavamo
vlasnike i administratore vaše organizacije te to prikazujemo na nadzornoj ploči.
Vratite 2xx čim se teret trajno prihvati; obradite ga asinkrono.
Testna slanja iz API-ja za testiranje krajnje točke dobivaju jedan ponovni pokušaj otprilike minutu nakon
prvog pokušaja i nikad ne mijenjaju status krajnje točke.
Redoslijed
Redoslijed isporuke temelji se na najboljem nastojanju. U praksi isporučujemo prema
redoslijedu emitiranja događaja, ali ponovni pokušaji mogu promijeniti redoslijed nakon neuspjeha.
Uvijek uklonite duplikate i uskladite prema call_id / ID-u objekta.
Duplikati
Isporuka je najmanje jednom: ponovni pokušaj nakon odgovora koji nikada
nismo vidjeli može duplicirati događaj. Svaki ponovni pokušaj nosi isti
event_id, stoga pohranite obrađene ID-jeve i preskočite ponavljanja. event_id se
također dijeli među krajnjim točkama — dvije krajnje točke pretplaćene na isti
događaj primaju isti event_id.
Istek vremena
Isporuke krajnjim točkama imaju istek vremena od 30 s po pokušaju. Na
naslijeđenoj putanji, blokirajući zahtjevi koji upravljaju ponašanjem poziva uživo —
razmjena konfiguracije
telephony.incoming / web.incoming
— ograničeni su na 10 s za prvi pokušaj telefonskog poziva i 13 s
za cijelu razmjenu, uključujući jedan ponovni pokušaj, te na 10 s za sesiju
widgeta. Spor odgovor odgađa preuzimanje poziva, stoga nastojte odgovoriti u roku od nekoliko sekundi. Slanje alata u načinu rada webhooka
prema zadanim postavkama dopušta 20 s, a deklaracije alata mogu postaviti timeout na najvišoj razini.
Izvorne IP adrese
Izlazni webhookovi dolaze iz ThunderPhoneova raspona IP adresa u oblaku. Ako vaš vatrozid zahtijeva popis dopuštenih adresa, obratite se podršci i podijelit ćemo trenutačne raspone.
Odabir između naslijeđenih webhookova i webhookova temeljenih na krajnjim točkama
| Značajka | Naslijeđeni (/v1/webhook) | Krajnje točke (/v1/developer/webhook-endpoints) |
|---|---|---|
| Broj URL-ova | 1 po organizaciji | Više po organizaciji |
| Obuhvat događaja | samo telephony.* / web.* | Svih 10 vrsta događaja |
| Filtar događaja | — | Po krajnjoj točki |
| Ponovni pokušaji | Nema, osim jednoga za razmjenu konfiguracije telefonskog poziva | 8 pokušaja tijekom 24 h |
| Omotnica | type + data | type + data + event_id |
| Rotacija tajne | Zamjenjuje jednu tajnu | Tajna po krajnjoj točki |
| Onemogućavanje bez brisanja | PUT /v1/webhook s {"url": ""} | status=disabled |
| Vidljivost statusa | — | active / disabled / failing |
| Blokirajuća razmjena konfiguracije | Da (telephony.incoming / web.incoming) | Nikada — samo obavijesti |
| Najbolje za | Dinamičku konfiguraciju poziva | Primanje događaja u produkciji |
Nove integracije trebaju primati događaje putem webhookova temeljenih na krajnjim točkama. Zadržite (ili dodajte) naslijeđeni URL samo ako konfigurirate pozive dinamički u trenutku javljanja ili upotrebljavate slanje alata u načinu rada webhooka — te se razmjene zahtjeva i odgovora izvršavaju samo na naslijeđenoj putanji.
Povezano
Sve vrste događaja i njihovi podaci.
Upravljajte višestrukim krajnjim točkama, filtrima događaja i tajnama.
Blokirajući zahtjev na koji Vaš poslužitelj mora odgovoriti kako bi konfigurirao pozive.
Podaci nakon poziva s transkriptom, snimkom i metrikama.