Webhooks are automated messages sent from apps when something happens. They are a type of API that sends information from one application to another in real-time, without the need for constant polling. Think of them as an event-driven communication channel.
Instead of your application having to repeatedly ask a service, "Has anything new happened?", a webhook allows the service to proactively tell your application, "Something new has happened!" as soon as it occurs.
The process typically involves the following steps:
Source App (e.g., GitHub) -> HTTP POST Request (Payload: Commit Info) -> Your App's Webhook Endpoint -> Process Payload & Update Database
To receive webhooks, you need to expose an HTTP endpoint (a URL) on your server that can accept POST requests. Here's a conceptual outline of how you might set this up:
const express = require('express');
const bodyParser = require('body-parser');
const crypto = require('crypto'); // For signature verification
const app = express();
const PORT = process.env.PORT || 3000;
// Middleware to parse JSON request bodies
app.use(bodyParser.json());
// Middleware to verify webhook signature (optional but recommended)
const verifySignature = (req, res, next) => {
const secret = 'YOUR_WEBHOOK_SECRET'; // Keep this secret!
const signature = req.headers['x-hub-signature-256'] || req.headers['signature']; // Check common header names
if (!signature) {
return res.status(400).send('Signature header missing');
}
const payload = JSON.stringify(req.body);
const hmac = crypto.createHmac('sha256', secret);
hmac.update(payload);
const expectedSignature = `sha256=${hmac.digest('hex')}`;
if (crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature))) {
next(); // Signature is valid
} else {
res.status(401).send('Invalid signature');
}
};
// Define your webhook endpoint
app.post('/webhook/listen', verifySignature, (req, res) => {
console.log('Received webhook payload:', req.body);
// Process the event data
const eventType = req.body.event_type; // Example field
if (eventType === 'new_order') {
// Handle new order logic
console.log('New order received:', req.body.data);
// Update database, send email, etc.
} else if (eventType === 'payment_success') {
// Handle payment success
console.log('Payment successful:', req.body.data);
}
// ... handle other event types
// Respond with a 200 OK to acknowledge receipt
res.sendStatus(200);
});
app.listen(PORT, () => {
console.log(`Webhook server listening on port ${PORT}`);
});
You'll need to go to the settings of the application sending the webhook (e.g., Stripe, GitHub, Slack) and provide your webhook URL (e.g., https://yourdomain.com/webhook/listen) and potentially any required secrets or event filters.
{
"ref": "refs/heads/main",
"before": "a1b2c3d4e5f6...",
"after": "f6e5d4c3b2a1...",
"commits": [
{
"id": "f6e5d4c3b2a1...",
"message": "Add webhook documentation",
"url": "https://github.com/user/repo/commit/f6e5d4c3b2a1...",
"author": {
"name": "Your Name",
"email": "your.email@example.com",
"username": "yourusername"
},
"committer": {
"name": "Your Name",
"email": "your.email@example.com",
"username": "yourusername"
},
"timestamp": "2023-10-27T10:00:00Z",
"added": ["README.md"],
"modified": [],
"removed": []
}
],
"repository": {
"id": 123456789,
"name": "repo",
"full_name": "user/repo",
"owner": {
"login": "user",
"id": 987654321,
// ... other owner details
},
// ... other repository details
},
"pusher": {
"name": "user",
"email": "user@example.com"
},
// ... other fields
}