Open in
Огляд вебхуків
Як ThunderPhone надсилає події в реальному часі, як перевіряти підписи та як порівнюються застаріла й кінцева моделі доставки.
ThunderPhone надсилає HTTP-запити POST на ваш сервер, коли під час дзвінка
відбуваються події — починається вхідний дзвінок, завершується дзвінок, завершується
перевірка оцінювання, спрацьовує сповіщення тощо. Є дві моделі
доставки:
Кілька URL-адрес, секрети для кожної кінцевої точки, фільтри подій для кожної кінцевої точки
та автоматичні повторні спроби.
Керуйте через GET/POST/PATCH/DELETE /v1/developer/webhook-endpoints.
Одна URL-адреса на організацію. Передає події життєвого циклу дзвінка, зокрема
блокувальні обміни конфігурацією. Керується через GET/PUT /v1/webhook.
Усі перелічені типи подій у каталозі подій
доставляються через кінцеві точки вебхуків. Шість подій життєвого циклу дзвінка
(telephony.incoming, telephony.complete, telephony.tool,
web.incoming, web.complete, web.tool) також надсилаються до
застарілого вебхука з однією URL-адресою — якщо у вас є і застаріла URL-адреса, і
відповідна кінцева точка, ви отримуєте подію за обома шляхами. Блокувальна
поведінка (обмін конфігурацією telephony.incoming / web.incoming
та виклик інструментів у режимі вебхуків)
доступна виключно через застарілий шлях; кожна доставка до кінцевої точки є
сповіщенням без очікування відповіді.
Формат корисного навантаження
Доставки до кінцевих точок містять 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 є унікальним для кожної надісланої події. Він однаковий для повторних спроб
і для кожної кінцевої точки, що отримує подію — виконуйте дедуплікацію за ним.
Застарілий вебхук з однією URL-адресою надсилає ті самі type і data, але
без event_id:
{
"type": "telephony.incoming",
"data": { "call_id": 987654321, "from_number": "+14155550199", "to_number": "+15551234567" }
}Під час передавання кожне тіло серіалізується канонічно — ключі відсортовано за алфавітом, без пробілів, UTF-8. Відформатовані приклади в цій документації наведено лише для зручності читання.
Перегляньте каталог подій, щоб отримати повний список типів подій і полів корисного навантаження.
Перевірка підпису
Кожен запит містить два підписи, обидва HMAC-SHA256 з ключем secret
кінцевої точки (або secret вебхука на рівні вашої організації для застарілих
доставок):
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);
},
);Семантика доставки
Ця семантика застосовується до доставок кінцевих точок. Застарілий
вебхук з однією URL-адресою виконує одну синхронну спробу без повторних спроб, за винятком
обміну конфігурацією телефонного дзвінка
telephony.incoming,
який повторюється один раз.
Повторні спроби
Для кожної події негайно виконується одна спроба. Будь-яка відповідь 2xx
підтверджує доставку. За будь-якого іншого результату (не-2xx,
помилка підключення, тайм-аут) ми повторюємо спробу через 1 хв, 5 хв, 30 хв, 2 год, 6 год,
12 год і 24 год після першої спроби — 8 спроб протягом
24 годин. Якщо всі спроби завершуються невдачею, доставка припиняється, а кінцева точка
позначається як status="failing" у
кінцевих точках вебхуків; ми надсилаємо електронний лист
власникам і адміністраторам вашої організації та показуємо це на панелі керування. Поверніть 2xx, щойно
корисне навантаження буде надійно прийнято; обробляйте його асинхронно.
Тестові надсилання з test API кінцевої точки отримують одну повторну спробу приблизно через хвилину після
першої спроби та ніколи не змінюють статус кінцевої точки.
Порядок
Порядок доставки забезпечується настільки, наскільки це можливо. На практиці ми доставляємо події
у порядку їх створення, але повторні спроби можуть змінити порядок у разі помилки.
Завжди виконуйте дедуплікацію та звірку за call_id / ідентифікатором об’єкта.
Дублікати
Доставка виконується щонайменше один раз: повторна спроба після відповіді, якої ми не
отримали, може дублювати подію. Кожна повторна спроба містить той самий
event_id, тому зберігайте оброблені ідентифікатори та пропускайте повтори. event_id також
спільний для всіх ендпойнтів — два ендпойнти, підписані на
ту саму подію, отримують той самий event_id.
Тайм-аути
Доставки до кінцевих точок мають тайм-аут 30 с для кожної спроби. У
застарілому шляху блокувальні запити, що керують поведінкою активного дзвінка, —
обмін конфігурацією
telephony.incoming / web.incoming —
обмежені 10 с для першої спроби телефонного дзвінка та 13 с для всього обміну, включно з однією
повторною спробою, а також 10 с для сеансу віджета. Повільна відповідь затримує
прийняття дзвінка, тому намагайтеся відповідати протягом кількох секунд. Диспетчеризація інструментів у режимі вебхука
за замовчуванням допускає 20 с, а оголошення інструментів можуть задавати 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-адресу лише якщо ви динамічно налаштовуєте дзвінки під час прийняття або використовуєте виклик інструментів у режимі вебхуків — ці обміни запитами/відповідями працюють лише через застарілий шлях.
Пов’язані матеріали
Усі типи подій і їхні корисні навантаження.
Керуйте кількома кінцевими точками, фільтрами подій і секретами.
Блокувальний запит, на який ваш сервер має відповісти, щоб налаштувати дзвінки.
Корисне навантаження після дзвінка з транскриптом, записом і метриками.