dokumentacja · dla deweloperów

Webhooki

Powiadomienia push o tym, co interesuje Twoje systemy: zakończony skan, nowy tracker, opublikowana wersja, ukończony eksport dowodów. Podpisane, powtarzane i możliwe do podejrzenia.

Endpointy

Twórz endpointy w Ustawienia workspace’u → Deweloperzy → Webhooki lub przez API. Akceptowane są tylko adresy https na publicznych hostach; adresy prywatne i wewnętrzne są odrzucane przy rejestracji. Sekret podpisu (whsec_…) jest pokazywany raz przy tworzeniu i można go rotować w każdej chwili; po rotacji weryfikuj względem obu sekretów, dopóki Twój deploy nie nadrobi.

Zdarzenia

Dwanaście typów zdarzeń, subskrybowanych pojedynczo lub przez *:

scan.completed · scan.failed · tracker.new · issue.opened · issue.resolved · alert.raised · config.published · version.promoted · export.completed · declaration.updated · install.broken · plan.changed

Weryfikacja dostarczenia

Dostarczenia są zgodne z konwencją Standard Webhooks. Z każdym POST przychodzą trzy nagłówki:

webhook-id:        <delivery id>
webhook-timestamp: <unix seconds>
webhook-signature: v1,<base64(hmac_sha256(key, id.timestamp.body))>

Klucz HMAC to część base64 Twojego sekretu whsec_, zdekodowana do surowych bajtów. Przelicz podpis nad id + "." + timestamp + "." + body, porównaj w stałym czasie i odrzuć wszystko starsze niż pięć minut:

import { createHmac, timingSafeEqual } from 'node:crypto';

function verify(secret, headers, rawBody) {
  const key = Buffer.from(secret.slice('whsec_'.length), 'base64');
  const msg = headers['webhook-id'] + '.' + headers['webhook-timestamp'] + '.' + rawBody;
  const want = createHmac('sha256', key).update(msg).digest();
  const got = Buffer.from(headers['webhook-signature'].split(',')[1], 'base64');
  const fresh = Math.abs(Date.now() / 1000 - Number(headers['webhook-timestamp'])) < 300;
  return fresh && want.length === got.length && timingSafeEqual(want, got);
}

Ponowne próby i ponowne dostarczanie

Nieudane dostarczenie jest powtarzane z backoffem: 1 minuta, potem 5 minut, 30 minut, 2 godziny, 6 godzin; potem jest oznaczane jako martwe. Każda próba, kod odpowiedzi i następna próba są widoczne w dzienniku dostarczeń endpointu, a każde dostarczenie można wysłać ponownie ręcznie; ponowne dostarczenie odwołuje się do oryginału. Historia dostarczeń jest przechowywana 90 dni.

Odpowiadanie

Odpowiadaj szybko dowolnym 2xx i wykonuj właściwą pracę asynchronicznie; wszystko inne liczy się jako błąd i planuje ponowną próbę. Dostarczenia mogą przychodzić w złej kolejności i, rzadko, więcej niż raz; użyj webhook-id dla idempotencji.