ThunderPhone 2.0 on nyt julkaistu.Ota käyttöön itse – alkaen 2 ¢/min.Lue lisää julkistuksesta

Webhooks

Webhookien yleiskatsaus

Miten ThunderPhone toimittaa reaaliaikaisia tapahtumia, miten allekirjoitukset vahvistetaan ja miten vanha toimitusmalli vertautuu päätepistepohjaiseen toimitusmalliin.

ThunderPhone lähettää HTTP POST -pyyntöjä palvelimellesi, kun puhelun aikana tapahtuu asioita — saapuva puhelu alkaa, puhelu päättyy, arviointiajo valmistuu, hälytys laukeaa ja niin edelleen. Käytössä on kaksi toimitusmallia:

Kaikki tapahtumaluettelossa luetellut tapahtumatyypit toimitetaan webhook-päätepisteiden kautta. Kuusi puhelun elinkaaren tapahtumaa (telephony.incoming, telephony.complete, telephony.tool, web.incoming, web.complete, web.tool) lähetetään myös vanhaan yhden URL-osoitteen webhookiin — jos käytössäsi on sekä vanha URL-osoite että vastaava päätepiste, saat tapahtuman molempia reittejä pitkin. Estävä toiminta (telephony.incoming / web.incoming -määritysvaihto ja webhook-tilan työkalun välitys) on käytettävissä vain vanhalla reitillä; jokainen päätepistetoimitus on ilmoitus, johon ei odoteta vastausta.

Hyötykuorman muoto

Päätepistetoimitukset ovat JSON-objekteja, joissa on 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 yksilöllinen jokaiselle lähetetylle tapahtumalle. Se on sama uudelleenyrityksissä ja kaikissa tapahtuman vastaanottavissa päätepisteissä — poista kaksoiskappaleet sen perusteella.

Vanha yhden URL-osoitteen webhook lähettää saman type- ja data-sisällön, mutta ilman event_id-kenttää:

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

Siirrettäessä jokainen runko sarjoitetaan kanonisesti — avaimet lajitellaan aakkosjärjestykseen, välilyöntejä ei käytetä ja merkistönä on UTF-8. Näiden dokumenttien kauniisti muotoillut esimerkit ovat vain luettavuuden vuoksi.

Katso tapahtumaluettelosta täydellinen luettelo tapahtuma- tyypeistä ja hyötykuormakentistä.

Allekirjoituksen vahvistaminen

Jokaisessa pyynnössä on kaksi allekirjoitusta, jotka molemmat ovat HMAC-SHA256-allekirjoituksia päätepisteen secret-avaimella (tai organisaatiotason webhookin secret-avaimella vanhoja toimituksia varten):

  • X-ThunderPhone-Signature-V2: t=<unix seconds>,v1=<hex> allekirjoittaa aikaleiman, metodin, polun ja kyselyparametrit sekä raakarungon. Vahvista tämä allekirjoitus ja hylkää pyynnöt, joiden t poikkeaa kellostasi yli 5 minuuttia, jotta kaapattua pyyntöä ei voi toistaa myöhemmin. Uudelleenyritykset allekirjoitetaan uudelleen, kun ne lähetetään.
  • X-ThunderPhone-Signature allekirjoittaa vain raakarungon. Se lähetetään edelleen muuttumattomana, jotta nykyiset vahvistajat toimivat edelleen.

Vaiheet

  1. Lue otsake, metodi, raakapolku ja kysely sekä raaka runko ennen jäsentämistä.
  2. Laske salaisuuttasi käyttäen heksamuotoinen HMAC-SHA256 arvosta <t>\n<METHOD>\n<path and query>\n<body>.
  3. Hylkää pyyntö, jos t poikkeaa yli 300 sekuntia tai jos tulos ei vastaa arvoa v1 vakioaikaisessa vertailussa.

Rungot ovat kanonista JSON-sarjallistusta (lajitellut avaimet, tiiviit erottimet), ja allekirjoitamme täsmälleen lähettämämme tavut. vahvistusoppaassa ovat tarkka allekirjoitettava merkkijono, käytännön esimerkki, SDK:ta käyttämätön koodi ja vanha otsake.

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);
  },
);

Toimitussemantiikka

Nämä semantiikat koskevat päätepisteen toimituksia. Vanha yhden URL-osoitteen webhook tekee yhden synkronisen yrityksen ilman uudelleenyrityksiä, lukuun ottamatta puhelun telephony.incoming määritysvaihtoa, joka yritetään uudelleen kerran.

Uudelleenyritykset

Jokaista tapahtumaa yritetään kerran välittömästi. Mikä tahansa 2xx-vastaus kuittaa toimituksen. Kaikissa muissa tapauksissa (muu kuin 2xx, yhteysvirhe, aikakatkaisu) yritämme uudelleen 1 min, 5 min, 30 min, 2 h, 6 h, 12 h ja 24 h ensimmäisen yrityksen jälkeen — yhteensä 8 yritystä 24 tunnin aikana. Jos kaikki yritykset epäonnistuvat, toimitus pysähtyy ja päätepiste merkitään tilaan status="failing" webhook-päätepisteissä; lähetämme sähköpostia organisaatiosi omistajille ja ylläpitäjille sekä näytämme tiedon hallintapaneelissa. Palauta 2xx heti, kun hyötykuorma on hyväksytty pysyvästi; käsittele se asynkronisesti. Päätepisteen testaus-API:n testilähetyksiä yritetään uudelleen kerran noin minuutin kuluttua ensimmäisestä yrityksestä, eivätkä ne koskaan muuta päätepisteen tilaa.

Järjestys

Toimitusjärjestys pyritään säilyttämään parhaan mahdollisen mukaan. Käytännössä toimitamme tapahtumat niiden lähetysjärjestyksessä, mutta uudelleenyritykset voivat muuttaa järjestystä epäonnistumisen yhteydessä. Poista aina kaksoiskappaleet ja täsmäytä tiedot call_id-tunnuksen / objektitunnuksen perusteella.

Kaksoiskappaleet

Toimitus tapahtuu vähintään kerran: uudelleenyritys vastauksen jälkeen, jota emme koskaan nähneet, voi luoda tapahtumasta kaksoiskappaleen. Jokaisella uudelleenyrityksellä on sama event_id, joten tallenna käsitellyt tunnukset ja ohita toistot. event_id on myös jaettu päätepisteiden välillä — kaksi samaa tapahtumaa tilaavaa päätepistettä vastaanottaa saman event_id-tunnuksen.

Aikakatkaisut

Päätepisteen toimituksilla on 30 s aikakatkaisu yritystä kohden. Vanhassa polussa reaaliaikaista puhelukäyttäytymistä ohjaavat estävät pyynnöt — telephony.incoming / web.incoming määritysvaihto — on rajoitettu 10 s puhelun ensimmäisessä yrityksessä ja 13 s koko vaihdolle, mukaan lukien sen yksi uudelleenyritys, sekä 10 s widget-istunnolle. Hidas vastaus viivästyttää puheluun vastaamista, joten pyri vastaamaan muutamassa sekunnissa. Webhook-tilan työkalun lähetys sallii oletusarvoisesti 20 s ja työkalumäärityksissä voidaan asettaa ylimmän tason timeout.

Lähtö-IP-osoitteet

Lähtevät webhookit tulevat ThunderPhonen pilvipalvelun IP-osoitealueelta. Jos palomuurisi edellyttää sallittujen osoitteiden luetteloa, ota yhteyttä tukeen, niin jaamme nykyiset alueet.

Valinta vanhojen ja päätepistepohjaisten webhookien välillä

OminaisuusLegacy (/v1/webhook)Päätepisteet (/v1/developer/webhook-endpoints)
URL-osoitteiden määrä1 organisaatiota kohdenUseita organisaatiota kohden
TapahtumakattavuusVain telephony.* / web.*Kaikki 10 tapahtumatyyppiä
Tapahtumasuodatin—Päätepistekohtainen
UudelleenyrityksetEi lainkaan, lukuun ottamatta yhtä puhelun asetustenvaihtoa8 yritystä 24 tunnin aikana
Kirjekuoritype + datatype + data + event_id
Salaisuuden kiertoKorvaa yksittäisen salaisuudenPäätepistekohtainen salaisuus
Poista käytöstä poistamattaPUT /v1/webhook ja {"url": ""}status=disabled
Tilan näkyvyys—active / disabled / failing
Estävä asetustenvaihtoKyllä (telephony.incoming / web.incoming)Ei koskaan — vain ilmoituksia
Sopii parhaitenDynaaminen puhelun määritysTapahtumien käsittely tuotannossa

Uusien integraatioiden tulee vastaanottaa tapahtumat päätepistepohjaisten webhookien kautta. Säilytä (tai lisää) vanha URL-osoite vain, jos määrität puhelut dynaamisesti puheluun vastaamisen yhteydessä tai käytät webhook-tilan työkalujen välitystä — nämä pyyntö-/vastausvaihdot toimivat vain vanhalla reitillä.


Aiheeseen liittyvät