lexguard-backend / src /services /webhookDispatcher.js
github-actions[bot]
Deploy to Hugging Face
b921752
Raw
History Blame Contribute Delete
2.21 kB
const Webhook = require('../models/Webhook');
const Contract = require('../models/Contract');
const crypto = require('crypto');
async function dispatchWebhooks(event, contractId, payload = {}) {
try {
const contract = await Contract.findById(contractId).select('userId originalFileName status overallRiskLevel');
if (!contract) return;
// Find all active webhooks for this user that subscribe to this event
const webhooks = await Webhook.find({
userId: contract.userId,
isActive: true,
events: event
});
if (webhooks.length === 0) return;
const eventPayload = {
event,
contractId: contract._id,
fileName: contract.originalFileName,
status: contract.status,
overallRiskLevel: contract.overallRiskLevel,
timestamp: new Date().toISOString(),
...payload
};
const payloadString = JSON.stringify(eventPayload);
// Fire off all webhooks concurrently
await Promise.allSettled(
webhooks.map(async (webhook) => {
const headers = {
'Content-Type': 'application/json',
'User-Agent': 'LexGuard-Webhook-Dispatcher/1.0'
};
// Add HMAC signature if secret exists
if (webhook.secret) {
const signature = crypto.createHmac('sha256', webhook.secret).update(payloadString).digest('hex');
headers['X-LexGuard-Signature'] = `sha256=${signature}`;
}
try {
const response = await fetch(webhook.targetUrl, {
method: 'POST',
headers,
body: payloadString
});
if (!response.ok) {
console.error(`⚠️ [Webhook Dispatcher] Failed to deliver ${event} to ${webhook.targetUrl}. Status: ${response.status}`);
} else {
console.log(`✅ [Webhook Dispatcher] Delivered ${event} to ${webhook.targetUrl}`);
}
} catch (fetchErr) {
console.error(`❌ [Webhook Dispatcher] Error delivering to ${webhook.targetUrl}:`, fetchErr.message);
}
})
);
} catch (error) {
console.error('❌ [Webhook Dispatcher] Critical failure:', error.message);
}
}
module.exports = { dispatchWebhooks };