Zarejestruj się
Zarejestruj się
Wszystkie przewodniki

Wysyłaj powiadomienia o wnioskach urlopowych na Slacka za pomocą webhooków Collabin

Gdy ktoś składa wniosek o urlop, osoby, które powinny o tym wiedzieć, powinny się o tym dowiedzieć tam, gdzie już pracują — na Slacku. Ten przewodnik krok po kroku łączy webhooki Collabin z kanałem Slack: zasubskrybujesz zdarzenia urlopowe, zweryfikujesz kryptograficznie każdą dostawę i wyślesz sformatowaną wiadomość. Ten sam wzorzec działa z Microsoft Teams, Discordem, n8n, Make lub każdym innym wewnętrznym systemem.

Jak działają webhooki Collabin

Webhook to endpoint HTTPS, który hostujesz samodzielnie; Collabin wywołuje go żądaniem POST zawsze, gdy wystąpi zasubskrybowane zdarzenie. Dostępne są dwa zdarzenia:

ZdarzenieWywoływane, gdy
leave.createdzostanie złożony nowy wniosek o urlop
leave.status_changedwniosek zostanie zatwierdzony lub odrzucony

Każda dostawa to koperta JSON:

{
  "event": "leave.created",
  "timestamp": "2026-06-13T09:30:00Z",
  "delivery_id": "f3a91c0d2b8e4a17",
  "organization_id": 42,
  "data": {
    "id": 1337,
    "user_id": 7,
    "user": { "id": 7, "name": "Jan Kowalski" },
    "leave_type_id": 1,
    "leave_type": { "id": 1, "name": "Urlop wypoczynkowy" },
    "start_date": "2026-07-01T00:00:00Z",
    "end_date": "2026-07-05T00:00:00Z",
    "is_half_day": false,
    "status": "PENDING"
  }
}

Każdemu żądaniu towarzyszą trzy nagłówki:

  • X-Collabin-Event — nazwa zdarzenia, dzięki czemu można kierować ruch bez parsowania treści.
  • X-Collabin-Delivery — unikalny identyfikator dostawy, przydatny do deduplikacji i korelacji logów.
  • X-Collabin-Signaturesha256=<hex>, podpis HMAC-SHA256 surowej treści żądania, obliczony z użyciem tajnego klucza Twojego webhooka. Zawsze zweryfikuj ten podpis, zanim zaufasz danym.

Collabin czeka maksymalnie 10 sekund i traktuje każdą odpowiedź 2xx jako sukces — odpowiadaj szybko, a właściwą pracę wykonuj asynchronicznie.

Czego będziesz potrzebować

  • Konta Collabin w planie Pro (zarządzanie webhookami jest dostępne tylko w tym planie).
  • Przestrzeni roboczej Slack, w której możesz utworzyć incoming webhook.
  • Miejsca, w którym uruchomisz ~40 linii kodu Node.js: mały VPS, Cloud Run, funkcja serverless — cokolwiek z publicznym adresem URL HTTPS.

Krok 1: Utwórz incoming webhook w Slacku

W Slacku utwórz aplikację (lub użyj istniejącej), włącz Incoming Webhooks i dodaj webhook dla kanału, na który mają trafiać powiadomienia. Slack wygeneruje adres URL w formacie https://hooks.slack.com/services/T000/B000/XXXX. Traktuj go jako tajny.

Krok 2: Wdróż mostek (bridge)

Ten mały serwer Express weryfikuje podpis Collabin i przekazuje czytelną wiadomość do Slacka:

const crypto = require('crypto');
const express = require('express');

const COLLABIN_SECRET = process.env.COLLABIN_WEBHOOK_SECRET;
const SLACK_URL = process.env.SLACK_WEBHOOK_URL;

const app = express();
// Zachowujemy surową treść — podpis jest liczony dla dokładnych bajtów.
app.use(express.raw({ type: 'application/json' }));

app.post('/collabin-webhook', async (req, res) => {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', COLLABIN_SECRET)
    .update(req.body)
    .digest('hex');

  const received = req.get('X-Collabin-Signature') || '';
  const valid = received.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));

  if (!valid) {
    return res.status(401).send('invalid signature');
  }

  // Potwierdzamy natychmiast; Collabin potrzebuje tylko odpowiedzi 2xx.
  res.status(200).send('ok');

  const payload = JSON.parse(req.body.toString('utf8'));
  const leave = payload.data;
  const who = leave.user ? leave.user.name : `użytkownik #${leave.user_id}`;
  const type = leave.leave_type ? leave.leave_type.name : 'Urlop';
  const from = leave.start_date.slice(0, 10);
  const to = leave.end_date.slice(0, 10);

  const text = payload.event === 'leave.created'
    ? `:palm_tree: *${who}* złożył wniosek o *${type}* od *${from}* do *${to}*`
    : `:bell: wniosek *${who}* (${type}, ${from} – ${to}) ma teraz status *${leave.status}*`;

  await fetch(SLACK_URL, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ text })
  });
});

app.listen(process.env.PORT || 3000);

Dwa szczegóły są ważniejsze, niż się wydaje:

  1. Weryfikuj na podstawie surowej treści. Jeśli Twój framework najpierw parsuje JSON, a Ty go ponownie serializujesz, zmiana kolejności kluczy lub białych znaków zepsuje HMAC. Odczytuj dokładne bajty.
  2. Używaj porównania w czasie stałym (crypto.timingSafeEqual), aby sprawdzenie nie ujawniało informacji o czasie wykonania.

Krok 3: Zarejestruj webhook w Collabin

  1. W panelu Collabin otwórz Webhooki.
  2. Dodaj nowy webhook: wklej adres URL swojego endpointu i wybierz zdarzenia (leave.created, leave.status_changed lub oba).
  3. Collabin przypisze webhookowi tajny klucz — skopiuj go do zmiennej środowiskowej COLLABIN_WEBHOOK_SECRET swojego mostka.

Złóż testowy wniosek o urlop — wiadomość powinna pojawić się w Slacku w ciągu jednej lub dwóch sekund.

Uwagi operacyjne

  • Brak automatycznych ponownych prób. Dostawa działa na zasadzie „wyślij i zapomnij": jeśli Twój endpoint jest nieosiągalny lub zwróci status inny niż 2xx, zdarzenie nie zostanie wysłane ponownie — natomiast nieudana próba zostaje zapisana w dzienniku błędów systemowych Collabin, dzięki czemu wiesz dokładnie, co i kiedy poszło nie tak.
  • Dezaktywuj, nie usuwaj podczas debugowania: webhook można przełączyć na nieaktywny i później ponownie włączyć bez konieczności wprowadzania konfiguracji od nowa.
  • Jeden webhook na odbiorcę. Każdy webhook ma własny tajny klucz; każdemu systemowi docelowemu przypisz własną rejestrację, a nie jeden wspólny endpoint.

Poza Slackiem

Powyższy mostek jest celowo minimalny. Korzystając z tych samych zweryfikowanych danych, możesz automatycznie oznaczać osoby jako nieobecne, synchronizować z wewnętrznym systemem HR lub zasilać narzędzie no-code — wskaż trigger webhooka w n8n lub Make na Collabin, a weryfikację podpisu umieść w kroku typu function.