I recently converted a Fastify application handling 2Hire webhooks to Express.js. However, the webhook URL isn't triggering as I expected.
2Hire webhooks Subscription API Doc: https://developer.2hire.io/reference/subscribe-1
2Hire webhooks Receiving signals Doc: https://developer.2hire.io/docs/receiving-signals
Error
{"message": {"code": "CHALLENGE_ERROR","errorId": "2c31cx-x-x-x-x82034a925","details": {"cause": "CHALLENGE_FAILED" } }}
Despite setting up the raw body correctly and configuring the endpoint, the webhook does not trigger when tested.
Can anyone help identify what might be going wrong or what I may have missed in the conversion?
Below is the core part of my implementation:
const express = require('express');const bodyParser = require('body-parser');const crypto = require('crypto');const dotenv = require('dotenv');dotenv.config();const app = express();const SECRET = process.env.SECRET;const PORT = 8080;const signalNames = new Set(["online", "position", "distance_covered", "autonomy_percentage", "autonomy_meters", "*"]);function isSignal(signal) { return signalNames.has(signal);}function validateTopic(topic) { const parts = topic.split(":"); return parts.length === 4 && parts[0] === "vehicle" && parts[2] === "generic" && isSignal(parts[3]);}function generateSignature(message, secret) { const hmac = crypto.createHmac('sha256', secret); hmac.update(message, 'utf8'); return `sha256=${hmac.digest('hex')}`;}app.use(bodyParser.json({ verify: (req, res, buf) => { req.rawBody = buf.toString(); }}));app.get('/listener', (req, res) => { const { 'hub.mode': mode, 'hub.topic': topic, 'hub.challenge': challenge } = req.query; if (!validateTopic(topic) || mode !== 'subscribe') { res.status(400).send('Validation error'); } else { res.send(challenge); }});app.post('/listener', (req, res) => { const signature = req.headers['x-hub-signature']; const computedSignature = generateSignature(req.rawBody, SECRET); if (!validateTopic(req.body.topic) || signature !== computedSignature) { res.status(401).send('Invalid signature or topic'); } else { console.log("Webhook Received: ", req.body); res.send('Webhook received'); }});app.listen(PORT, () => { console.log(`Server listening on http://localhost:${PORT}`);});