Veiledning for webhooks

Sist oppdatert: 15. oktober 2025

1. Oversikt

Med webhooks kan du reagere på vaktendringer i sanntid. Når en medarbeider får en vakt, vakten endres eller tildelingen fjernes, sender ShiftScheduler en HTTP POST til URL-en din.

2. Aktivering av webhooks

  1. Åpne Innstillinger → Webhooks.
  2. Angi HTTPS-endepunktet som skal motta hendelser.
  3. Valgfritt: Angi en delt hemmelighet for å signere innholdet med HMAC-SHA256.

Du kan endre URL eller hemmelighet når som helst. Endringene trer i kraft umiddelbart.

3. Hendelser som sendes

| Hendelse | Utløses når … |
| ----- | --------------- |
| `shift.created` | En ny vakt opprettes i appen eller via REST API-et. |
| `shift.updated` | En eksisterende vakt endres (datoer, klokkeslett, merknad, arbeidssted eller medarbeider). |
| `shift.deleted` | En vakt slettes. |

Alle hendelser inneholder de fullstendige vaktdataene, slik at du kan speile tilstanden i ShiftScheduler uten et ekstra API-kall.

4. Forespørselsformat

Hver webhook-POST har følgende headere:

| Header | Beskrivelse |
| ------ | ----------- |
| `Content-Type` | Alltid `application/json`. |
| `X-ShiftScheduler-Event` | Hendelsesnavn (f.eks. `shift.updated`). |
| `X-ShiftScheduler-Signature` | Heksadesimal HMAC SHA-256-signatur (bare med når en hemmelig webhook-nøkkel er konfigurert). |

JSON-innholdet ser slik ut:

{
  "event": "shift.created",
  "workspaceId": "64f1088d4f3c2c0012b12345",
  "timestamp": "2025-10-15T09:21:34.512Z",
  "data": {
    "id": "6717a347e1577b0b4e9fd200",
    "location": { "id": "6702ac44e1577b0b4e9fd100", "title": "Website Refresh" },
    "person": { "id": "66fa6f3be1577b0b4e9fd001", "name": "Hana Sato" },
    "date": "2025-10-20",
    "startTime": "09:00",
    "endTime": "17:00",
    "breakMinutes": 30,
    "note": "Workshop preparation"
  }
}

5. Verifisering av signaturer

Når en hemmelighet er angitt, sammenligner du headeren X-ShiftScheduler-Signature med din egen HMAC-beregning:

const crypto = require('crypto');

function verifySignature(secret, payload, signature) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(payload))
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature || '', 'hex'),
    Buffer.from(expected, 'hex')
  );
}

Bruk en sammenligning med konstant kjøretid for å unngå informasjonslekkasje ved feil signatur.

6. Feilhåndtering og nye forsøk

Webhooks sendes i bakgrunnen og blokkerer ikke grensesnittet eller API-svar. Hvis endepunktet returnerer en statuskode utenfor 2xx-serien eller ikke kan nås, logges hendelsen, men den sendes ikke på nytt automatisk. Vi anbefaler en idempotent mottaker som svarer raskt, for eksempel ved å legge arbeidet i en kø.