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

Вебхуки

RolChat доставляет события в ваши системы в виде подписанных HTTP-запросов POST. Эта страница описывает вебхуки плагинов; вебхуки, которые отправляет правило Автоматизации, отличаются повторами, временем ожидания и сменой секрета, см. Вебхуки автоматизации. Те же правила действуют и в обратном направлении, когда ваша система, плагин или провайдер отправляет данные в RolChat. Проверяйте каждую доставку в указанном ниже порядке, прежде чем что-либо с ней делать.

POST /your/endpoint HTTP/1.1
Content-Type: application/json
User-Agent: RolChat-Webhook/1.0
X-RolChat-Timestamp: 1713615825
X-RolChat-Signature: sha256=a1b2c3…
X-RolChat-Nonce: nonce_01HKQN9…
X-RolChat-Event-Id: evt_01HKQN9…
{ "id": "evt_01HKQN9…", "type": "conversation.created", "occurred_at": "…", "data": { … } }
Заголовок Значение
X-RolChat-Timestamp Unix-время отправки в секундах. Входит в подписываемое сообщение.
X-RolChat-Signature sha256=<hex>. Префикс называет алгоритм, чтобы его можно было сменить в будущем.
X-RolChat-Nonce ULID, уникальный для этого HTTP-запроса. Повторная попытка получает новый nonce.
X-RolChat-Event-Id Собственный ID события. Не меняется между повторами; используйте его для дедупликации.

Исходящие доставки идут только на HTTPS-эндпоинты. HTTP-адрес отклоняется при создании подписки.

Подписываемое сообщение - это метка времени, символ точки и сырое тело запроса, байт в байт:

canonical = "<timestamp>.<body>"
signature = hex( HMAC-SHA256( secret, canonical ) )

Подписывайте полученные байты, а не повторно сериализованную копию разобранного JSON. Изменения пробелов или порядка ключей ломают подпись. SHA-256 - единственный допустимый алгоритм.

Выполните эти пять проверок по порядку. Примеры на Python, Node.js, Go, Ruby и PHP приведены на странице примеров проверки.

  1. Актуальность. Отклоняйте запрос, если |now − X-RolChat-Timestamp| > 300 секунд (400). Пять минут покрывают расхождение часов и делают перехваченный запрос бесполезным по истечении этого времени. Синхронизируйте сервер по NTP.
  2. Подпись. Вычислите ожидаемое значение и сравните его с помощью сравнения за постоянное время (hmac.compare_digest, crypto.timingSafeEqual, hash_equals). При несовпадении отклоняйте с 401. Обычное сравнение строк раскрывает информацию через время выполнения и недопустимо.
  3. Nonce. Сохраните X-RolChat-Nonce с TTL 10 минут атомарной операцией «записать, если отсутствует» (SET NX EX 600). Если значение уже есть, отклоняйте с 409: это повтор запроса. Если хранилище nonce недоступно, отказывайте с 503, чтобы RolChat повторил попытку; никогда не переходите по умолчанию к «принять».
  4. Разбирайте тело только теперь.
  5. Дедуплицируйте по ID события. Повторы приходят с новым nonce, но с тем же X-RolChat-Event-Id. Если этот ID уже обработан за последние семь дней, ответьте 200 без повторной обработки.

Отвечайте 2xx, как только доставка надёжно принята; саму работу выполняйте асинхронно. RolChat ждёт ответа 15 секунд.

  • Секрет вебхука - это 64 случайных байта в кодировке base64url (около 86 символов). Он генерируется при создании подписки или плагина и показывается один раз.
  • Храните его в собственном хранилище секретов или в переменных окружения; RolChat хранит только зашифрованную копию.
  • Ротация рекомендуется через 90 дней; продукт показывает напоминание, но никогда не отключает подписку из-за отсутствия ротации.
  • Ротация использует окно перекрытия: после POST /api/v1/plugins/{id}/webhook-secret/rotate и старый, и новый секрет проходят проверку в течение семи дней, новые доставки подписываются новым секретом, а старый удаляется по истечении окна. В момент ротации ничего не ломается.
  • Если секрет утёк, POST /api/v1/plugins/{id}/webhook-secret/revoke немедленно делает его недействительным, выпускает новый, отправляет письмо администраторам аккаунта и создаёт запись в журнале аудита.

Ответ не из диапазона 2xx или сетевой сбой планирует повторную попытку:

Попытка Задержка после предыдущей
1 сразу
2 15 секунд
3 1 минута
4 5 минут
5 30 минут
6 2 часа
7 8 часов
8 24 часа

408, 429, 5xx и сетевые ошибки повторяются. 400, 401, 403, 404 и 410 не повторяются: доставка сразу попадает в очередь недоставленных сообщений, потому что повтор отклонённой подписи или отсутствующего эндпоинта не поможет. После восьми неудачных попыток доставка также попадает в эту очередь.

Недоставленные сообщения хранятся 30 дней и видны в разделе Настройки → Плагины → {плагин} → Журнал вебхуков → DLQ, где администратор может повторно отправить любое из них (POST /api/v1/plugins/{id}/webhook-dlq/{entry_id}/replay).

  • Исходящее тело: по умолчанию 1 MB (настраивается для каждого плагина). Входящее тело в RolChat: 5 MB. Больше - 413.
  • Плагин может объявить allowed_source_ips; RolChat применяет этот список разрешённых адресов до проверки подписи.
  • В качестве дополнительной проверки можно ориентироваться на user agent RolChat-Webhook/1.0. Это не средство защиты.

Провайдеры отправляют данные в RolChat на /api/v1/webhooks/{category}/{adapter}, используя собственные схемы подписи (Twilio, Telnyx, Bandwidth, Meta для WhatsApp, Stripe). Каждый адаптер проверяет подпись своего провайдера, нормализует данные и повторно публикует их во внутренней шине событий с подписью RolChat. Ваша собственная система может отправлять данные в RolChat с теми же заголовками X-RolChat-*, описанными выше, подписанными секретом плагина, которому принадлежит эндпоинт.

У действия Отправить HTTP-запрос модуля «Автоматизация» свои правила доставки:

  • Один секрет на аккаунт. Показать или сменить его можно на экране «Автоматизация» (Владелец и Администратор). Смена вступает в силу сразу: окна перекрытия нет, старый секрет перестаёт проходить проверку немедленно, поэтому сначала обновите приёмник или смиритесь с коротким перерывом.
  • Время ожидания: RolChat ждёт ответа 10 секунд.
  • Повторы: всего до 6 попыток. Пауза перед 2-й попыткой - 30 секунд, затем примерно 2 минуты, 8 минут, 32 минуты и 2 часа 8 минут, каждая со сдвигом до 20 %. Одна пауза никогда не превышает 6 часов.
  • Что повторяется: сетевые ошибки, тайм-ауты, 5xx, 408, 425 и 429. Другие ответы 4xx, заблокированный адрес или слишком большое тело не повторяются: доставка сразу попадает в очередь недоставленных, как и после последней неудачной попытки.
  • Заголовки: X-RolChat-Signature, X-RolChat-Signature-V2, X-RolChat-Timestamp, X-RolChat-Delivery-Id, X-RolChat-Attempt.

POST /api/v1/webhooks/test-signature отправляет синтетическое подписанное событие на эндпоинт вызывающего плагина, чтобы вы могли проверить свою реализацию от начала до конца до появления реального трафика.

  • Проверка по разобранному и заново закодированному JSON вместо сырых байтов.
  • Использование == для сравнения подписей.
  • Дедупликация по nonce (у каждого повтора он новый) вместо ID события.
  • Часы, отстающие или спешащие больше чем на пять минут.
  • Медленная работа до ответа, из-за которой срабатывает тайм-аут 15 секунд и то же событие приходит снова.