ThunderPhone 2.0 on nüüd saadaval.Iseteenindusena alates 2 senti/min.Loe uudist

Webhooks

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:

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

  1. Loe toorpäringu sisu enne mis tahes parsimist.
  2. Arvuta hmac_sha256(secret, body).hexdigest().
  3. 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.

Python
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
Node.js (Express)
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);
  },
);

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

FunktsioonPärand (/v1/webhook)Lõpp-punktid (/v1/developer/webhook-endpoints)
URL-ide arv1 organisatsiooni kohtaMitu organisatsiooni kohta
Sündmuste katvusainult telephony.* / web.*Kõik 10 sündmusetüüpi
Sündmuste filterLõpp-punkti kaupa
KorduskatsedPuuduvad8 katset 24 h jooksul
Ümbristype + datatype + data + event_id
Saladuse roteerimineAsendab ühe saladuseLõpp-punkti saladus
Keelamine kustutamataPUT /v1/webhook koos {"url": ""}status=disabled
Oleku nähtavusactive / disabled / failing
Blokeeriv konfiguratsioonivahetusJah (telephony.incoming / web.incoming)Mitte kunagi — ainult teavitused
Sobib kõige pareminiDünaamiline kõnede konfigureerimineSü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