Sign Up
Sign Up
← All guides

Send leave request notifications to Slack with Collabin webhooks

When someone requests leave, the people who need to know should find out where they already work β€” in Slack. This guide wires Collabin's webhooks to a Slack channel, end to end: you'll subscribe to leave events, verify each delivery cryptographically, and post a formatted message. The same pattern works for Microsoft Teams, Discord, n8n, Make, or any internal system.

How Collabin webhooks work

A webhook is an HTTPS endpoint you host; Collabin calls it with a POST request whenever a subscribed event happens. Two events are available:

EventFired when
leave.createda new leave request is submitted
leave.status_changeda request is approved or rejected

Every delivery is a JSON envelope:

{
  "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": "Jane Doe" },
    "leave_type_id": 1,
    "leave_type": { "id": 1, "name": "Vacation" },
    "start_date": "2026-07-01T00:00:00Z",
    "end_date": "2026-07-05T00:00:00Z",
    "is_half_day": false,
    "status": "PENDING"
  }
}

Three headers accompany every request:

  • X-Collabin-Event β€” the event name, so you can route without parsing the body.
  • X-Collabin-Delivery β€” a unique delivery ID, handy for de-duplication and log correlation.
  • X-Collabin-Signature β€” sha256=<hex>, an HMAC-SHA256 of the raw request body computed with your webhook's secret. Always verify this before trusting the payload.

Collabin waits up to 10 seconds and treats any 2xx response as success β€” respond quickly and do the heavy lifting asynchronously.

What you'll need

  • A Collabin account on the Pro plan (webhook management requires it).
  • A Slack workspace where you can create an incoming webhook.
  • Somewhere to run ~40 lines of Node.js: a small VPS, Cloud Run, a serverless function β€” anything with a public HTTPS URL.

Step 1: Create a Slack incoming webhook

In Slack, create an app (or use an existing one), enable Incoming Webhooks, and add one for the channel where notifications should land. Slack gives you a URL like https://hooks.slack.com/services/T000/B000/XXXX. Keep it secret.

Step 2: Deploy the bridge

This small Express server verifies Collabin's signature and forwards a readable message to Slack:

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();
// Keep the raw body β€” the signature is computed over the exact bytes.
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');
  }

  // Acknowledge immediately; Collabin only needs a 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 : `user #${leave.user_id}`;
  const type = leave.leave_type ? leave.leave_type.name : 'Leave';
  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}* requested *${type}* from *${from}* to *${to}*`
    : `:bell: ${type} request of *${who}* (${from} – ${to}) is now *${leave.status}*`;

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

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

Two details matter more than they look:

  1. Verify against the raw body. If your framework parses JSON first and you re-serialize it, key order or whitespace changes break the HMAC. Read the exact bytes.
  2. Use a constant-time comparison (crypto.timingSafeEqual) so the check doesn't leak timing information.

Step 3: Register the webhook in Collabin

  1. In your Collabin dashboard, open Webhooks.
  2. Add a new webhook: paste your endpoint URL and select the events (leave.created, leave.status_changed, or both).
  3. Collabin assigns the webhook a secret β€” copy it into the COLLABIN_WEBHOOK_SECRET environment variable of your bridge.

Submit a test leave request, and the message should appear in Slack within a second or two.

Operating notes

  • No automatic retries. Delivery is fire-and-forget: if your endpoint is unreachable or returns a non-2xx status, that event is not re-sent β€” but the failed attempt is recorded in Collabin's system error log, so you can see exactly what went wrong and when.
  • Deactivate instead of delete when debugging: a webhook can be toggled inactive and re-enabled later without re-entering its configuration.
  • One webhook per consumer. Each webhook has its own secret; give every downstream system its own registration rather than sharing one endpoint.

Beyond Slack

The bridge above is deliberately minimal. With the same verified payload you can mark people out-of-office automatically, sync to an internal HR system, or feed a no-code tool β€” point an n8n or Make webhook trigger at Collabin, and use a function step for the signature check.