Open in
Webhookide ülevaade
Kuidas ThunderPhone edastab reaalajas sündmusi, kuidas allkirju kontrollida ning kuidas võrrelda pärand- ja lõpp-punktil põhinevaid edastusmudeleid.
ThunderPhone saadab sinu serverile HTTP POST päringuid, kui kõne ajal midagi
juhtub — sissetulev kõne algab, kõne lõpeb, hindamisprotsess lõpeb,
käivitub hoiatus jne. Saadaval on kaks edastusmudelit:
Mitu URL-i, lõpp-punktipõhised saladused, lõpp-punktipõhised sündmusefiltrid
ja automaatsed korduskatsed.
Halda kaudu GET/POST/PATCH/DELETE /v1/developer/webhook-endpoints.
Üks URL organisatsiooni kohta. Sisaldab kõne elutsükli sündmusi, sealhulgas
blokeerivaid konfiguratsioonivahetusi. Hallatakse kaudu GET/PUT /v1/webhook.
Kõik kümme sündmuste kataloogis olevat sündmusetüüpi
edastatakse veebikonksu lõpp-punktide kaudu. Kuus kõne elutsükli sündmust
(telephony.incoming, telephony.complete, telephony.tool,
web.incoming, web.complete, web.tool) saadetakse samuti
ühe URL-iga pärandveebikonksu kaudu — kui sul on nii pärand-URL kui ka
sobiv lõpp-punkt, saad sündmuse mõlemale teele. Blokeeriv käitumine
(telephony.incoming / web.incoming konfiguratsioonivahetus ja veebikonksurežiimi
tööriista väljakutse) on ainult
pärandteel; iga lõpp-punkti edastus on teavitus, mis ei oota vastust.
Andmevorming
Lõpp-punkti edastused on JSON-objektid väljadega data, event_id ja
type:
{
"data": {
"call_id": 987654321,
"from_number": "+14155550199",
"to_number": "+15551234567"
},
"event_id": "3f6b2ad0-1c9e-4a57-9f2b-8f6f0f9d2f11",
"type": "telephony.incoming"
}event_id on iga väljastatud sündmuse jaoks kordumatu. See on sama nii
korduskatsete kui ka iga sündmuse saanud lõpp-punkti puhul — kasuta seda duplikaatide eemaldamiseks.
Ühe URL-iga pärandveebikonks saadab sama type ja data, kuid
ilma event_id-ta:
{
"type": "telephony.incoming",
"data": { "call_id": 987654321, "from_number": "+14155550199", "to_number": "+15551234567" }
}Võrgus serialiseeritakse iga sisu kanooniliselt — võtmed sorditakse tähestikulises järjekorras, tühikuid pole, kodeering on UTF-8. Nendes dokumentides olevad vormindatud näited on ainult loetavuse huvides.
Täieliku sündmusetüüpide ja andmeväljade loendi leiad sündmuste kataloogist.
Allkirja kontrollimine
Iga päring sisaldab päises X-ThunderPhone-Signature HMAC-SHA256 allkirja, mis on arvutatud toorpäringu
sisust. Allkirjastamisvõti on lõpp-punkti secret (või pärand-edastuste korral sinu organisatsioonitaseme veebikonksu secret).
Sammud
- Loe toorpäringu sisu enne mis tahes parsimist.
- Arvuta
hmac_sha256(secret, body).hexdigest(). - Võrdle tulemust konstantse ajaga päisega
X-ThunderPhone-Signature.
Allkirjastame täpselt need baidid, mida edastame, ning need baidid on kanoniseeritud JSON-i serialiseering (sorditud võtmed, kompaktsed eraldajad). Seega töötab kontrollimine toorsisu alusel alati — ja kui sinu raamistik annab sulle ainult parsitud JSON-i, tekitab selle uuesti serialiseerimine sorditud võtmete ja kompaktsete eraldajatega identsed baidid. Mõlemat meetodit käsitletakse kontrollimise juhendis.
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);
},
);Edastamise semantika
Need semantikad kehtivad lõpp-punkti edastustele. Pärandne ühe URL-iga veebikonks teeb ühe sünkroonse katse ilma korduskatseteta.
Korduskatsed
Iga sündmust proovitakse kohe üks kord edastada. Mis tahes 2xx vastus
kinnitab edastuse. Mis tahes muu tulemuse korral (mitte-2xx,
ühenduse viga, ajalõpp) proovime uuesti 1 min, 5 min, 30 min, 2 h, 6 h,
12 h ja 24 h pärast esimest katset — 8 katset 24 tunni jooksul.
Kui kõik katsed ebaõnnestuvad, edastamine peatub ja lõpp-punkt
märgitakse olekuga status="failing"
veebikonksu lõpp-punktides. Tagasta 2xx kohe,
kui andmekoormus on püsivalt vastu võetud; töötle seda asünkroonselt.
Järjestus
Edastamise järjestus on parima võimaliku pingutuse põhine. Praktikas
edastame sündmused nende väljastamise järjekorras, kuid ebaõnnestumise
korral võivad korduskatsed järjekorda muuta. Eemalda alati duplikaadid ja
ühtlusta andmed call_id / objekti ID alusel.
Duplikaadid
Edastamine toimub vähemalt üks kord: korduskatse pärast vastust,
mida me ei näinud, võib sündmuse dubleerida. Iga korduskatse sisaldab sama
event_id, seega salvesta töödeldud ID-d ja jäta kordused vahele. event_id
on ühine ka lõpp-punktide vahel — kaks sama sündmust tellinud lõpp-punkti
saavad sama event_id.
Ajalõpud
Lõpp-punkti edastustel on iga katse kohta 30 s ajalimiit. Pärandteel
aeguvad reaalajas kõnekäitumist mõjutavad blokeerivad päringud —
telephony.incoming / web.incoming
konfiguratsioonivahetus — 10 s pärast, kuid aeglane vastus lükkab
kõnele vastamist edasi, seega püüa vastata paari sekundi jooksul.
Veebikonksurežiimis tööriista väljakutsumine lubab
vaikimisi 20 s ning tööriista deklaratsioonid võivad määrata tipptaseme
timeout.
Lähte-IP-d
Väljuvad veebikonksud pärinevad ThunderPhone'i pilve IP-vahemikust. Kui sinu tulemüür nõuab lubatud loendit, võta ühendust toega ja jagame praeguseid vahemikke.
Valimine pärandsete ja lõpp-punktipõhiste veebikonksude vahel
| Funktsioon | Pärand (/v1/webhook) | Lõpp-punktid (/v1/developer/webhook-endpoints) |
|---|---|---|
| URL-ide arv | 1 organisatsiooni kohta | Mitu organisatsiooni kohta |
| Sündmuste katvus | ainult telephony.* / web.* | Kõik 10 sündmusetüüpi |
| Sündmuste filter | — | Lõpp-punkti kaupa |
| Korduskatsed | Puuduvad | 8 katset 24 h jooksul |
| Ümbris | type + data | type + data + event_id |
| Saladuse roteerimine | Asendab ühe saladuse | Lõpp-punkti saladus |
| Keelamine kustutamata | PUT /v1/webhook koos {"url": ""} | status=disabled |
| Oleku nähtavus | — | active / disabled / failing |
| Blokeeriv konfiguratsioonivahetus | Jah (telephony.incoming / web.incoming) | Mitte kunagi — ainult teavitused |
| Sobib kõige paremini | Dünaamiline kõnede konfigureerimine | Sündmuste töötlemine tootmises |
Uued integratsioonid peaksid sündmusi vastu võtma lõpp-punktipõhiste veebikonksude kaudu. Hoia (või lisa) pärand-URL ainult siis, kui konfigureerid kõnesid dünaamiliselt kõnele vastamise ajal või kasutad veebikonksurežiimis tööriista väljakutsumist — need päringu/vastuse vahetused toimivad ainult pärandteel.
Seotud
Kõik sündmusetüübid ja nende andmekoormused.
Halda mitut lõpp-punkti, sündmuste filtreid ja saladusi.
Blokeeriv päring, millele sinu server peab kõnede konfigureerimiseks vastama.
Kõnejärgne andmekoormus koos transkriptsiooni, salvestise ja mõõdikutega.