раздел 04
Вебхуки: события Zoom
Вебхук - это когда не вы спрашиваете Zoom, а Zoom сам присылает POST на ваш URL, как только что-то произошло. Не нужно опрашивать API по таймеру в надежде, что запись наконец готова - Zoom сообщит сам.
Зачем
recording.completed- облачная запись обработана и готова к скачиванию. Главное событие для пайплайнов вокруг записей.meeting.started/meeting.ended- встреча началась или закончилась. Удобно для статусов и уведомлений.- Десятки других событий: участник вошёл, встреча создана, изменена и т.д.
Как настроить
1
Поднять endpoint
Публичный HTTPS-URL на вашем сервере, который принимает
POST с JSON. Это адрес, куда Zoom будет слать события.2
Указать его в приложении
В настройках приложения (вкладка Feature / Event Subscriptions) включите вебхуки, впишите URL и отметьте нужные события - например,
recording.completed.3
Пройти валидацию endpoint
Zoom проверит, что URL действительно ваш: пришлёт challenge, на который надо ответить корректно (см. ниже про secret token и CRC).
4
Обрабатывать события
Дальше на каждое событие приходит
POST с телом, где есть тип события и данные. Разбирайте по полю event.Валидация endpoint: secret token и CRC
У приложения есть secret token. При настройке (и периодически) Zoom шлёт на ваш URL событие проверки endpoint.url_validation с полем plainToken. Вы должны вернуть подтверждение: посчитать HMAC-SHA256 от plainToken на вашем secret token и отдать обратно plainToken и полученный хэш. Эта проверка называется CRC (challenge-response check). Без корректного ответа Zoom не активирует вебхук.
import hashlib
import hmac
SECRET_TOKEN = "..." # из настроек приложения
def handle_validation(plain_token: str):
signature = hmac.new(
SECRET_TOKEN.encode(),
plain_token.encode(),
hashlib.sha256,
).hexdigest()
return {"plainToken": plain_token, "encryptedToken": signature}
Пример тела события
Когда запись готова, на ваш endpoint придёт примерно такое (структура - идея, поля упрощены):
{
"event": "recording.completed",
"payload": {
"account_id": "ACCOUNT_ID",
"object": {
"id": 123456789,
"topic": "Демо для клиента",
"recording_files": [
{
"file_type": "MP4",
"download_url": "https://...",
"status": "completed"
}
]
}
}
}