Когда нужен webhook
Мессенджеры и почта рассчитаны на людей, а webhook — на программы. Он нужен, когда событие мониторинга должно что-то запустить: создать тикет в helpdesk, написать в корпоративный мессенджер, которого нет в списке каналов, переключить трафик на резервный сервер, поставить отметку на внутренней статус-странице или сохранить историю сбоев в своё хранилище.
Запрос отправляется сразу после проверки, которая зафиксировала событие. Сайты проверяются раз в минуту на платных тарифах и раз в 5 минут на бесплатном.
Формат запроса
PingDesk отправляет POST с заголовками Content-Type: application/json, User-Agent: PingDesk-Webhook/1.0 и X-PingDesk-Event с кодом события — по нему удобно маршрутизировать запрос, не разбирая тело. Поля тела запроса:
- event — машинный код события: down, up, ssl_expiry и другие из списка выше.
- siteId, apiMonitorId или cronMonitorId — ID монитора в PingDesk; в запросе есть только одно из этих полей, в зависимости от типа монитора.
- name — название монитора.
- url — адрес проверяемого сайта или API; для cron-мониторов — значение вида cron://slug.
- details — объект с исходными значениями проверки. При падении — statusCode, responseTimeMs, error; при восстановлении — responseTimeMs и restoredAt; для SSL — sslGrade, daysRemaining, expiresAt; для домена — daysRemaining, expiresAt, registrar; для медленного ответа — responseTimeMs и thresholdMs.
- title — заголовок события на русском языке, например «🔴 Недоступен: Интернет-магазин».
- message — полный текст уведомления на русском: заголовок, детали, время по Москве и ссылка на монитор в PingDesk. Его можно переслать в чат без обработки.
- severity — важность: critical, warning, info или resolved (восстановление).
- sentAt — время отправки запроса в формате ISO 8601, UTC.
- deliveryId — ID уведомления. Он одинаковый у всех повторных попыток одного уведомления и дублируется в заголовке X-PingDesk-Delivery; у следующего напоминания ID новый.
Как проверить подлинность запроса
Если в канале задан Secret, PingDesk подписывает каждый запрос. В заголовке X-PingDesk-Timestamp передаётся время отправки в секундах Unix, а в X-PingDesk-Signature — значение sha256=<hex>, где hex — HMAC-SHA256 строки «<timestamp>.<тело запроса>» с ключом Secret. Сам секрет в запросе не передаётся.
- Прочитайте тело запроса как есть, в виде байтов или строки, до разбора JSON: подпись считается по точному тексту тела.
- Возьмите значение X-PingDesk-Timestamp, склейте строку «timestamp.тело» и посчитайте от неё HMAC-SHA256 с вашим Secret в шестнадцатеричном виде.
- Сравните результат со значением X-PingDesk-Signature после префикса sha256= функцией сравнения за постоянное время: crypto.timingSafeEqual в Node.js, hmac.compare_digest в Python, hash_equals в PHP.
- Отклоняйте запросы, у которых метка времени старше примерно 5 минут, — это защищает от повторной отправки перехваченного запроса.
- Если подписи нет или она не совпала, верните 401 и не обрабатывайте тело.
- Ответьте кодом 2xx как можно быстрее, а тяжёлую обработку выполняйте в фоне: PingDesk ждёт ответа не больше 10 секунд.
Хранение секрета и совместимость
Secret, как и URL канала, хранится в PingDesk в зашифрованном виде (AES-256-GCM) и после сохранения не возвращается ни в интерфейс, ни через API — вместо него показывается маска. Если секрет утёк, задайте новое значение в обработчике и в канале PingDesk.
Каналы, созданные до появления подписи, для совместимости дополнительно получают старый заголовок X-Webhook-Secret с секретом в открытом виде, чтобы существующие обработчики не сломались. Рекомендуем перейти на проверку подписи X-PingDesk-Signature.
Повторы, дубли и надёжность
Доставка считается успешной, если обработчик ответил кодом 2xx в течение 10 секунд. Если он вернул ошибку или не ответил, PingDesk повторяет запрос автоматически через 1, 5, 15, 30 и 60 минут — но только пока событие актуально: запрос о падении не уйдёт, если сайт уже восстановился. Для правил с напоминаниями повторная попытка не ждёт дольше интервала «Повторять каждые». Все попытки видны в «Журнале уведомлений».
Отдельно от повторных попыток работают напоминания правила: стандартное правило «Сайт недоступен» повторяет событие down каждые 5 минут, пока сайт лежит, а после восстановления присылает одно событие up. Если обработчик принял запрос, но не успел ответить, повторная попытка придёт с тем же deliveryId — сохраняйте обработанные ID и пропускайте повторы. Тикеты удобно группировать по паре «event + ID монитора» и закрывать по событию up. Чтобы получать только первое событие без напоминаний, в поле «Повторять каждые» укажите 0.
Частые вопросы
Можно ли подключить webhook на бесплатном тарифе?
+
Да. На бесплатном тарифе доступен один канал уведомлений, и им может быть webhook. На Starter каналов 5, на Pro — 10, на Agency — 50.
Подписывает ли PingDesk тело запроса через HMAC?
+
Да, если в канале задан Secret. Заголовок X-PingDesk-Signature содержит sha256=<HMAC-SHA256 строки «timestamp.тело запроса» с ключом Secret>, а X-PingDesk-Timestamp — время отправки в секундах Unix. Пересчитайте подпись по сырому телу, сравните за постоянное время и отклоняйте запросы старше 5 минут.
Можно ли отправлять вебхук на адрес во внутренней сети?
+
Нет. PingDesk отправляет запросы только на публично доступные адреса по HTTP или HTTPS. Приватные и зарезервированные IP-адреса блокируются.
Сколько PingDesk ждёт ответа?
+
До 10 секунд. Если обработчик не ответил или вернул код вне диапазона 2xx, отправка отмечается ошибкой в «Журнале уведомлений» и повторяется через 1, 5, 15, 30 и 60 минут, пока событие актуально.
Как понять, что сайт восстановился?
+
Придёт запрос с event: up, severity: resolved и тем же ID монитора. В details будут время ответа и момент восстановления в поле restoredAt.
Как выглядит тестовый запрос?
+
В нём event: test, name: PingDesk test, url: https://pingdesk.ru, пустой объект details, title «🔔 Тестовое уведомление PingDesk», а в message — текст тестового уведомления. ID монитора в тестовом запросе нет. Если задан Secret, тестовый запрос тоже подписан.
Можно ли отправлять события в несколько систем?
+
Да. Создайте несколько webhook-каналов с разными адресами и в правилах выберите для каждого события нужный канал или «Все активные каналы».