Open in
Общ преглед на уебкуките
Как ThunderPhone доставя събития в реално време, как да проверявате подписи и как се сравняват наследеният и базираният на крайни точки модели за доставка.
ThunderPhone изпраща HTTP POST заявки до вашия сървър, когато по време на разговор
се случат определени неща — започва входящ разговор, разговорът приключва, изпълнение
на оценяване завършва, задейства се предупреждение и т.н. Има два модела
за доставка:
Множество URL адреси, тайни за всяка крайна точка, филтри за събития за всяка крайна точка
и автоматични повторни опити.
Управлявайте чрез GET/POST/PATCH/DELETE /v1/developer/webhook-endpoints.
Един URL адрес за организация. Съдържа събитията от жизнения цикъл на разговорите, включително
блокиращите обмени на конфигурация. Управлява се чрез GET/PUT /v1/webhook.
Всички изброени типове събития в каталога на събитията се
доставят чрез webhook крайни точки. Шестте събития от жизнения цикъл на разговорите
(telephony.incoming, telephony.complete, telephony.tool,
web.incoming, web.complete, web.tool) се изпращат също до
остарелия webhook с един URL адрес — ако имате както остарял URL адрес, така и
съвпадаща крайна точка, получавате събитието и по двата пътя. Блокиращото
поведение (обменът на конфигурация telephony.incoming / web.incoming
и изпращането на инструменти в режим webhook)
съществува единствено по остарелия път; всяка доставка до крайна точка е
уведомление без изчакване.
Формат на полезния товар
Доставките до крайни точки са JSON обект с data, event_id и
type:
{
"data": {
"call_id": 987654321,
"from_number": "+14155550199",
"to_number": "+15551234567"
},
"event_id": "3f6b2ad0-1c9e-4a57-9f2b-8f6f0f9d2f11",
"type": "telephony.incoming"
}event_id е уникален за всяко генерирано събитие. Той е идентичен при повторни опити
и за всяка крайна точка, която получава събитието — използвайте го за дедупликация.
Остарелият webhook с един URL адрес изпраща същите type и data, но
без event_id:
{
"type": "telephony.incoming",
"data": { "call_id": 987654321, "from_number": "+14155550199", "to_number": "+15551234567" }
}При предаване всеки body се сериализира канонично — ключовете са подредени по азбучен ред, без празни интервали, в UTF-8. Примерите с форматиране в тази документация са само за по-лесно четене.
Вижте Каталога на събитията за пълния списък с типове събития и полета на полезния товар.
Проверка на подписа
Всяка заявка съдържа два подписа, и двата HMAC-SHA256 с ключ secret на
крайната точка (или secret на webhook на ниво организация за наследени
доставки):
X-ThunderPhone-Signature-V2: t=<unix seconds>,v1=<hex>подписва времевото клеймо, метода, пътя и заявката, както и необработеното тяло. Проверявайте този подпис и отхвърляйте заявки, чийтоtсе различава с повече от 5 минути от вашия часовник, така че прихваната заявка да не може да бъде повторно изпълнена по-късно. Повторните опити се подписват отново при изпращането им.X-ThunderPhone-Signatureподписва само необработеното тяло. Той все още се изпраща без промяна, за да продължат да работят съществуващите механизми за проверка.
Стъпки
- Прочетете заглавката, метода, суровия път и низа на заявката, както и суровото тяло преди всякакъв анализ.
- Изчислете шестнадесетичния HMAC-SHA256 на
<t>\n<METHOD>\n<path and query>\n<body>с вашата тайна. - Отхвърлете заявката, ако
tсе отклонява с повече от 300 секунди или ако резултатът не съвпада сv1при сравнение в константно време.
Телата са в канонична JSON сериализация (сортирани ключове, компактни разделители) и подписваме точно байтовете, които предаваме. Ръководството за проверка съдържа точния подписван низ, пример с изчисления, код без SDK и наследената заглавка.
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 "", 204import 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);
},
);Семантика на доставянето
Тази семантика се прилага за доставки към крайни точки. Наследеният
webhook с един URL е един синхронен опит без повторни опити, с изключение на
обмена на конфигурация за телефонни обаждания
telephony.incoming,
който се повтаря веднъж.
Повторни опити
За всяко събитие се прави един незабавен опит. Всеки отговор 2xx
потвърждава доставката. При всеки друг резултат (не-2xx,
грешка във връзката, изчакване) правим повторен опит 1 m, 5 m, 30 m, 2 h, 6 h,
12 h и 24 h след първия опит — 8 опита в рамките на
24 часа. Ако всички опити са неуспешни, доставката спира и крайната точка
се маркира с status="failing" в
крайните точки за webhook; изпращаме имейл до
собствениците и администраторите на вашата организация и показваме това в таблото. Върнете 2xx веднага щом
полезният товар бъде надеждно приет; обработвайте асинхронно.
Тестовите изпращания от API за тестване на крайната точка получават един повторен опит приблизително минута след
първия опит и никога не променят статуса на крайната точка.
Подреждане
Подреждането на доставянията е с най-добро усилие. На практика доставяме в
реда, в който се генерират събитията, но повторните опити могат да променят реда при неуспех.
Винаги премахвайте дубликати и съгласувайте по call_id / id на обекта.
Дубликати
Доставянето е поне веднъж: повторен опит след отговор, който не сме
получили, може да дублира събитие. Всеки повторен опит съдържа същия
event_id, затова съхранявайте обработените id и пропускайте повторенията. event_id се
споделя и между крайни точки — две крайни точки, абонирани за едно и
също събитие, получават един и същ event_id.
Изчаквания
Доставките към крайни точки имат изчакване от 30 s за всеки опит. По
наследения път блокиращите заявки, които управляват поведението на активно обаждане —
обменът на конфигурация
telephony.incoming / web.incoming
— са ограничени до 10 s за първия опит на телефонно обаждане и 13 s за целия обмен, включително неговия единствен
повторен опит, и до 10 s за сесия на widget. Бавният отговор забавя
приемането на обаждането, затова се стремете да отговаряте в рамките на няколко секунди. Изпращането на инструменти в режим webhook
позволява 20 s по подразбиране, а декларациите на инструменти могат да задават timeout от най-горно ниво.
IP адреси на източника
Изходящите уебкуки произхождат от диапазона облачни IP адреси на ThunderPhone. Ако защитната ви стена изисква списък с разрешени адреси, свържете се с поддръжката и ще споделим актуалните диапазони.
Избор между наследени уебкуки и уебкуки, базирани на крайни точки
| Функция | Наследени (/v1/webhook) | Крайни точки (/v1/developer/webhook-endpoints) |
|---|---|---|
| Брой URL адреси | 1 на организация | Много на организация |
| Обхват на събитията | Само telephony.* / web.* | Всички 10 типа събития |
| Филтър за събития | — | За всяка крайна точка |
| Повторни опити | Няма, с изключение на един за обмена на конфигурация при телефонно обаждане | 8 опита за 24 ч. |
| Обвивка | type + data | type + data + event_id |
| Смяна на секрет | Заменя единствения секрет | Секрет за всяка крайна точка |
| Деактивиране без изтриване | PUT /v1/webhook с {"url": ""} | status=disabled |
| Видимост на състоянието | — | active / disabled / failing |
| Блокиращ обмен на конфигурация | Да (telephony.incoming / web.incoming) | Никога — само известия |
| Подходящо за | Динамична конфигурация на обаждания | Получаване на събития в продукционна среда |
Новите интеграции трябва да получават събития чрез уебкуки, базирани на крайни точки. Запазете (или добавете) наследен URL само ако конфигурирате повиквания динамично при приемането им или използвате извикване на инструменти в режим на уебкуки — тези обмени заявка/отговор се изпълняват само по наследения път.
Свързани
Всички типове събития и техните полезни товари.
Управлявайте множество крайни точки, филтри за събития и тайни.
Блокиращата заявка, на която вашият сървър трябва да отговори, за да конфигурира разговори.
Полезен товар след разговор с транскрипция, запис и показатели.