Вебхуки
Вебхуки отправляют события контента на ваш HTTPS-эндпоинт. Когда запись создаётся, обновляется или удаляется — CMS делает подписанный POST-запрос на настроенный URL.
Как настроить
- Откройте Вебхуки в боковой панели.
- Нажмите Добавить вебхук.
- Заполните:
- Название — метка для списка.
- URL приёмника — HTTPS-адрес, куда CMS будет отправлять POST.
- События —
entity.created,entity.updated,entity.deleted. Можно выбрать несколько. - Типы контента — фильтр по типам контента. «Все типы контента» = без фильтра.
- Активен — включить/выключить доставку.
- Сохраните. Сервер сгенерирует ключ подписи и покажет его один раз — скопируйте. Восстановить можно только ротацией ключа.
События
| Событие | Когда срабатывает |
|---|---|
entity.created |
Создана новая запись любого типа. |
entity.updated |
Изменена существующая запись. |
entity.deleted |
Запись удалена. |
Фильтр по типам контента сужает доставку: если выбрать только blog-post,
вебхук сработает только для изменений постов, а не для всех записей.
Что получает приёмник
CMS отправляет POST с JSON-теллом:
{
"id": "whev_a1b2c3",
"tenant_id": "cf6efe09-...",
"type": "entity.created",
"entity_slug": "blog-post",
"entity_id": "550e8400-...",
"data": { "title": "Привет", "slug": "hello" },
"user": { "id": "u-1", "username": "alice", "role": "editor" },
"timestamp": "2026-08-11T12:00:00Z",
"attempt": 1
}
Заголовки:
| Заголовок | Что содержит |
|---|---|
Content-Type |
application/json |
X-Dynamica-Signature |
HMAC-SHA256 подпись (см. ниже) |
X-Dynamica-Delivery |
ID доставки — для идемпотентности |
X-Dynamica-Event |
Тип события (entity.created) |
Поле prev_data появляется только при entity.updated — содержит
состояние до изменения. В остальных событиях этого поля нет.
Проверка подписи
Каждый запрос подписан HMAC-SHA256 с помощью ключа, который вы получили
при создании вебхука. Подпись передаётся в заголовке X-Dynamica-Signature
в формате t=<unix-секунды>,v1=<hex-HMAC>. HMAC считается от строки
"<timestamp>.<сырое тело запроса>" — используйте исходные байты, не
ре-сериализуйте JSON.
Проверка на стороне приёмника:
- Разбор
t(unix-секунды) иv1(hex-HMAC). - Отклонить, если
|now - t| > 5 минут. - Вычислить HMAC от сырого тела запроса (не ре-сериализовать JSON!).
- Сравнить с
v1константным временем.
Пример (Node.js):
const crypto = require('crypto');
function verify(secret, rawBody, header) {
const [tPart, v1Part] = header.split(',');
const ts = tPart.split('=')[1];
const v1 = v1Part.split('=')[1];
const expected = crypto
.createHmac('sha256', secret)
.update(`${ts}.${rawBody}`)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(v1)
);
}
Доставка и повторы
| Параметр | Значение |
|---|---|
| Таймаут | 10 секунд |
| Попыток | 8 (первая + 7 повторов) |
| Период | ~24 часа |
| Параллельность | 10 глобально, 3 на вебхук |
Расписание задержек: 1 мин → 5 мин → 30 мин → 2 ч → 6 ч → 12 ч → 24 ч.
Поведение по HTTP-кодам ответа:
| Код | Действие |
|---|---|
| 2xx | Успех. Доставка завершена. |
| 410 | Вебхук деактивируется. Повторов нет. |
| 4xx (кроме 410) | Ошибка клиента. Повторов нет. |
| 5xx | Повтор. Каждый провал увеличивает счётчик. |
| Таймаут / сеть | Повтор. |
После 8 неудач доставка попадает в dead letter — терминальный статус.
Журнал доставок
В админке, под списком вебхуков — журнал последних 50 доставок. Для каждой: статус, событие, HTTP-код ответа, попытка, отправленный payload и тело ответа приёмника.
Статусы:
- Успех — доставлено (2xx).
- Повтор — ждёт следующей попытки.
- Ожидает — в очереди.
- Очередь недоставленных — все попытки исчерпаны.
- Цепь разомкнута — предохранитель отключил доставку (5 минут).
- Частичный сбой — запрос доставлен, но обработка команд не завершена.
- Клиентская ошибка — 4xx, доставки прекращены.
Действия в журнале:
- Тест — отправить тестовую доставку.
- Повторить — повторить конкретную доставку.
- Сменить ключ — сгенерировать новый ключ подписи.
Предохранитель
Если приёмник стабильно отвечает 5xx или не отвечает, предохранитель размыкает цепь: доставка приостанавливается на 5 минут. Условия: 20 последовательных неудач или ≥50% неудач из последних 50 запросов.
Лимиты
Количество вебхуков зависит от тарифа. Проверяется при создании — лимит превышен → вебхук не создастся.
Что дальше
- Плагины — реверс-прокси плагины с UI.
- GraphQL API — запросы и мутации.
- Фильтрация — фильтры для запросов.