import Posthook from '@posthook/node';
import { Signatures, SignatureVerificationError } from '@posthook/node';
const posthook = new Posthook(process.env.POSTHOOK_API_KEY);
const signatures = new Signatures(process.env.POSTHOOK_SIGNING_KEY);
/* 1. Schedule */
async function onUserProfileUpdate(user) {
// Always schedule the sync for 5 minutes later
// Pass the creation time of THIS specific event
await posthook.hooks.schedule({
path: '/webhooks/sync/salesforce',
postIn: '5m',
data: {
userId: user.id,
triggeredAt: new Date().toISOString()
}
});
}
/* 2. Handle */
app.post('/webhooks/sync/salesforce', async (req, res) => {
try {
const delivery = signatures.parseDelivery(req.body, req.headers);
const { userId, triggeredAt } = delivery.data;
const user = await db.getUser(userId);
// STALE CHECK:
// If the user record has been updated SINCE this hook was scheduled,
// then a newer hook exists in the queue. We can safely skip this one.
if (new Date(user.updatedAt) > new Date(triggeredAt)) {
return res.status(200).send('Stale request, skipping');
}
// If timestamps match (or are very close), this is the latest action.
await salesforce.sync(user);
res.status(200).send('Synced');
} catch (err) {
if (err instanceof SignatureVerificationError) {
return res.status(401).json({ error: err.message });
}
throw err;
}
});