Skip to content

Instantly share code, notes, and snippets.

@ruby0x1
Last active May 10, 2019 02:41
Show Gist options
  • Save ruby0x1/597443bc08b64e0d07ff9ca802578a48 to your computer and use it in GitHub Desktop.
Save ruby0x1/597443bc08b64e0d07ff9ca802578a48 to your computer and use it in GitHub Desktop.
A simple example of a validated github webhook using node.js
//A simple example of a github webhook using node.js
//To correctly set up:
// Inside a file named `.env`, in the same directory the app runs,
// place a line with WEBHOOK_SECRET='...'
// The secret value must match the secret you give github on their UI.
//That's it. run with `node app.js` and point github at <url>/mywebhook.
//(Prbably put it behind nginx if you do make it public facing)
'use strict';
//loads the .env file for us,
//making secrets available on process.env
require('dotenv').config()
const express = require("express");
const bodyparser = require("body-parser");
const crypto = require("crypto");
var app = express();
function validate(req) {
if (!req.headers['user-agent'].includes('GitHub-Hookshot/')) return false;
const secret = process.env.WEBHOOK_SECRET; //comes from the .env file alongside the app
const payload = JSON.stringify(req.body);
const theirs = req.headers['x-hub-signature'];
const ours = `sha1=${crypto.createHmac('sha1', secret).update(payload).digest('hex')}`;
return crypto.timingSafeEqual(Buffer.from(theirs), Buffer.from(ours));
};
app.use(bodyparser.json());
app.post("/mywebhook", function (req, res) {
if(!validate(req)) return res.sendStatus(403);
console.log('do things here...');
res.end();
});
var server = app.listen(9999, function () {
console.log("webhook running on port ", server.address().port);
});
@ruby0x1
Copy link
Author

ruby0x1 commented May 10, 2019

I should probably mention the dependency for package.json

"dependencies": {
    "body-parser": "^1.19.0",
    "dotenv": "^8.0.0",
    "express": "^4.16.4"
  },

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment