├── package.json ├── LICENSE ├── src └── hubot-github-webhook-listener.coffee └── README.md /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hubot-github-webhook-listener", 3 | "version": "0.9.1", 4 | "author": "Taylor Brown ", 5 | "description": "Listens for github webhooks and emits an event for other Hubot scripts to respond to.", 6 | "keywords": [ 7 | "hubot", 8 | "chat", 9 | "github", 10 | "bot", 11 | "webhook" 12 | ], 13 | "licenses": [ 14 | { 15 | "type": "MIT", 16 | "url": "http://github.com/ynab/hubot-github-webhook-listener/raw/master/LICENSE" 17 | } 18 | ], 19 | "repository": { 20 | "type": "git", 21 | "url": "http://github.com/ynab/hubot-github-webhook-listener.git" 22 | }, 23 | "license": "MIT", 24 | "main": "./src/hubot-github-webhook-listener.coffee", 25 | "devDependencies": { 26 | "coffee-script": "~1.7.1", 27 | "hubot": ">= 2.6.0 < 3.0.0" 28 | }, 29 | "bugs": { 30 | "url": "https://github.com/ynab/hubot-github-webhook-listener/issues" 31 | }, 32 | "dependencies": { 33 | "querystring": "^0.2.0", 34 | "url": "^0.10.3" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2015 You Need a Budget, LLC. (Taylor Brown) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/hubot-github-webhook-listener.coffee: -------------------------------------------------------------------------------- 1 | # Description: 2 | # Listens for github webhooks and emits an event for other Hubot scripts to respond to. 3 | # Inspired _heavily_ (with some verbatim copying) by hubot-github-repo-event-notifier 4 | # 5 | # Configuration: 6 | # 7 | # 1. Create a new webhook for your `myuser/myrepo` repository at: 8 | # https://github.com/myuser/myrepo/settings/hooks/new 9 | # Set the webhook url to: :/hubot/github-repo-listener[?param1=value1¶m2=value2] 10 | # 11 | # Incoming webhooks are emitted as events with the name github-repo-event 12 | # The body of the event is: 13 | # { 14 | # eventType, # The name of the event 15 | # data, # The full parsed object body of the posted event 16 | # query # The parsed query string of the posted event 17 | # } 18 | # Commands: 19 | # None 20 | # 21 | # URLS: 22 | # POST /hubot/github-repo-listener[?param1=value1¶m2=value2] 23 | # 24 | # Notes: 25 | # For easy local testing, I highly recommend ngrok: https://ngrok.com/ 26 | # 1. Install ngrok 27 | # 2. run ngrok: `ngrok 8080`. 28 | # It will show you a public URL like: `Forwarding https://7a008da9.ngrok.com -> 127.0.0.1:8080` 29 | # 3. Put that URL in as your Github webhook: `https://7a008da9.ngrok.com/hubot/github-repo-listener` 30 | # 4. Run hubot locally: `HUBOT_GITHUB_TOKEN=some_log_guid bin/hubot -a github --name Hubot` 31 | # 5. Fire off a github event by interacting with your repo. Comment on an issue or a PR for example. 32 | # 6. Navigate to `http://127.0.0.1:4040/` 33 | # There you can see all webhooks posted to your local machine, and can replay them as many times as you wish. 34 | # 35 | # Authors: 36 | # Taytay 37 | # Using code written by: spajus, patcon, and parkr 38 | 39 | url = require('url') 40 | querystring = require('querystring') 41 | 42 | debug = false 43 | 44 | module.exports = (robot) -> 45 | 46 | #TODO: Introduce secret so that these are verified: 47 | # See: https://developer.github.com/webhooks/securing/ and 48 | # https://gist.github.com/dcollien/c5d86c968cbc85e88286 49 | robot.router.post "/hubot/github-repo-listener", (req, res) -> 50 | try 51 | if (debug) 52 | robot.logger.info("Github post received: ", req) 53 | eventBody = 54 | eventType : req.headers["x-github-event"] 55 | signature : req.headers["X-Hub-Signature"] 56 | deliveryId : req.headers["X-Github-Delivery"] 57 | payload : req.body 58 | query : querystring.parse(url.parse(req.url).query) 59 | 60 | robot.emit "github-repo-event", eventBody 61 | catch error 62 | robot.logger.error "Github repo webhook listener error: #{error.stack}. Request: #{req.body}" 63 | 64 | res.end "" 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # hubot-github-webhook-listener 2 | 3 | A [Hubot](http://hubot.github.com/) script to that makes it easy to consume [Github Webhooks](https://developer.github.com/webhooks/). 4 | 5 | ## Installation 6 | 7 | From your hubot folder: 8 | `npm install --save hubot-github-webhook-listener` 9 | 10 | Then, in your `external-scripts.json` file, add: `"hubot-github-webhook-listener"` to the list. 11 | 12 | Create a new webhook for your `myuser/myrepo` repository at: 13 | https://github.com/myuser/myrepo/settings/hooks/new 14 | Set the webhook url to: <HUBOT_URL>:<PORT>/hubot/github-repo-listener 15 | 16 | For example, if your hubot lives at myhubot.herokuapp.com, then you will set the webhook URL to: http://myhubot.herokuapp.com/hubot/github-repo-listener 17 | 18 | ## Usage 19 | 20 | On every incoming webhook message, a hubot event is emitted as follows 21 | 22 | ```coffeescript 23 | eventBody = 24 | eventType : req.headers["x-github-event"] 25 | signature : req.headers["X-Hub-Signature"] 26 | deliveryId : req.headers["X-Github-Delivery"] 27 | payload : req.body 28 | query : querystring.parse(url.parse(req.url).query) 29 | 30 | robot.emit "github-repo-event", eventBody 31 | ``` 32 | 33 | For details on these fields, see the [Github Webhook documentation](https://developer.github.com/webhooks/). 34 | 35 | **SECURITY WARNING**: This script does not currently validate the Github Secret to verify that the webhook came from Github. So, if someone knows the URL to your Hubot, they can spoof webhooks and issue your Hubot commands. So, for now be careful about exposing commands like `destroy company`, etc. I plan to validate these webhooks soon. In the meantime, patches are welcome. :) 36 | 37 | You can consume it like so from one of your scripts: 38 | ```coffeescript 39 | @robot.on "github-repo-event", (repo_event) => 40 | githubPayload = repo_event.payload 41 | switch(repo_event.eventType) 42 | when "issue_comment" 43 | ... 44 | ``` 45 | 46 | NOTE: This script does not emit anything in chat. It is just a background task that makes consuming Github webhooks easier for other scripts. 47 | 48 | For another example, see our [Hubot-Github adapter](https://github.com/ynab/hubot-github) that gives you a hubot in your Github issue comments. 49 | 50 | ## Motivation 51 | 52 | I was using [hubot-github-repo-event-notifier](https://github.com/hubot-scripts/hubot-github-repo-event-notifier), but I needed something more generic to power our hubot-github adapter. So, I gutted it, and this script was born. 53 | 54 | ## Local Testing 55 | 56 | For easy local testing, I highly recommend ngrok: https://ngrok.com/ 57 | 58 | 1. Install [ngrok](https://ngrok.com/) 59 | 2. run ngrok: `ngrok 8080`. 60 | It will show you a public URL like: `Forwarding https://7a008da9.ngrok.com -> 127.0.0.1:8080` 61 | 3. Put that URL in as your Github webhook: `https://7a008da9.ngrok.com/hubot/github-repo-listener` 62 | 4. Install the hubot-github adapter `npm install --save hubot-github-adapter` 63 | 5. Run hubot locally: `HUBOT_GITHUB_TOKEN=some_long_guid bin/hubot -a github-adapter --name Hubot` 64 | 6. Fire off a github event by interacting with your repo. Comment on an issue or a PR for example. 65 | 7. Navigate to `http://127.0.0.1:4040/` 66 | There you can see all webhooks posted to your local machine, and can replay them as many times as you wish. 67 | 68 | ## Copyright 69 | 70 | Copyright © [YouNeedABudget.com](http://youneedabudget.com), LLC. (Github: [YNAB](http://github.com/ynab)) 71 | 72 | ## Author 73 | 74 | Taylor Brown, aka [Taytay](http://github.com/Taytay) 75 | 76 | ## License 77 | 78 | MIT License; see LICENSE for further details. 79 | --------------------------------------------------------------------------------