Skip to content

Instantly share code, notes, and snippets.

@miguelestrada
Created November 18, 2016 14:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save miguelestrada/e172c49fe0e122833eb0a96833cfd317 to your computer and use it in GitHub Desktop.
Save miguelestrada/e172c49fe0e122833eb0a96833cfd317 to your computer and use it in GitHub Desktop.
Sample event listener
/*eslint-env node, express*/
// This application uses express as its web server
// for more info, see: http://expressjs.com
var express = require("express");
var crypto = require("crypto");
var WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;
const WEBHOOK_CALLBACK = "/webhook_callback";
var WEBHOOK_VERIFICATION_TOKEN_HEADER="X-OUTBOUND-TOKEN".toLowerCase();
var WEBHOOK_ORDER_INDEX_HEADER="X-OUTBOUND-INDEX".toLowerCase();
var WEBHOOK_RETRY_COUNT_HEADER="X-OUTBOUND-RETRY-COUNT".toLowerCase();
// create a new express server
var app = express();
// serve the files out of ./public as our main files
app.use(express.static(__dirname + "/public"));
function rawBody(req, res, next) {
var buffers = [];
req.on("data", function(chunk) {
buffers.push(chunk);
});
req.on("end", function(){
req.rawBody = Buffer.concat(buffers);
next();
});
}
function errorHandler(err, req, res, next) {
if (res.headersSent) {
return next(err);
}
res.status(500);
res.render("error", { error: err });
}
app.use(rawBody);
app.use(errorHandler);
app.listen(process.env.PORT || 3000, () => {
console.log("app is listening on port: " + (process.env.PORT || 3000));
console.log("\n");
});
app.post(WEBHOOK_CALLBACK, function(req, res) {
if (!verifySender(req.headers, req.rawBody)) {
console.log("Cannot verify caller ! -------------");
console.log(req.rawBody.toString());
res.status(200).end();
return;
}
var body = JSON.parse(req.rawBody.toString());
var stringJsonbody = JSON.stringify(body);
var eventType = body.type;
if (eventType === "verification")
handleVerificationRequest(res, body.challenge);
else {
var orderIndex = req.headers[WEBHOOK_ORDER_INDEX_HEADER];
var retryCount = req.headers[WEBHOOK_RETRY_COUNT_HEADER];
console.log("X-OUTBOUND-ORDER-INDEX, OUTBOUND-RETRY-COUNT: " + orderIndex + ", " + retryCount);
console.log(stringJsonbody);
console.log("Event original time:" + Date (body.time));
console.log("Latency: " + (Date.now() - body.time) );
res.status(200).end();
}
});
function verifySender(headers, rawbody)
{
var headerToken = headers[WEBHOOK_VERIFICATION_TOKEN_HEADER];
var endpointSecret = WEBHOOK_SECRET;
var expectedToken = crypto
.createHmac("sha256", endpointSecret)
.update(rawbody)
.digest("hex");
if (expectedToken === headerToken) {
return Boolean(true);
}
return Boolean(false);
}
function handleVerificationRequest(response, challenge)
{
var responseBodyObject = { "response" : challenge };
var responseBodyString = JSON.stringify(responseBodyObject);
var endpointSecret = WEBHOOK_SECRET;
var responseToken = crypto
.createHmac("sha256", endpointSecret)
.update(responseBodyString)
.digest("hex");
response.writeHead(200,
{
"Content-Type" : "application/json; charset=utf-8",
"X-OUTBOUND-TOKEN" : responseToken
});
response.end(responseBodyString);
console.log ("Verification request processed");
// console.log("VERIFICATION BODY: " + responseBodyString);
// console.log("VERIFICATION X-OUTBOUND-TOKEN: " + responseToken);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment