I’m running into issues with getting Calendly webhooks set up in my Node.js application. Even though I tried following the documentation carefully, something isn’t quite right.
Here’s how I approached the integration:
Step 1: I retrieved my user information by making a GET request to https://api.calendly.com/users/me
:
{
"resource": {
"avatar_url": null,
"created_at": "2024-05-22T09:45:15.000000Z",
"current_organization": "https://api.calendly.com/organizations/xyz456-1234-5678-abcd-xyz456789012",
"email": "[email protected]",
"name": "User Example",
"resource_type": "User",
"scheduling_url": "https://calendly.com/user-example",
"slug": "user-example",
"timezone": "Europe/London",
"updated_at": "2024-09-22T12:40:00.000000Z",
"uri": "https://api.calendly.com/users/abc123-4567-8901-cdef-abc123456789"
}
}
Step 2: I created a webhook subscription by sending a POST request to https://api.calendly.com/webhook_subscriptions
:
{
"url": "https://prod.api.user-app.com/calendly-webhook",
"events": [
"invitee.created",
"invitee.canceled",
"invitee_no_show.created",
"invitee_no_show.deleted"
],
"organization": "https://api.calendly.com/organizations/xyz456-1234-5678-abcd-xyz456789012",
"scope": "organization",
"signing_key": "3fQ8s9D-K58VuwXyAZsHykp7zBGD45JhZaLqk5h6j1M"
}
Step 3: I implemented the handler in Node.js:
const checkWebhookSignature = (request) => {
const receivedSignature = request.headers['calendly-webhook-signature'];
const secret = process.env.CALENDLY_SECRET;
const requestBody = JSON.stringify(request.body);
const hmacHash = crypto.createHmac('sha256', secret);
const generatedHash = hmacHash.update(requestBody).digest('hex');
return receivedSignature === generatedHash;
};
// WEBHOOK HANDLER FOR CALENDLY
ApiRouter.post('/calendly-webhook', async (req, res) => {
try {
console.log('Webhook payload received:');
if (!checkWebhookSignature(req)) {
return res.status(401).send('Signature mismatch');
}
const eventPayload = req.body;
switch (eventPayload.event) {
case 'invitee.created':
await handleInviteeCreation(eventPayload.payload);
break;
case 'invitee.canceled':
await handleAppointmentCancellation(eventPayload.payload);
break;
case 'invitee_no_show.created':
await handleNoShow(eventPayload.payload);
break;
case 'invitee_no_show.deleted':
await handleNoShowRemoval(eventPayload.payload);
break;
default:
console.log(`Unknown event received: ${eventPayload.event}`);
}
res.status(200).send('Webhook handled successfully');
} catch (error) {
console.error('Error handling Calendly webhook:', error);
res.status(500).send('Failed to handle the webhook');
}
});
When I try to test using Postman with this payload, I keep encountering “Signature mismatch”:
Header:
Calendly-Webhook-Signature: t=1694609256,v1=3fQ8s9D-K58VuwXyAZsHykp7zBGD45JhZaLqk5h6j1M
Body:
{
"event": "invitee.created",
"payload": {
"event": {
"start_time": "2024-10-05T15:00:00Z",
"end_time": "2024-10-05T15:30:00Z"
},
"invitee": {
"email": "[email protected]",
"name": "Test User"
}
}
}
I can’t seem to understand what could be causing the problem with the signature validation. Any insights or help would be appreciated!