ThunderPhone 2.0 ir klāt.Sāciet patstāvīgi — no 2 ¢/min.Lasīt paziņojumu

Webhooks

Tīmekļa aizķeru pārskats

Kā ThunderPhone piegādā reāllaika notikumus, kā pārbaudīt parakstus un kā salīdzināmi mantotais un galapunktos balstītais piegādes modelis.

ThunderPhone nosūta HTTP POST pieprasījumus uz jūsu serveri, kad zvana laikā notiek kāds notikums — sākas ienākošs zvans, beidzas zvans, tiek pabeigta novērtēšanas izpilde, tiek aktivizēts brīdinājums un tā tālāk. Ir divi piegādes modeļi:

Visi notikumu katalogā uzskaitītie notikumu tipi tiek piegādāti, izmantojot tīmekļa aizķeres galapunktus. Seši zvana dzīves cikla notikumi (telephony.incoming, telephony.complete, telephony.tool, web.incoming, web.complete, web.tool) tiek nosūtīti arī uz mantoto tīmekļa aizķeri ar vienu URL — ja jums ir gan mantotais URL, gan atbilstošs galapunkts, jūs saņemat notikumu pa abiem ceļiem. Bloķējoša darbība ( telephony.incoming / web.incoming konfigurācijas apmaiņa un tīmekļa aizķeres režīma rīku nosūtīšana) ir pieejama tikai mantotajā ceļā; katra piegāde uz galapunktu ir paziņojums bez atbildes gaidīšanas.

Lietderīgās slodzes formāts

Piegādes uz galapunktiem ir JSON objekts ar data, event_id un type:

{
  "data": {
    "call_id": 987654321,
    "from_number": "+14155550199",
    "to_number": "+15551234567"
  },
  "event_id": "3f6b2ad0-1c9e-4a57-9f2b-8f6f0f9d2f11",
  "type": "telephony.incoming"
}

event_id ir unikāls katram izsūtītajam notikumam. Tas ir identisks atkārtotos mēģinājumos un visos galapunktos, kas saņem notikumu — izmantojiet to dublikātu novēršanai.

Mantotā tīmekļa aizķere ar vienu URL nosūta to pašu type un data, bet bez event_id:

{
  "type": "telephony.incoming",
  "data": { "call_id": 987654321, "from_number": "+14155550199", "to_number": "+15551234567" }
}

Pārsūtē katrs pamatteksts tiek seriālizēts kanoniski — atslēgas ir sakārtotas alfabētiski, bez atstarpēm, UTF-8. Šajā dokumentācijā glīti formatētie piemēri ir paredzēti tikai lasāmībai.

Pilnu notikumu tipu un lietderīgās slodzes lauku sarakstu skatiet notikumu katalogā.

Paraksta verifikācija

Katram pieprasījumam ir divi paraksti — abi ir HMAC-SHA256 paraksti, kas veidoti ar galapunkta secret (vai jūsu organizācijas līmeņa tīmekļa aizķeres secret mantotajām piegādēm):

  • X-ThunderPhone-Signature-V2: t=<unix seconds>,v1=<hex> paraksta laikspiedolu, metodi, ceļu un vaicājumu, kā arī neapstrādāto pamattekstu. Verificējiet šo parakstu un noraidiet pieprasījumus, kuru t no jūsu sistēmas laika atšķiras vairāk nekā 5 minūtes, lai pārtvertu pieprasījumu vēlāk nevarētu atkārtoti nosūtīt. Atkārtoti mēģinājumi tiek parakstīti no jauna, kad tie tiek nosūtīti.
  • X-ThunderPhone-Signature paraksta tikai neapstrādāto pamattekstu. Tas joprojām tiek nosūtīts nemainīts, lai esošie verificētāji turpinātu darboties.

Darbības

  1. Pirms jebkādas parsēšanas nolasiet galveni, metodi, neapstrādāto ceļu un vaicājumu, kā arī neapstrādāto pamattekstu.
  2. Izmantojot savu slepeno atslēgu, aprēķiniet heksadecimālo HMAC-SHA256 vērtību <t>\n<METHOD>\n<path and query>\n<body>.
  3. Noraidiet pieprasījumu, ja t atšķiras par vairāk nekā 300 sekundēm vai ja rezultāts nemainīga laika salīdzinājumā neatbilst v1.

Pamatteksti ir kanoniskā JSON serializācija (sakārtotas atslēgas, kompakti atdalītāji), un mēs parakstām tieši tos baitus, kurus nosūtām. Verifikācijas ceļvedī ir precīza parakstītā virkne, izstrādāts piemērs, kods bez SDK un mantotā galvene.

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

Piegādes semantika

Šī semantika attiecas uz piegādēm uz galapunktu. Mantotā tīmekļa aizķere ar vienu URL ir viens sinhrons mēģinājums bez atkārtotiem mēģinājumiem, izņemot tālruņa zvana telephony.incoming konfigurācijas apmaiņu, kas tiek atkārtota vienu reizi.

Atkārtoti mēģinājumi

Katru notikumu nekavējoties mēģina piegādāt vienu reizi. Jebkura 2xx atbilde apstiprina piegādi. Jebkurā citā gadījumā (ne-2xx atbilde, savienojuma kļūda, noildze) mēs mēģinām vēlreiz pēc 1 minūtes, 5 minūtēm, 30 minūtēm, 2 stundām, 6 stundām, 12 stundām un 24 stundām pēc pirmā mēģinājuma — kopā 8 mēģinājumi 24 stundu laikā. Ja neizdodas visi mēģinājumi, piegāde tiek pārtraukta un galapunkts tiek atzīmēts ar status="failing" sadaļā tīmekļa aizķeru galapunkti; mēs nosūtām e-pastu jūsu organizācijas īpašniekiem un administratoriem un parādām to vadības panelī. Atgrieziet 2xx, tiklīdz datu saturs ir droši pieņemts; apstrādājiet to asinhroni. Testa sūtījumiem no galapunkta testēšanas API aptuveni minūti pēc pirmā mēģinājuma tiek veikts viens atkārtots mēģinājums, un tie nekad nemaina galapunkta statusu.

Secība

Piegādes secība tiek nodrošināta pēc iespējas. Praksē mēs piegādājam notikumus to izraisīšanas secībā, taču neveiksmes gadījumā atkārtoti mēģinājumi var mainīt secību. Vienmēr novērsiet dublikātus un saskaņojiet pēc call_id / objekta id.

Dublikāti

Piegāde notiek vismaz vienu reizi: atkārtots mēģinājums pēc atbildes, ko mēs nekad nesaņēmām, var dublēt notikumu. Katram atkārtotajam mēģinājumam ir tas pats event_id, tādēļ saglabājiet apstrādātos identifikatorus un izlaidiet atkārtojumus. event_id ir kopīgs arī starp galapunktiem — divi galapunkti, kas abonē vienu un to pašu notikumu, saņem to pašu event_id.

Noildzes

Galapunktu piegādēm katram mēģinājumam ir 30 sekunžu noildze. Mantotajā ceļā bloķējošiem pieprasījumiem, kas nosaka aktīva zvana darbību — konfigurācijas apmaiņai telephony.incoming / web.incoming — ir noteikts 10 sekunžu ierobežojums tālruņa zvana pirmajam mēģinājumam un 13 sekunžu ierobežojums visai apmaiņai, ieskaitot tās vienu atkārtoto mēģinājumu, kā arī 10 sekunžu ierobežojums logrīka sesijai. Lēna atbilde aizkavē zvana pieņemšanu, tāpēc centieties atbildēt dažu sekunžu laikā. Tīmekļa aizķeres režīma rīku izsaukšana pēc noklusējuma atļauj 20 sekundes, un rīku deklarācijās var norādīt augstākā līmeņa timeout.

Avota IP adreses

Izejošās tīmekļa aizķeres tiek sūtītas no ThunderPhone mākoņa IP diapazona. Ja jūsu ugunsmūrim nepieciešams atļauju saraksts, sazinieties ar atbalsta dienestu, un mēs kopīgosim pašreizējos diapazonus.

Izvēle starp mantotajām un uz galapunktiem balstītajām tīmekļa aizķerēm

FunkcijaMantotie (/v1/webhook)Galapunkti (/v1/developer/webhook-endpoints)
URL skaits1 katrai organizācijaiVairāki katrai organizācijai
Notikumu aptvērumsTikai telephony.* / web.*Visi 10 notikumu veidi
Notikumu filtrs—Katram galapunktam
Atkārtoti mēģinājumiNav, izņemot vienu tālruņa zvana konfigurācijas apmaiņai8 mēģinājumi 24 stundu laikā
Aploksnetype + datatype + data + event_id
Slepenās atslēgas nomaiņaAizstāj vienu slepeno atslēguSlepenā atslēga katram galapunktam
Atspējot bez dzēšanasPUT /v1/webhook ar {"url": ""}status=disabled
Statusa redzamība—active / disabled / failing
Bloķējoša konfigurācijas apmaiņaJā (telephony.incoming / web.incoming)Nekad — tikai paziņojumi
VispiemērotākaisDinamiska zvanu konfigurācijaNotikumu apstrāde produkcijā

Jaunajās integrācijās notikumi jāsaņem, izmantojot uz galapunktiem balstītas tīmekļa aizķeres. Saglabājiet (vai pievienojiet) mantoto URL tikai tad, ja dinamiski konfigurējat zvanus to pieņemšanas brīdī vai izmantojat tīmekļa aizķeru režīma rīku izsaukšanu — šīs pieprasījuma/atbildes apmaiņas darbojas tikai mantotajā maršrutā.


Saistītā informācija