← Back

Build your own Probot

A lot of people look at Probot and wonder how they can extend it - add custom routes, integrate it with other platforms, control its startup. I firmly believe that too many features and options can make a framework unwieldy, so rather than show where all of those things can fit in Probot itself, we’re going to take a look at building our own Probot.

Interestingly, the API design (started by @bkeepers) looks and feels a lot like a chatbot. I’m hoping that from this post, you (yes you!) will get an understanding of how Probot integrates with GitHub and why it feels easy to use, and then you’ll be able to bring those patterns to your own projects.

I’m going to leave the Why we built Probot until the end because while it is interesting and enlightening, we want to build stuff!

A couple of important notes:

  • Unless specifically stated, all code is pseudo-code, not copied directly from Probot. I’ll be oversimplifying some code so that we don’t have to think about edge-cases and complications.
  • Many parts of Probot have been extracted into smaller modules (shoutout @gr2m). We’ll talk about how they work, but you’ll probably just want to use them directly.
  • There’s a lot of code here - if you’re looking at something and wanting for some more explanation, please tell me!

Probot is an opinionated Express server

At its core, Probot uses Express to run a Node.js HTTP server. When an event happens on GitHub that your Probot app is configured to care about, GitHub sends HTTP POST requests (webhooks) to a special “webhook endpoint,” containing information in a JSON payload about what event was triggered. You can imagine code like this being a central part of the Probot framework (I’ll link to actual code shortly):

const express = require('express')
const app = express()

app.post('/', (req, res) => {
  // We got a webhook! Now run the Probot app's code.
})

When a Probot server receives a Webhook, it does a few things before actually running your code: