Skip to content

Latest commit

 

History

History

github

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

Github Webhook

This example shows how to receive events from Github and send notifications using Pushbullet or a Google Home. You can also keep a local mirror of your repositories.

The full API description file is here: github.yml.

Github Webhook

Setup the Webhook

Setup a webhook for each of your repositories with the following parameters:

  • Payload URL: URL that point to your genapid instance, with /github as path.
  • Content type: application/json
  • Secret: A random string
  • SSL verification: you can put genapid behind a web server to handle SSL. See this conf file for an example of Apache conf.
  • Which events would you like to trigger this webhook?: Send me everything.
  • Active: enabled

Match Github Webhook

We start a pipe with a filter on the path set above, using a match predicate:

- name: "Incoming github request"
  pipe:
  - name: github dedicated endpoint
    match:
      string: =In.Req.URL.Path
      value: /github

In order to authenticate the Webhook we have to calculate a hash on the payload. We first get the content of the body and check that the content-type is the one expected, using a body predicate:

  - name: Get body
    body:
      mime: application/json
      type: string
    register: body

We store the result in R.body.

The hash to check is passed in a header that looks like:

X-Hub-Signature-256: sha256=03550210cfcc0002e56e3bb72b5b695ea552ad6da8b14b31ac27590e8f791f16

We calculate the hash on the payload using the secret set on Github and check it corresponds to the one passed in Github header with the header predicate.

  - name: Check GitHub hash
    header:
      name: X-Hub-Signature-256
      value: '= "sha256=" + hmacSha256("GITHUB_SECRET"", R.body.payload)'

All parameter values that starts with an equal signs are expressions evaluated before the predicate is evaluated.

Now that we are sure we are processing a valid Github Webook, we parse the JSON payload and retrieve the name of the event:

  - name: Parse JSON body
    body:
      type: json
    register: body
  - header:
      name: X-GitHub-Event
    register: event

We can then process each event we are interesting in and use its payload. We start a new sub-pipe for each event. First, we match the event name, here a ping event. Then we write the zen string (inspirational phrase) in genapid log, and use Pushbullet API to receive a notification.

  - name: ping event
    pipe:

    - match:
        string: '=R.event.value'
        value: ping

    - log:
        msg: =format("received ping, %v", R.body.payload.zen)

    - http:
        url: https://api.pushbullet.com/v2/pushes
        method: post
        headers:
          Access-Token: 'PUSHBULLET_SECRET'
        body:
          json:
            type: note
            title: Github ping
            body: =R.body.payload.zen

The http predicate is used to call an external API. The PUSHBULLET_SECRET can be retrieved on your Pushbullet account settings page.

To process other events, we add other sub-pipes. For example, to receive a notification when a pull request event with the opened action is received:

  - name: pull_request event
    pipe:
    - match:
        string: '=R.event.value'
        value: pull_request
    - match:
        string: =R.body.payload.action
        value: opened
    - http:
        url: https://api.pushbullet.com/v2/pushes
        method: post
        headers:
          Access-Token: 'PUSHBULLET_SECRET'
        body:
          json:
            type: note
            title: github pull request
            body: >
              =format("received pull_request on %v from %v",
              R.body.payload.repository, R.body.payload.sender.login)

Default parameters

In these examples, some parameters are repeated in several predicates. We can factorize those parameters in a default predicate before our sub-pipes:

  - default:
      http: # pushbullet push API
        url: https://api.pushbullet.com/v2/pushes
        method: post
        headers:
          Access-Token: 'PUSHBULLET_SECRET'
      match: # match event name per default
        string: '=R.event.value'

Now, the above event processing predicates can be written:

  - name: ping event
    pipe:
    - match:
        value: ping
    - log:
        msg: =format("received ping, %v", R.body.payload.zen)
    - http:
        body:
          json:
            type: note
            title: github ping
            body: =R.body.payload.zen

  - name: pull_request event
    pipe:
    - match:
        value: pull_request
    - match:
        string: =R.body.payload.action
        value: opened
    - http:
        body:
          json:
            type: note
            title: github pull request
            body: >
              =format("received pull_request on %v from %v",
              R.body.payload.repository, R.body.payload.sender.login)

Voice notification on the Google Home

You can use the chromecast predicate to use your Google Home to receive notifications.

Add the configuration for the Google Home and TTS API service with a default predicate before the event sub-pipes:

  - default:
      chromecast: # Used to give voice notifications
        # Google Home IP addr
        addr: 192.168.3.9
        # Credentials to use Google API service for TTS
        google_service_account: "path_to/google_service_account.json"

Then in each event sup-pipe, you can use:

      - chromecast:
          tts: >
            =format("Github pull request received on %v",
            R.body.payload.repository)

Local Github repository mirror

To keep an up-to-date local mirror of some Github repositories, you can checkout the repositories in a local directory (here /var/lib/genapid/github/) and use a command predicate in the push event pipe to get new commits each time someone push something on Github:

    - name: Pull commits
      command:
        cmd: git
        args:
          - pull
        chdir: >
          = "/var/lib/genapid/github/"+ R.body.payload.repository.name

See github.yml for the complete API file description.