Перейти к содержимому
mini.casa
Разработчикам

Надёжные сигналы для долгой работы

Подписанные HTTPS-запросы при изменении заданий, доменов, публикаций или одобрений с доставкой как минимум один раз.

Зарегистрируйте конечную точку

Добавьте конечную точку на странице Разработчикам или с областью доступа webhooks:write:

curl -s -X POST "$BASE/workspaces/$WS/webhooks" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: $(openssl rand -hex 16)" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://hooks.example.com/mini-casa","events":["job.updated","publication.updated"]}'

Ответ содержит signing_secret (whsec_...), показанный один раз. URL должен использовать HTTPS на порту 443 и разрешаться только в публичные адреса; приватные, петлевые и внутренние адреса отклоняются, проверка повторяется перед каждой доставкой, перенаправления никогда не выполняются. У пространства может быть до 10 действующих конечных точек.

Докажите, что управляете ею

Новые конечные точки начинают в состоянии pending_verification. Кнопка Проверить (или POST /webhooks/{id}/verify) отправляет один подписанный webhook.challenge. Ответьте 2xx с {"challenge": "<data.challenge>"}, и конечная точка станет active.

События

  • job.updated: задание или массовый запуск меняет состояние.
  • job.item.updated: один элемент массового запуска меняет состояние.
  • domain.updated: собственный домен проходит проверки.
  • publication.updated: сборка начинается, завершается успешно, неудачно или заменяется другой.
  • approval.updated: по одобрению принято решение, оно истекло или использовано.
  • billing.entitlement.updated: меняется тариф или доступные права.

Тела содержат только идентификаторы и состояние, никогда учётные данные, содержимое или персональные данные. Получайте текущее состояние через API.

Проверяйте каждый запрос

У каждого запроса есть SmallWorld-Webhook-Id, SmallWorld-Webhook-Timestamp (секунды Unix) и SmallWorld-Webhook-Signature (v1=<hex>,kid=<key id>). Подпись представляет собой HMAC-SHA256 от <timestamp>.<raw body> с вашим секретом. Используйте исходное тело до разбора JSON, сравнивайте за постоянное время и отклоняйте метки, отличающиеся от ваших часов более чем на пять минут.

import crypto from "node:crypto";

export function verify(secret, timestamp, rawBody, header) {
  const expected = crypto.createHmac("sha256", secret).update(`${timestamp}.${rawBody}`).digest("hex");
  const given = /v1=([a-f0-9]+)/.exec(header)?.[1] ?? "";
  const fresh = Math.abs(Date.now() / 1000 - Number(timestamp)) <= 300;
  return fresh && given.length === expected.length
    && crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected));
}

Гарантии доставки

  • Как минимум один раз. Запрос повторяется до ответа 2xx. Идентификатор события сохраняется при каждой попытке и повторной доставке, поэтому храните его и игнорируйте уже встреченные идентификаторы.
  • Интервал повторов увеличивается от минуты до суток в течение суммарно 72 часов. Затем доставка становится недоставленным сообщением, которое можно отправить снова со страницы разработчика или через redeliver_webhook.
  • Конечная точка, у которой подряд не доставлены 10 событий, приостанавливается до вашего возобновления.
  • Порядок не гарантируется: воспринимайте состояние как подсказку и читайте ресурс.