Best Practices
Production-ready webhook handling: respond fast, handle duplicates, queue processing, error handling, and monitoring.
Follow these practices to build reliable, production-ready webhook handlers.
Respond Quickly
Return a 2xx status code as fast as possible. GitScrum expects a response within 30 seconds. If your processing takes longer, acknowledge receipt immediately and process asynchronously.
Queue-Based Processing
Decouple receiving from processing using a message queue:
const Queue = require('bull');
const webhookQueue = new Queue('webhooks');
app.post('/webhooks/gitscrum', (req, res) => {
// Acknowledge immediately
res.status(200).json({ received: true });
// Queue for async processing
webhookQueue.add(req.body);
});
webhookQueue.process(async (job) => {
const event = job.data;
// Heavy processing here: database writes, API calls, notifications
await processWebhook(event);
});from celery import Celery
celery_app = Celery('webhooks', broker='redis://localhost:6379')
@app.route('/webhooks/gitscrum', methods=['POST'])
def webhook():
event = request.get_json()
# Acknowledge immediately
process_webhook.delay(event)
return jsonify({"received": True}), 200
@celery_app.task
def process_webhook(event):
# Heavy processing here
passHandle Duplicates
The same event may be delivered more than once. Design your handler to be idempotent — processing the same event twice should produce the same result.
Use the UUID as Idempotency Key
const processedEvents = new Set(); // Use Redis in production
webhookQueue.process(async (job) => {
const { data } = job.data;
const eventId = data.uuid;
// Skip if already processed
if (processedEvents.has(eventId)) {
console.log(`Skipping duplicate: ${eventId}`);
return;
}
processedEvents.add(eventId);
await processWebhook(job.data);
});Error Handling
Catch All Exceptions
Never let your webhook handler crash. Wrap processing in error handling:
app.post('/webhooks/gitscrum', async (req, res) => {
try {
// Always respond 200 first
res.status(200).json({ received: true });
await processWebhook(req.body);
} catch (error) {
console.error('Webhook processing error:', error);
// Log the error but don't crash the server
}
});Log Everything
Log all incoming webhooks for debugging and audit:
app.post('/webhooks/gitscrum', (req, res) => {
const timestamp = new Date().toISOString();
const headers = {
'x-header': req.headers['x-header'],
'user-agent': req.headers['user-agent'],
};
console.log(JSON.stringify({
timestamp,
headers,
body: req.body,
}));
res.status(200).json({ received: true });
});Monitoring
Track Delivery Success Rates
Monitor your webhook endpoint for:
- Response time (keep under 5 seconds)
- Error rates (5xx responses)
- Payload size
- Processing queue depth
Health Check Endpoint
Add a health check alongside your webhook endpoint:
app.get('/webhooks/health', (req, res) => {
res.status(200).json({
status: 'healthy',
queue_depth: webhookQueue.getJobCount(),
uptime: process.uptime(),
});
});Event Filtering
If you use the same endpoint URL for multiple events, filter by checking the payload structure:
app.post('/webhooks/gitscrum', (req, res) => {
res.status(200).json({ received: true });
const { data } = req.body;
// Route based on payload structure
if (data.workflow) {
handleTaskEvent(data);
} else if (data.time_box) {
handleSprintEvent(data);
} else if (data.acceptance_criteria) {
handleUserStoryEvent(data);
}
});Environment Separation
Use different webhook endpoints for different environments:
| Environment | Endpoint |
|---|---|
| Development | https://dev.your-server.com/webhooks/gitscrum |
| Staging | https://staging.your-server.com/webhooks/gitscrum |
| Production | https://your-server.com/webhooks/gitscrum |
Configure separate GitScrum projects for each environment and point webhooks to the matching endpoint.
Testing with ngrok
During development, use a tunneling tool like ngrok to expose your local server:
# Start your local server on port 3000
node server.js
# In another terminal, start ngrok
ngrok http 3000Copy the ngrok HTTPS URL and paste it into your GitScrum webhook configuration. This allows you to test webhooks against your local development server.
Related
- Quick Start — Set up your first webhook
- Security — Secure your webhook endpoints
- Troubleshooting — Common issues and fixes