Перейти к основному содержимому

Исходящие вебхуки

Получатель вебхука — это адрес на вашей стороне, по которому MonoPbx обращается, когда в вашей компании что-то происходит: звонок начинается или завершается, меняется очередь, регистрируется устройство, приходит текстовое сообщение. Каждое событие, которое выбирает фильтр получателя, отправляется ему как подписанный JSON-запрос POST. Доставка выполняется не менее одного раза, поэтому ваш получатель должен уметь увидеть одно и то же событие дважды.

Вебхуки — единственный канал автоматизации в этом выпуске.

Настройка получателя​

  1. Убедитесь, что получатель доступен по публичному адресу https на порту 443 (или другом порту от 1024 и выше). Адреса loopback, частных сетей и внутренние имена не принимаются.
  2. Создайте получателя через API (POST /api/v1/webhooks, право integrations:write). Выберите события для получения в event_types или оставьте поле пустым, чтобы получать все события, которые получателю разрешено видеть.
  3. Скопируйте secret для подписи из ответа. Он показывается один раз. Если вы его потеряете, замените его.
  4. Нажмите Проверить (POST /api/v1/webhooks/{id}/test). MonoPbx сразу отправляет подписанное событие webhook.test и возвращает результат доставки.

У компании может быть до 20 получателей. Тесты и повторные отправки ограничены 10 на компанию в минуту.

Выбор событий​

event_types принимает типы событий (call.ended) или шаблоны тем (call.*). Можно выбрать любой тип события WebSocket событий, кроме записей аудита. Получатель также получает:

  • cdr.written: запись о звонке сохранена. Поля записи те же, что в API записей о звонках. Ссылка на запись, стоимость и внутренние участники не включаются.
  • webhook.test: только от кнопки проверки. Подписаться на него нельзя.

Кто что получает​

Получатель получает только те события, которые его создатель может читать по всей компании. Право для каждого вида событий:

СобытияПраво
call.*, leg.*calls:control
queue.*queues:read
presence.*directory:read
voicemail.*voicemail:read
device.*devices:read
sms.*messaging:read
cdr.writtencall_history:read
config.changedправо чтения изменённого вида записи, например users:read или trunks:read
audit.*никогда не доставляется

Если вы создаёте получателя без одного из этих прав, события, которые его требуют, вам не отправляются. Явно указанная в фильтре запись, которую вам не разрешено получать, отклоняется, а список типов событий предлагает только те, которые вы можете получать. Изменение URL или фильтра получателя сбрасывает его разрешения до прав того, кто внёс изменение.

Проверка подписи​

Каждая доставка содержит эти заголовки в соответствии со спецификацией Standard Webhooks:

ЗаголовокЗначение
webhook-idИдентификатор события. Одинаковый при каждой попытке и повторной отправке. Используйте его, чтобы игнорировать дубликаты.
webhook-timestampВремя попытки в секундах Unix.
webhook-signaturev1,<base64>: HMAC-SHA256 от {webhook-id}.{webhook-timestamp}.{body}. Во время замены секрета есть две подписи, разделённые пробелом.
content-typeapplication/json

Используйте любую библиотеку Standard Webhooks и передайте необработанное тело запроса и заголовки. Библиотека отклоняет неверную подпись и метку времени старше пяти минут.

from standardwebhooks.webhooks import Webhook

Webhook("whsec_...").verify(request.body, request.headers) # raises if invalid or older than 5 min
import { Webhook } from "standardwebhooks";

new Webhook("whsec_...").verify(rawBody, headers);

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

Замена секрета​

POST /api/v1/webhooks/{id}/rotate-secret возвращает новый секрет, который показывается один раз. Старый секрет продолжает подписывать запросы в течение льготного периода (по умолчанию 24 часа, не более 7 дней, или 0, если без него). Обновите получатель в течение этого периода, чтобы ни одна доставка не была отклонена.

Повторы и недоставленные сообщения​

Доставка записывается до первой попытки, поэтому перезапуск MonoPbx её не теряет.

Ответ от вашего получателяЧто происходит
Любой 2xxДоставлено.
Любой другой код статуса, тайм-аут, сетевая ошибка или ошибка DNSПовтор через 5 секунд, 5 минут, 30 минут, 2 часа, 5 часов, затем дважды через 10 часов. Заголовок Retry-After до одного часа увеличивает ожидание.
Восьмая ошибкаНедоставлено. Остаётся в представлении недоставленных сообщений 30 дней и может быть отправлено повторно.
Ответ 3xxОшибка. Перенаправления никогда не выполняются.
Заблокированный адрес или тело больше 256 КиБСразу недоставлено.

Тело ответа от вашего получателя никогда не читается и не сохраняется. Чтобы отправить недоставленную доставку повторно, используйте POST /api/v1/webhooks/deliveries/{id}/redeliver; она получит восемь новых попыток с тем же webhook-id.

У каждого получателя есть ограничение частоты (по умолчанию 600 доставок в минуту, не более 6000). Доставки сверх лимита ждут несколько секунд.

Мониторинг доставок​

  • GET /api/v1/webhooks показывает каждого получателя с количеством ожидающих и недоставленных сообщений.
  • GET /api/v1/webhooks/deliveries?filter=status:eq:dead — это представление недоставленных сообщений.
  • GET /api/v1/webhooks/deliveries/{id}/attempts показывает каждую попытку: время, код статуса, задержку и результат. Хранится 90 дней.

Ограничения​

  • Разрешены только адреса https на порту 443 или на портах от 1024 и выше. Учётные данные в адресе не принимаются.
  • Адреса в частных сетях, loopback, link-local (включая адреса метаданных облака), в сетях CGN (carrier-grade NAT) и в зарезервированных сетях отклоняются как при сохранении получателя, так и при каждой попытке.
  • Получатель должен ответить 2xx, чтобы доставка считалась выполненной.

Структура события​

Тело каждой доставки имеет одну и ту же структуру: id, tenant_id, occurred_at, schema, type и data. Схемы JSON находятся в файле docs/api/events.schema.json репозитория продукта.