-
-
Save miguelestrada/e172c49fe0e122833eb0a96833cfd317 to your computer and use it in GitHub Desktop.
Sample event listener
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*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