Исходящие вебхуки
Исходящий вебхук — это сообщение, которое панель отправляет на ваш адрес, когда с аккаунтом хостинга что-то происходит, чтобы другая система могла отреагировать: ваш собственный биллинг, канал в чате, таблица, скрипт провижининга.
Вебхуки доступны администраторам и реселлерам. Администратор узнаёт обо всех аккаунтах. Реселлер узнаёт только об аккаунтах, которые принадлежат ему. Клиенты и API-токены создавать их не могут: вебхуки настраиваются в самой панели, в собственном сеансе человека, чтобы утёкший токен никогда не превратился в постоянный канал событий панели.
Как добавить
Откройте страницу безопасности своего аккаунта (администратор: Безопасность; реселлер: Безопасность входа) и найдите Вебхуки под API-токенами.
- Введите адрес, например
https://example.com/hooks/panel. - Отметьте нужные события.
- Нажмите Добавить вебхук.
Панель один раз показывает секрет подписи (он начинается с whsec_). Скопируйте его сразу. Он
хранится в зашифрованном виде и повторно показан быть не может; если вы его потеряли, удалите вебхук и
добавьте новый.
У каждого человека может быть не более 10 вебхуков.
Адрес
- Он должен начинаться с
https://. Простойhttp://отклоняется, потому что вызов содержит данные аккаунта. - Он не должен содержать имя пользователя или пароль. Вместо этого проверяйте подпись.
- Он может содержать не более 500 символов.
- Он должен находиться в публичном интернете. Адреса на этом сервере, в частной сети, на интерфейсе loopback или в диапазоне метаданных облачного провайдера отклоняются — и при сохранении адреса, и снова в момент, когда панель подключается (так что имя хоста, которое позже начнёт указывать на частный адрес, тоже не сработает).
- Перенаправления не выполняются. Указывайте конечный адрес.
События
| Событие | Когда отправляется |
|---|---|
account.created |
Аккаунт хостинга создан |
account.suspended |
Аккаунт приостановлен |
account.unsuspended |
Приостановленный аккаунт возобновлён |
account.deleted |
Аккаунт удалён |
account.activity |
Другая активность в аккаунте |
Кнопка Проверить у каждого вебхука отправляет событие ping, чтобы вы убедились, что ваш адрес отвечает.
Одновременно может ожидать только одна проверка.
Что отправляется
Каждый вызов — это HTTP-запрос POST с телом JSON:
{
"event": "account.created",
"at": "2026-10-23T08:15:00Z",
"account": { "id": 42, "username": "example", "domain": "example.com" },
"detail": "short text about what happened"
}
at — время UTC. У события ping вид {"event":"ping","at":"…","webhook_id":7}.
С каждым вызовом приходят следующие заголовки:
| Заголовок | Значение |
|---|---|
X-Nimbopanel-Event |
Название события, например account.created |
X-Nimbopanel-Delivery |
Число, идентифицирующее эту доставку. Повтор той же доставки сохраняет то же число, поэтому используйте его, чтобы игнорировать дубликаты |
X-Nimbopanel-Timestamp |
Когда вызов был подписан, в секундах Unix |
X-Nimbopanel-Signature |
sha256= и далее подпись (см. ниже) |
Content-Type |
application/json |
User-Agent |
Nimbopanel-Webhook/1 |
Проверка подписи
Запрос на ваш адрес может отправить кто угодно. Подпись — это способ узнать, что вызов пришёл из вашей панели.
Подпись — это HMAC-SHA256 в шестнадцатеричном виде от метки времени, точки и необработанного тела ровно в том виде, как оно получено, вычисленный с вашим секретом подписи:
X-Nimbopanel-Signature == "sha256=" + hex( HMAC_SHA256( secret, X-Nimbopanel-Timestamp + "." + body ) )
Проверяйте в таком порядке:
- Вычислите указанное выше значение от необработанного тела запроса (до любого разбора или переформатирования JSON).
- Сравните его с заголовком сравнением за постоянное время.
- Отклоняйте вызов, если метка времени отличается от ваших часов более чем на 5 минут. Это не даёт повторно воспроизвести старый вызов.
- Используйте
X-Nimbopanel-Delivery, чтобы игнорировать уже обработанную доставку.
Пример на PHP:
$body = file_get_contents('php://input');
$ts = $_SERVER['HTTP_X_NIMBOPANEL_TIMESTAMP'] ?? '';
$sig = $_SERVER['HTTP_X_NIMBOPANEL_SIGNATURE'] ?? '';
$want = 'sha256=' . hash_hmac('sha256', $ts . '.' . $body, $secret);
if (!hash_equals($want, $sig) || abs(time() - (int) $ts) > 300) {
http_response_code(401);
exit;
}
Пример на Node.js:
const crypto = require('crypto');
function valid(rawBody, headers, secret) {
const ts = headers['x-nimbopanel-timestamp'] || '';
const want = 'sha256=' + crypto.createHmac('sha256', secret).update(ts + '.' + rawBody).digest('hex');
const got = headers['x-nimbopanel-signature'] || '';
return got.length === want.length
&& crypto.timingSafeEqual(Buffer.from(got), Buffer.from(want))
&& Math.abs(Date.now() / 1000 - Number(ts)) <= 300;
}
Ответ, повторы и приостановка
- Отвечайте любым статусом 2xx в течение 10 секунд. Всё остальное считается неудачей.
- Неудачный вызов повторяется через 1 минуту, затем через 5 минут, 30 минут и 2 часа. Всего это пять попыток в течение примерно двух с половиной часов, после чего доставка помечается как неудачная.
- Вызовы на один адрес отправляются по одному, начиная с самых старых. Доставка, ожидающая повтора, не задерживает более новые, поэтому не рассчитывайте, что события придут в строгом порядке. Медленный адрес задерживает только сам себя.
- После 50 неудачных доставок подряд вебхук приостанавливается: новые события для него больше не ставятся в очередь. Успешное нажатие Проверить сбрасывает счётчик, и события снова идут.
- Для одного вебхука ожидает не более 200 недоставленных вызовов. Сверх этого новые события для него не ставятся в очередь, пока часть не будет доставлена или не завершится неудачей.
- Панель хранит для каждого вебхука 50 последних завершённых доставок вместе с полученным ответом, чтобы вы видели, что не удалось. Самые свежие перечислены под вебхуком.
Если вместо статуса панель показывает причину, это одно из: адрес не находится в публичном интернете, нет ответа в течение 10 секунд, имя хоста не существует, сертификат HTTPS недействителен или панель не смогла подключиться.
Хорошие привычки
- Отвечайте быстро кодом
200и выполняйте настоящую работу потом. Получатель, который отвечает дольше 10 секунд, выглядит как неудача и получает то же событие снова. - Обрабатывайте одну и ту же доставку дважды без вреда. Повторы и сетевые ошибки делают дубликаты возможными.
- Не храните секрет в репозитории с кодом. Если он утёк, удалите вебхук и добавьте новый.
См. также: Руководство реселлера · Устранение неполадок