Подписанные вебхуки DOKIVO: результат готов, ваша система уведомлена
Обработка закончилась — внешний сервис получает подписанное событие. Разбираем проверку HMAC, повторы, сроки файла и границу между доставкой уведомления и сохранением результата.
Уведомить вашу систему, когда обработка завершена
PDF уже отправлен, но таблица ещё строится. Можно регулярно спрашивать статус, а можно получить событие завершения и сразу перейти к результату. В сценариях DOKIVO появились подписанные вебхуки: сервис отправляет небольшой JSON на настроенный HTTPS-адрес, а ваша интеграция проверяет событие и скачивает файл через API.
Это полезно, когда обработка — только часть процесса: спецификация должна попасть в папку закупки, а исключения — на проверку сотруднику. При этом уведомление не содержит самого документа и не означает, что файл уже сохранён у получателя. Доставить событие, скачать XLSX и записать его в учётную систему — три самостоятельных действия.
Подключение находится в разделе сценариев DOKIVO. Первичная принятая проверка 28 октября относится к обработке текстовых PDF спецификаций. Ниже разбираем контракт уведомления, проверку подписи и фактические результаты доставки; подключение конкретной внешней CRM остаётся частью интеграции клиента.
Что передаётся в событии run.completed
Событие содержит свой идентификатор, тип, runId, версию сценария, исход обработки, время, срок доступности и сведения об артефакте. В нём нет строк таблицы, содержимого PDF, имён файлов или API-ключа. Ссылка для неограниченного публичного скачивания также не передаётся: доступ к результату проверяется отдельным API-запросом.
Так получатель узнаёт, что нужно проверить, не превращая уведомление в копию спецификации. После приёма он запрашивает свежий статус по runId, смотрит result.available и expiresAt, затем скачивает результат с собственной авторизацией. Позднее уведомление не возвращает уже истёкший файл.
Для проверки подключения предусмотрен отдельный тип connection.test. Он помогает отличить настройку доставки от настоящего завершения обработки. Приёмник не должен запускать бизнес-действия на любой JSON, похожий на событие: сначала проверяются подпись, тип и соответствие идентификатора в теле заголовку.
| Подтверждение | Чего ещё не доказывает |
|---|---|
| Получатель ответил 2xx | Что XLSX скачан и его строки приняты в учёт |
| API вернул файл | Что целевое хранилище успешно записало эти байты |
| CRM подтвердила запись | Что все исходные числа документа проверены человеком |
Почему подпись проверяется по исходным байтам
Отправитель использует HMAC-SHA256: общий секрет служит ключом, а подписываемые данные состоят из timestamp, точки и точного тела события. Заголовки называются X-Dokivo-Event-Id, X-Dokivo-Timestamp и X-Dokivo-Signature. Версия подписи указывается как v1= перед шестнадцатеричным значением.
HMAC-SHA256(secret, timestamp + "." + rawBody)
Это пояснение контракта. Секрет хранится в защищённой настройке получателя; здесь нет рабочего ключа или запроса к сервису.
Сначала сохраните исходное тело HTTP-запроса. Если разобрать JSON и собрать его заново, пробелы, переводы строк или порядок полей могут измениться. Смысл JSON останется тем же, но подпись относится к прежним байтам. Поэтому проверка по повторно сериализованному объекту способна отклонить правильное событие.
Получатель сравнивает подпись способом с постоянным временем, проверяет допустимый возраст timestamp, совпадение body.id с заголовком и ожидаемый тип. Одной корректной подписи недостаточно для защиты от повторного действия: прежнее настоящее событие тоже имеет правильную подпись. Для этого нужен постоянный журнал уже принятых идентификаторов.
В проверенном варианте n8n использованы Webhook с получением raw body и Crypto v2 с секретом в credential. Это отдельная настройка получателя. Обычный скачиваемый шаблон сайта работает через опрос статуса; не нужно считать, что кнопка n8n автоматически создала внешний HTTPS-приёмник в вашей системе.
Повторная доставка не запускает PDF ещё раз
Сетевой сбой или ответ 503 не означает, что исходный документ нужно обрабатывать повторно. В DOKIVO уведомления имеют отдельный журнал доставки. Для временных ответов 429, 5xx и сетевых ошибок предусмотрены ограниченные повторы с увеличением интервала и учётом Retry-After. Повтор уведомления не создаёт новый запуск конвертации и не расходует её квоту.
Контракт ограничивает доставку двенадцатью попытками и сутками. Это предел, а не обещание обязательно ждать сутки перед следующим сообщением. Другие постоянные ошибки получателя и перенаправления не превращаются в бесконечный цикл. В интерфейсе можно увидеть доставку и состояние попытки отдельно от результата обработки.
Получатель задаётся публичным HTTPS-адресом на порту 443. На каждой попытке проверяются DNS-адреса, внутренние и служебные сети не разрешаются, переход по redirect выключен. Тело события ограничено 32 КиБ, таймаут запроса — десять секунд. Эти границы относятся к отправке уведомления, а не к максимальному размеру PDF.

Реальная доставка 503 → 200 и пять проверок приёмника
Production-отправитель DOKIVO проверили на собственном публичном HTTPS-получателе. Он дважды ответил 503, затем принял событие с ответом 200. Во всех попытках совпали идентификатор события, точные байты тела и проверенная HMAC-подпись. Это подтверждает повтор доставки того же события, а не создание похожих новых уведомлений.
Для настоящего завершения обработки отдельно приняли run.completed: получатель ответил 200, журнал показал доставку. Интерфейс на широком и узком экранах перестал предлагать ложную «следующую попытку» уже доставленному уведомлению. Статус результата и исключённый PDF при этом оставались видимы.
Приёмник n8n прошёл пять случаев: неверная подпись, устаревшее событие и несовпадающий eventId получили 401; корректное событие и его точный повтор — 200. После принятого события получался тот же XLSX. Проверка использовала исходное JSON-тело с пробелами и переносом строки, чтобы действительно проверить raw body.
Эти две проверки имеют разные границы. Получатель n8n работал внутри изолированного контейнера по loopback; публичный HTTPS-отправитель был проверен отдельно. Это не сквозная приёмка внешнего n8n клиента. Также повтор мог ещё раз скачать тот же файл: однократная запись в CRM или на диск не заявляется без проверки её собственного журнала.
Как устроить понятный обработчик событий
- Примите исходное тело и заголовки. Ограничьте размер и не меняйте байты до проверки HMAC.
- Проверьте подлинность и свежесть. Сопоставьте подпись, timestamp, идентификатор и тип события. Отказ не должен запускать скачивание.
- Зафиксируйте eventId. Используйте постоянное хранилище, способное различать параллельные одинаковые события.
- Прочитайте текущий запуск. Проверьте готовность и срок результата, скачайте его через авторизованный API.
- Подтвердите целевое действие. Сохраняйте файл идемпотентно по runId и отдельно отмечайте фактический ответ хранилища или CRM.
При первом подключении начните с тестового события и учебной спецификации. Заранее определите, кто разбирает needs_attention, временную недоступность приёмника и истёкший файл. Такой процесс проще сопровождать, чем единственную зелёную отметку, в которой смешаны доставка уведомления и правильность документа.
Частые вопросы
Вебхук передаёт таблицу Excel?
Нет. Он передаёт ограниченные метаданные события. Сам XLSX скачивается отдельным авторизованным API-запросом.
Доставка 200 означает сохранение в CRM?
Нет. Это подтверждение приёма события. Скачивание и запись файла в целевой сервис проверяются отдельно.
Повтор уведомления снова обрабатывает PDF?
Нет. Повторы относятся к журналу доставки. Повторная обработка документа требует отдельного намерения запуска.
Где начать настройку?
Откройте сценарии и подключения, выберите приёмник и проверьте тестовое событие. Контракт маршрутов опубликован в OpenAPI.