Перейти к содержимому
Версия 1.0 ещё не выпущена; проект находится на стадии pre-MVP. См. возможности и ограничения версии 1.0.

Контракт исходящих вебхуков

Исходящие вебхуки уведомляют внешнюю систему об изменениях контента. Это не команды плагинов и не место выполнения бизнес-правил CMS. Настройте подписчиков в разделе Настройки → Интеграции → Исходящие вебхуки с соответствующим правом сайта. Неудача уведомления не отменяет публикацию. Доставка выполняется по возможности с ограниченными повторами, без гарантии получения каждого события каждым подписчиком.

Пока выполняется Сохранить подписчиков, редактирование недоступно. Если другой пользователь сохранил список раньше, ваши правки остаются в форме. Кнопка Загрузить список и сбросить правки заменяет их актуальным списком. Если список или история доставок не загрузились, нажмите Повторить. Повторная загрузка истории не затрагивает правки подписчиков.

Успешные изменения контента, workflow, релизов, медиа и моделей ставят в очередь события: content.created, content.updated, content.trashed, content.restored, content.deleted, content.published, content.unpublished, workflow.transitioned, release.applied, media.created, media.updated, media.deleted, model.applied. Отклонённая запись, откат транзакции и идемпотентный повтор не создают нового события. Согласованный релиз отправляет события только после полного коммита в базе сайта.

Тело JSON содержит id, event, site_id, occurred_at (ISO-8601) и data. Данные определяют запись, модель, медиа или релиз и включают применимые сохранённую версию, ревизию и язык. События публикации указывают первичный instance_id, модель и состояние публикации. Приватные снимки полей и учётные данные не передаются. Текущие данные читайте через соответствующий API; снятая с публикации или удалённая запись может отсутствовать в публичном ответе.

После успешного изменения доставка получает состояние pending; ответ подписчика по сети не задерживает изменение. Существующий обработчик по расписанию выполняет первую отправку и повторы. Все доставки одного события сохраняют его ID и исходное тело, включая ручной повтор.

Отправитель выполняет POST с Content-Type: application/json. X-Deewan-Event содержит название события. X-Deewan-Delivery — ID конфигурации подписчика, не ID события. X-Deewan-Signature содержит sha256= и HMAC-SHA256 в виде шестнадцатеричной строки в нижнем регистре от точных UTF-8-байтов тела с секретом подписчика.

Проверьте исходные байты до разбора JSON, безопасно сравните подпись, проверьте нужный сайт и поддерживаемое событие, затем устраните дубликаты по стабильному id тела отдельно для каждого подписчика и сайта. Повторная сериализация JSON до проверки меняет подписанные байты. occurred_at подписан. Защита от повторного воспроизведения должна учитывать период, в течение которого разрешена повторная доставка. Отдельного заголовка с подписанной меткой времени нет.

Один ID события используется для рассылки и повторов. Повторы и повторные отправки сохраняют исходное тело и подписываются текущим секретом подписчика, поэтому изменение секрета требует согласованного обновления получателя. Каждая доставка записывает id и URL подписчика, куда она ушла. Повтор или повторная отправка выполняются, только пока подписчик с этим id имеет тот же URL, и отклоняются, если URL изменился, подписчик удалён или запись о доставке создана до того, как система начала сохранять адресата. Новый подписчик получает случайный id и не может занять id, у которого уже есть история доставок. Не устраняйте дубликаты только по X-Deewan-Delivery: он повторяется у несвязанных событий.

Любой 2xx подтверждает доставку. Время ожидания ответа по умолчанию — 5 секунд. Недоступность сети, HTTP 408, 429 и 5xx допускают повтор. При остальных HTTP-ошибках повторов не будет. Всего выполняется не более пяти попыток. Задержка между ними растёт экспоненциально от одной минуты до одного часа и случайно изменяется в пределах 50–100%. Допустимый Retry-After в секундах или формате даты может увеличить ожидание, максимум до часа. После исчерпания попыток автоматические повторы прекращаются.

Обработчик по расписанию резервирует записи, для которых наступило время повторной попытки, и повторно проверяет текущего подписчика. Удалённые или отключённые подписки не получают повторов. Не рассчитывайте на порядок доставки или на то, что каждое уведомление придёт ровно один раз: потерянное подтверждение либо повторное получение временного права на обработку может повторить уже обработанное уведомление. Получателю следует в одной атомарной операции надёжно сохранить принятое событие и применить связанные с ним изменения, прежде чем подтверждать получение. Используйте сведения о доставке в настройках, чтобы проверить ошибки или вручную повторить отправку. Неудачный ответ не доказывает отсутствие эффекта.

Проверьте отказ для неверной подписи, изменённых байтов, другого сайта и неподдерживаемого события. Убедитесь, что одинаковые ID не приводят к повторным изменениям, а события с разными ID у одного подписчика обрабатываются независимо, а потерянное подтверждение допускает безопасный повтор. Система, обновляющая поисковый индекс по вебхукам, должна соблюдать контракт полного поколения и удаления, а не только бесконечно добавлять и обновлять записи через upsert.

Источники: backend/src/lib/outbound-webhook.ts, backend/src/lib/outbound-retry.ts и backend/src/lib/lifecycle/publication-effects.ts. Эти правила исходящих повторов независимы от протокола плагинов.

Управляйте контентом из скриптов и ИИ-агентов через API управления CMS.


Стабильная версия ещё не выпущена (pre-MVP)
Коммит исходного кода: fe23db481c422b40e317b92fc98116b4c0c26a87 (с локальными изменениями)
Дата сборки (UTC): 2026-10-18T09:22:34.630Z
Коммит для обновления: не определён: в рабочей копии есть изменения. Примечания к выпуску