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:

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

  1. Preberite neobdelano telo zahteve pred kakršnim koli razčlenjevanjem.
  2. Izračunajte hmac_sha256(secret, body).hexdigest().
  3. 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

FunkcijaPodedovani (/v1/webhook)Končne točke (/v1/developer/webhook-endpoints)
Število URL-jev1 na organizacijoVeč na organizacijo
Pokritost dogodkovSamo telephony.* / web.*Vseh 10 vrst dogodkov
Filter dogodkovZa posamezno končno točko
Ponovni poskusiBrez8 poskusov v 24 h
Ovojnicatype + datatype + data + event_id
Rotacija skrivnostiZamenja eno skrivnostSkrivnost za posamezno končno točko
Onemogočanje brez brisanjastatus=disabled
Vidnost stanjaactive / disabled / failing
Blokirajoča izmenjava konfiguracijeDa (telephony.incoming / web.incoming)Nikoli — samo obvestila
Najprimernejše zaDinamično konfiguracijo klicevPrejemanje 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