const express = require('express');
const rateLimit = require('express-rate-limit');
const helmet = require('helmet');
const app = express();
// Security middleware
app.use(helmet());
// Rate limiting
const webhookLimiter = rateLimit({
windowMs: 1 * 60 * 1000, // 1 minute
max: 100, // limit each IP to 100 requests per windowMs
message: 'Too many webhook requests from this IP',
standardHeaders: true,
legacyHeaders: false,
});
app.use('/webhooks', webhookLimiter);
// Health check endpoint
app.get('/health', (req, res) => {
res.status(200).json({
status: 'healthy',
timestamp: new Date().toISOString()
});
});
// Webhook endpoint
app.get('/webhooks/quickbutik', async (req, res) => {
const { event_type, order_id, product_id } = req.query;
// Log webhook receipt
console.log(`Webhook received: ${event_type}`, {
order_id,
product_id,
timestamp: new Date().toISOString(),
ip: req.ip
});
// Respond immediately
res.status(200).send('OK');
try {
// Add to processing queue
await addToQueue({
event_type,
order_id,
product_id,
received_at: new Date().toISOString()
});
} catch (error) {
console.error('Failed to queue webhook:', error);
// Send alert but don't fail the webhook response
await sendAlert({
type: 'webhook_queue_error',
event_type,
error: error.message
});
}
});
async function addToQueue(webhookData) {
// Add to Redis queue, SQS, or your preferred queue system
// This ensures webhook processing doesn't block the response
if (process.env.REDIS_URL) {
const redis = require('redis');
const client = redis.createClient({ url: process.env.REDIS_URL });
await client.lPush('webhook_queue', JSON.stringify(webhookData));
}
}
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Webhook server running on port ${PORT}`);
});