|
| 1 | +# urBackend Webhooks Guide |
| 2 | + |
| 3 | +Webhooks allow you to build event-driven applications by letting urBackend notify your custom external servers (like Next.js API routes, AWS Lambda, or Discord via Zapier) the absolute second data is added, updated, or removed from your database. |
| 4 | + |
| 5 | +## Securing Your Webhooks (HMAC Verification) |
| 6 | + |
| 7 | +Webhooks are sent as raw HTTP `POST` requests to a URL you configure. Because your webhook URL is public, anyone could theoretically send data to it. |
| 8 | + |
| 9 | +To prove that the data came **only from urBackend**, every payload is signed using your project's unique "Signing Secret" (which you can generate or copy from the Webhooks Dashboard). |
| 10 | + |
| 11 | +### How it Works |
| 12 | + |
| 13 | +1. You create a Webhook in the urBackend Dashboard and either copy the auto-generated **Signing Secret** (e.g. `whsec_xyz123...`) or enter your own. |
| 14 | +2. When a data event occurs (like a new User signing up), urBackend packages the JSON data and computes an `HMAC-SHA256` signature using your secret. |
| 15 | +3. This signature is attached to the outgoing request in the `X-urBackend-Signature` header. |
| 16 | +4. Your server receives the request, performs the exact same HMAC math, and accepts the webhook only if the signatures match. |
| 17 | + |
| 18 | +### Code Example (Node.js/Express) |
| 19 | + |
| 20 | +Here is a copy-paste code snippet on how to safely verify an incoming urBackend webhook event. |
| 21 | + |
| 22 | +```javascript |
| 23 | +const express = require('express'); |
| 24 | +const crypto = require('crypto'); |
| 25 | +const app = express(); |
| 26 | + |
| 27 | +// The secret provided by your urBackend Dashboard |
| 28 | +const URBACKEND_WEBHOOK_SECRET = process.env.URBACKEND_WEBHOOK_SECRET; |
| 29 | + |
| 30 | +app.post('/urbackend-webhook', express.json(), (req, res) => { |
| 31 | + // 1. Extract the signature header sent by urBackend |
| 32 | + const signature = req.headers['x-urbackend-signature']; |
| 33 | + |
| 34 | + // 2. Convert the raw request body payload to string |
| 35 | + const payload = JSON.stringify(req.body); |
| 36 | + |
| 37 | + // 3. Compute the expected digest using HMAC-SHA256 |
| 38 | + const expectedSignature = crypto |
| 39 | + .createHmac('sha256', URBACKEND_WEBHOOK_SECRET) |
| 40 | + .update(payload) |
| 41 | + .digest('hex'); |
| 42 | + |
| 43 | + // 4. Safely compare the signatures |
| 44 | + if (!signature || signature !== expectedSignature) { |
| 45 | + console.error("⚠️ Webhook verification failed! Potential spoofing attempt."); |
| 46 | + return res.status(401).send("Invalid signature"); |
| 47 | + } |
| 48 | + |
| 49 | + // 5. Success! The event is authentic. |
| 50 | + const { event, collection, payload: data } = req.body; |
| 51 | + |
| 52 | + console.log(`✅ Received authentic ${event} event on ${collection}`); |
| 53 | + console.log("Record ID:", data._id); |
| 54 | + |
| 55 | + // Always return a 200/20x as fast as possible to prevent timeouts |
| 56 | + res.status(200).send("Webhook received"); |
| 57 | +}); |
| 58 | + |
| 59 | +app.listen(3000, () => console.log('Webhook server running on port 3000')); |
| 60 | +``` |
| 61 | + |
| 62 | +## Retry Logic |
| 63 | + |
| 64 | +If your server takes too long to respond (timeout exceeding 10 seconds) or returns a `4xx / 5xx` HTTP status code, urBackend will mark the delivery as `failed`. The Webhook Dashboard provides a full "Delivery History" panel so you can inspect the exact payload, replay failed attempts, and debug your endpoint. |
0 commit comments