Open in
Oversikt over webhooks
Slik leverer ThunderPhone hendelser i sanntid, slik verifiserer du signaturer, og slik sammenlignes de eldre og endepunktbaserte leveringsmodellene.
ThunderPhone sender HTTP-POST-forespørsler til serveren din når ting
skjer under en samtale — et innkommende anrop starter, en samtale avsluttes, en vurderingskjøring fullføres, et varsel utløses og så videre. Det finnes to leveringsmodeller:
Flere URL-er, hemmeligheter per endepunkt, hendelsesfiltre per endepunkt
og automatiske nye forsøk.
Administrer via GET/POST/PATCH/DELETE /v1/developer/webhook-endpoints.
Én URL per organisasjon. Inneholder hendelsene i samtalens livssyklus, inkludert de
blokkerende konfigurasjonsutvekslingene. Administreres på GET/PUT /v1/webhook.
Alle oppførte hendelsestyper i hendelseskatalogen
leveres gjennom webhook-endepunkter. De seks hendelsene i samtalens livssyklus
(telephony.incoming, telephony.complete, telephony.tool,
web.incoming, web.complete, web.tool) sendes også til den
eldre webhooken med én URL — hvis du har både en eldre URL og et
matchende endepunkt, mottar du hendelsen på begge banene. Blokkerende
atferd (telephony.incoming- / web.incoming-konfigurasjonsutvekslingen og
verktøysdistribusjon i webhook-modus) finnes
utelukkende på den eldre banen; hver levering til et endepunkt er en
fire-and-forget-varsling.
Nyttelastformat
Leveringer til endepunkter er et JSON-objekt med data, event_id og
type:
{
"data": {
"call_id": 987654321,
"from_number": "+14155550199",
"to_number": "+15551234567"
},
"event_id": "3f6b2ad0-1c9e-4a57-9f2b-8f6f0f9d2f11",
"type": "telephony.incoming"
}event_id er unik for hver utsendte hendelse. Den er identisk på tvers av nye forsøk
og på tvers av hvert endepunkt som mottar hendelsen — dedupliser på den.
Den eldre webhooken med én URL sender samme type og data, men
uten event_id:
{
"type": "telephony.incoming",
"data": { "call_id": 987654321, "from_number": "+14155550199", "to_number": "+15551234567" }
}På nettverket serialiseres hver body kanonisk — nøkler sortert alfabetisk, ingen mellomrom, UTF-8. Eksemplene med pen formatering i denne dokumentasjonen er kun for lesbarhet.
Se hendelseskatalogen for hele listen over hendelses- typer og nyttelastfelt.
Signaturverifisering
Hver forespørsel har to signaturer, begge HMAC-SHA256 med endepunktets
secret som nøkkel (eller webhookens secret på organisasjonsnivå for eldre
leveringer):
X-ThunderPhone-Signature-V2: t=<unix seconds>,v1=<hex>signerer tidsstempelet, metoden, banen og spørringen samt råteksten. Verifiser denne, og avvis forespørsler dertavviker med mer enn 5 minutter fra klokken din, slik at en oppfanget forespørsel ikke kan spilles av på nytt senere. Nye forsøk signeres på nytt når de sendes.X-ThunderPhone-Signaturesignerer bare råteksten. Den sendes fortsatt uendret, slik at eksisterende verifiseringsprogrammer fortsetter å fungere.
Trinn
- Les headeren, metoden, den rå stien og spørringen samt den rå brødteksten før eventuell parsing.
- Beregn den heksadesimale HMAC-SHA256-verdien av
<t>\n<METHOD>\n<path and query>\n<body>med hemmeligheten din. - Avvis forespørselen hvis
tavviker med mer enn 300 sekunder, eller hvis resultatet ikke samsvarer medv1i en sammenligning med konstant tid.
Brødtekster er den kanoniske JSON-serialiseringen (sorterte nøkler, kompakte skilletegn), og vi signerer nøyaktig byteverdiene vi overfører. Veiledningen for verifisering inneholder den nøyaktige signerte strengen, et gjennomarbeidet eksempel, kode uten SDK-en og den eldre headeren.
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);
},
);Leveringssemantikk
Disse semantikkene gjelder leveringer til endepunkt. Den eldre webhooken med én URL
er ett synkront forsøk uten gjenforsøk, med unntak av
konfigurasjonsutvekslingen for telefonsamtaler
telephony.incoming,
som forsøkes på nytt én gang.
Gjenforsøk
Hver hendelse forsøkes levert umiddelbart én gang. Ethvert 2xx-svar
bekrefter leveringen. Ved ethvert annet utfall (ikke-2xx,
tilkoblingsfeil, tidsavbrudd) prøver vi på nytt etter 1 min, 5 min, 30 min, 2 t, 6 t,
12 t og 24 t etter første forsøk — 8 forsøk fordelt over
24 timer. Hvis alle forsøk mislykkes, stopper leveringen, og endepunktet
merkes med status="failing" i
webhook-endepunkter; vi sender e-post til eierne
og administratorene i organisasjonen din og viser det i dashbordet. Returner 2xx så snart
nyttelasten er mottatt og lagret varig; behandle den asynkront.
Testforsendelser fra endepunktets test-API får ett gjenforsøk omtrent ett minutt etter
første forsøk og endrer aldri endepunktets status.
Rekkefølge
Leveringsrekkefølgen er etter beste evne. I praksis leverer vi i
rekkefølgen hendelser sendes ut, men nye forsøk kan endre rekkefølgen ved feil.
Dedupliser og avstem alltid etter call_id / objekt-ID.
Duplikater
Levering er minst én gang: et nytt forsøk etter et svar vi aldri
mottok, kan duplisere en hendelse. Hvert nye forsøk har samme
event_id, så lagre behandlede ID-er og hopp over gjentakelser. event_id er
også delt på tvers av endepunkter — to endepunkter som abonnerer på den
samme hendelsen, mottar samme event_id.
Tidsavbrudd
Leveringer til endepunkter har et tidsavbrudd på 30 s per forsøk. På den
eldre ruten er blokkerende forespørsler som styrer oppførselen til aktive samtaler —
konfigurasjonsutvekslingen
telephony.incoming / web.incoming —
begrenset til 10 s for en telefonsamtales
første forsøk og 13 s for hele utvekslingen, inkludert det ene
gjenforsøket, og til 10 s for en widgetøkt. Et tregt svar forsinker
besvarelsen av samtalen, så sikt mot å svare innen et par sekunder. Utsending av verktøykall i webhook-modus tillater 20 s
som standard, og verktøydeklarasjoner kan angi et overordnet timeout.
Kilde-IP-er
Utgående webhooks kommer fra ThunderPhones sky-IP-område. Hvis brannmuren din krever en tillatelsesliste, kontakt kundestøtte, så deler vi de gjeldende intervallene.
Velge mellom eldre og endepunktbaserte webhooks
| Funksjon | Eldre (/v1/webhook) | Endepunkter (/v1/developer/webhook-endpoints) |
|---|---|---|
| Antall URL-er | 1 per organisasjon | Mange per organisasjon |
| Hendelsesdekning | Kun telephony.* / web.* | Alle 10 hendelsestyper |
| Hendelsesfilter | — | Per endepunkt |
| Nye forsøk | Ingen, unntatt ett for utveksling av telefonanropskonfigurasjon | 8 forsøk over 24 t |
| Konvolutt | type + data | type + data + event_id |
| Rotering av hemmelighet | Erstatter én hemmelighet | Hemmelighet per endepunkt |
| Deaktiver uten å slette | PUT /v1/webhook med {"url": ""} | status=disabled |
| Statustilgjengelighet | — | active / disabled / failing |
| Blokkerende konfigurasjonsutveksling | Ja (telephony.incoming / web.incoming) | Aldri — kun varsler |
| Best for | Dynamisk anropskonfigurasjon | Hendelsesmottak i produksjon |
Nye integrasjoner bør motta hendelser gjennom endepunktbaserte webhooks. Behold (eller legg til) en eldre URL bare hvis du konfigurerer samtaler dynamisk når de besvares, eller bruker verktøysdirigering i webhook-modus — disse forespørsels-/svarutvekslingene kjører bare på den eldre ruten.
Relatert
Alle hendelsestyper og nyttelastene deres.
Administrer flere endepunkter, hendelsesfiltre og hemmeligheter.
Den blokkerende forespørselen serveren din må svare på for å konfigurere samtaler.
Nyttelast etter samtalen med transkripsjon, opptak og beregninger.