Вебхуки

Вебхуки

Вебхуки позволяют MAIA уведомлять ваш сервер о событиях звонков в реальном времени. Когда звонок завершается, платформа отправляет HTTP POST-запрос на указанный вами URL с данными звонка и HMAC-подписью для проверки подлинности.

Событие call.completed

Сейчас доступно событие call.completed — оно отправляется после завершения звонка. В теле запроса приходят данные звонка: идентификатор, статус, длительность, транскрипт и извлечённые поля.

Настройка

Вебхуки настраиваются per-проект в кабинете dashboard.maia-ai.com. Для каждого проекта укажите:

  • URL вебхука — адрес вашего HTTPS-эндпоинта, на который MAIA будет слать POST-запросы.
  • Секрет — строка, которой подписываются запросы (HMAC). Храните её в безопасности и используйте для проверки подписи.

Управление базой знаний и часть настроек проекта доступны только в кабинете. Вебхуки также настраиваются в кабинете per-проект, а не через публичный API.

Пример payload

Тело запроса — JSON. Поля приводятся обобщённо; их состав может расширяться, поэтому пишите код устойчиво к дополнительным полям.

{
  "event": "call.completed",
  "data": {
    "id": "call_uuid",
    "status": "completed",
    "duration": 124,
    "transcript": "...текст разговора...",
    "fields": {
      "...": "извлечённые поля"
    }
  }
}
  • id — идентификатор звонка (тот же, что и в GET /v1/public/calls/{call_id}).
  • status — итоговый статус звонка.
  • duration — длительность звонка.
  • transcript — расшифровка разговора.
  • fields — извлечённые из разговора данные.

Проверка HMAC-подписи

Каждый запрос содержит HMAC-подпись в заголовке. Вычислите HMAC от сырого тела запроса по вашему секрету и сравните результат с подписью из заголовка. Сравнивайте подписи функцией, устойчивой к атакам по времени (constant-time).

⚠️

Проверяйте подпись по байтам сырого тела запроса, до любого парсинга или переформатирования JSON. Парсинг и обратная сериализация могут изменить байты и сломать проверку.

Псевдокод:

import hmac, hashlib
 
def verify(raw_body: bytes, signature_header: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(),
        raw_body,
        hashlib.sha256,
    ).hexdigest()
    return hmac.compare_digest(expected, signature_header)

Если подпись не совпадает — верните 401 и не обрабатывайте запрос.

Рекомендации

  • Отвечайте 2xx быстро. Верните 200/2xx сразу после приёма запроса, а тяжёлую обработку выполняйте асинхронно (очередь, фоновая задача). Долгий ответ может привести к таймауту и повторной доставке.
  • Идемпотентность. Один и тот же звонок может прийти повторно (ретраи при сбоях сети). Дедуплицируйте по id звонка, чтобы не обрабатывать одно событие дважды.
  • Проверяйте подпись всегда. Не доверяйте телу запроса без успешной проверки HMAC.
  • Используйте HTTPS. Эндпоинт вебхука должен быть доступен по HTTPS.

См. также