Also adding Patrick to the answer, I recommend using Express with body-parser along with it. Full example below. This works with Express 4.x, Node 8.x (the last since it was written).
Please replace YOUR_WEBHOOK_SECRET_HERE and do something in authorizationSuccessful .
// Imports const express = require('express'); const bodyParser = require('body-parser'); const crypto = require('crypto'); const app = express(); // The GitHub webhook MUST be configured to be sent as "application/json" app.use(bodyParser.json()); // Verification function to check if it is actually GitHub who is POSTing here const verifyGitHub = (req) => { if (!req.headers['user-agent'].includes('GitHub-Hookshot')) { return false; } // Compare their hmac signature to our hmac signature // (hmac = hash-based message authentication code) const theirSignature = req.headers['x-hub-signature']; const payload = JSON.stringify(req.body); const secret = 'YOUR_WEBHOOK_SECRET_HERE'; // TODO: Replace me const ourSignature = `sha1=${crypto.createHmac('sha1', secret).update(payload).digest('hex')}`; return crypto.timingSafeEqual(Buffer.from(theirSignature), Buffer.from(ourSignature)); }; const notAuthorized = (req, res) => { console.log('Someone who is NOT GitHub is calling, redirect them'); res.redirect(301, '/'); // Redirect to domain root }; const authorizationSuccessful = () => { console.log('GitHub is calling, do something here'); // TODO: Do something here }; app.post('*', (req, res) => { if (verifyGitHub(req)) { // GitHub calling authorizationSuccessful(); res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Thanks GitHub <3'); } else { // Someone else calling notAuthorized(req, res); } }); app.all('*', notAuthorized); // Only webhook requests allowed at this address app.listen(3000); console.log('Webhook service running at http://localhost:3000');
source share