Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch webhook node.js

I'm trying to catch a PUT/webhook request that is being made by the Aftership API in node.js. A PUT request is made each time a push notification is needed to be made, I am using Parse to send the notifications but I need some of the data from the webhook.

The header of the webhook looks like Content-Type: application/json And contains this data:

ts - UTC unix timestamp that the event occurred

event - the name of the event (for tracking update, the value will be 'tracking_update')

msg - details about the message for which the event occurred, in the following format.

How would I go about getting the tracking number, slug and the value for token in the custom fields dictionary in node or js?

{
    "event": "tracking_update",
    "msg": {
        "id": "53aa94fc55ece21582000004",
        "tracking_number": "906587618687",
        "title": "906587618687",
        "origin_country_iso3": null,
        "destination_country_iso3": null,
        "shipment_package_count": 0,
        "active": false,
        "order_id": null,
        "order_id_path": null,
        "customer_name": null,
        "source": "web",
        "emails": [],
        "custom_fields": {},
        "tag": "Delivered",
        "tracked_count": 1,
        "expected_delivery": null,
        "signed_by": "D Johnson",
        "shipment_type": null,
        "tracking_account_number": null,
        "tracking_postal_code": "DA15BU",
        "tracking_ship_date": null,
        "created_at": "2014-06-25T09:23:08+00:00",
        "updated_at": "2014-06-25T09:23:08+00:00",
        "slug": "dx",
        "unique_token": "xk7LesjIgg",
        "checkpoints": [{
            "country_name": null,
            "country_iso3": null,
            "state": null,
            "city": null,
            "zip": null,
            "message": "Signed For by: D Johnson",
            "coordinates": [],
            "tag": "Delivered",
            "created_at": "2014-06-25T09:23:11+00:00",
            "checkpoint_time": "2014-05-02T16:24:38",
            "slug": "dx"
        }]
    },
    "ts": 1403688191
}
like image 412
Clip Avatar asked Jan 09 '15 01:01

Clip


3 Answers

It can be done with Express framework, example:

var express = require('express'),
    bodyParser = require('body-parser'),
    app = express(),
    port = 3000;

app.use(bodyParser.json());

app.post('/', function (req, res) {
    var body = req.body;
    var trackingNumber = body.msg.tracking_number;
    var slug = body.msg.slug;
    var token = body.msg.unique_token;

    console.log(trackingNumber, slug, token);

    res.json({
        message: 'ok got it!'
    });
});

var server = app.listen(port, function () {

    var host = server.address().address
    var port = server.address().port

    console.log('Example app listening at http://%s:%s', host, port)

});

Here is the GIT repository, just clone it and do npm install and then npm start. The server will run on port 3000 :D

Note: I saw in Aftership Webhook's documentation, it said they will request POST HTTP method, not PUT so I create an example of post request. Just replace it with put if you want it to catch put request.

like image 122
Andi N. Dirgantara Avatar answered Sep 21 '22 11:09

Andi N. Dirgantara


For inspecting webhooks data, I would suggest to store every request in database and then query database. As each request is different, easiest way would be creating API in sails.js (Node.js framework with easy to use ORM).

sudo npm install sails -g
sails new _project_name_
cd _project_name_
sails generate api Records

With last command, sails has generated controller and model to store your webhook data.

I suggest installing pm2 for running app. you can run it with

pm2 start app.js

Next you should configure your webhook in Aftership for following url:

YOUR_SERVER_IP:PORT/Records/create

you can inspect data by following url:

YOUR_SERVER_IP:PORT/Records/find

if you want to parse data, it can be done in RecordsController.js, for example:

Parsing: function(req, res) {

    Records.find({}).exec(function(err, results) {

        var output = [];

        while (results.length) {
            var result = results.pop();
            //custom parsing goes here
            //example:
            output.push({
                tracking_number: result.msg.tracking_number,
                slug: result.msg.slug,
                unique_token: result.msg.unique_token
            });
        }
        return res.json(output);
    });


},

You can call this method via following url: YOUR_SERVER_IP:PORT/Records/Parsing

I have created project in Codeanywhere for demonstration

webhook endpoint is: http://port-1337.zavtt4t8a0jm7vigncyo3txxmuhxgvix3yxk66pvydgqfr.box.codeanywhere.com/records/create

For inspecting data, just replace /create part of url to /find

git repo is here: https://github.com/dkatavic/webhook_for_aftership

you can just clone the project on your server and run it (or use my server for testing)

like image 25
dkatavic Avatar answered Sep 23 '22 11:09

dkatavic


You can catch PUT request by

app.put('/someRouteToCatchWebHook', function(request, response) {
  //webhook parsing goes here
});

(i'm sure that you use expressjs in your code - see http://expressjs.com/api.html#app.METHOD for details).

If the webhook data is in request body, you can use the https://www.npmjs.com/package/body-parser module for parsing it.

like image 20
vodolaz095 Avatar answered Sep 22 '22 11:09

vodolaz095