Following on from my Git Hooks CI experiment, I thought I’d put my Digital Ocean Cloud VM to a little more work by checking out how to handle those shiny WebHooks that BitBucket provides.

What better way to do that than write your own WebHook endpoint from scratch!

What’s a WebHook?

A WebHook is just a fancy name for a URL that a service will invoke on a given event. When the event happens, the service will typically POST you a bunch of JSON about the event. All the A-list apps have WebHook support these days, including BitBucket and GitHub.

WebHooks are too cool for school.

Though, clearly, not as cool as Joe Bonamassa.


flickr photo shared by Dena Flows under a Creative Commons ( BY-NC-ND ) license

What do you get in the payload?

Glad you asked. Using my newfound passion for Yeoman, I generated a tiny express app to just listen and log a POST payload.

So what kinds of things do you get back from them? Tons of cool stuff…

{ repository:
   { scm: 'git',
     links: { avatar: [Object], self: [Object], html: [Object] },
     type: 'repository',
     is_private: true,
     full_name: 'glen_a_smith/webhook-sample',
     owner:
      { links: [Object],
        type: 'user',
        display_name: 'Glen Smith',
        uuid: '{0adfadf-adfa-adfa-adfa-adfadfadfadfa}',
        username: 'glen_a_smith' },
     name: 'blog',
     uuid: '{0adfadf-adfa-adfa-adfa-adfadfadfadfa}' },
  push: { changes: [ [Object] ] },
  actor:
   { links: { avatar: [Object], self: [Object], html: [Object] },
     type: 'user',
     display_name: 'Glen Smith',
     uuid: '{0adfadf-adfa-adfa-adfa-adfadfadfadfa}',
     username: 'glen_a_smith' } 
}

This is an example of the push payload which is sent to me everytime I check in a fresh commit to my webhook-sample repo. There’s lots of good stuff. Inside that push: { changes: [ ] } is even a detailed list of the changes in the commits you are receiving, but we’ll get to that in a second.

Setting up WebHooks in BitBucket

There are tons of good docs on the BitBucket site, and setting them up is just a couple of clicks away:

Adding Webhooks to BitBucket

Handling the JSON endpoint

So let’s get busy slurping up that JSON to give you a feel for the kinds of commit data you can extract out of the push. Here’s a scratchy express endpoint to get things started:

var express = require('express');
var router = express.Router();

/* WebHook Post entry point. */
router.post('/', function(req, res, next) {
        console.log("Webhook received!");
        console.log(req.body);
        console.log("Repo is " + req.body.repository.name);
        console.log("User is " + req.body.actor.username);
        req.body.push.changes.forEach(function (commit) {
            console.log("Branch/Tag is " + commit.new.name);
            console.log("Type is " + commit.new.type);
        });
        res.render('index', { title: 'WebHook Info' });
});


module.exports = router;

Which will output stuff like:

Repo is blog
User is glen_a_smith
Branch/Tag is master
Type is branch

All kinds of great!

So you can actually interate over each of the commits that are inbound, and see what’s changed, on which branches/tags, and by who. If you were rolling your own CI server, this is the hook that you’d want to check out!

Big fan of the WebHook.. Thinking of all kinds of applications for this sort of stuff..

Good luck with your experiments!