• Stars
    star
    82
  • Rank 382,685 (Top 8 %)
  • Language
    Go
  • License
    BSD 3-Clause "New...
  • Created about 9 years ago
  • Updated over 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Scriptable server and net/http middleware for GitHub Webhooks.

gh GoDoc Build Status Build status Coverage Status

Commands and packages for GitHub services.

Installation

~ $ go get -u github.com/rjeczalik/gh

webhook GoDoc

Package webhook implements middleware for GitHub Webhooks. User provides webhook service object that handles events delivered by GitHub. Webhook handler verifies payload signature delivered along with the event, unmarshals it to corresponding event struct and dispatches control to user service.

Documentation

https://godoc.org/github.com/rjeczalik/gh/webhook

Examples

Notify Slack's channel about recent push:

package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"net/url"

	"github.com/rjeczalik/gh/webhook"
)

var (
	secret  = flag.String("secret", "", "GitHub webhook secret")
	token   = flag.String("token", "", "Slack API token")
	channel = flag.String("channel", "", "Slack channel name")
)

type slack struct{}

func (s slack) Push(e *webhook.PushEvent) {
	const format = "https://slack.com/api/chat.postMessage?token=%s&channel=%s&text=%s"
	text := url.QueryEscape(fmt.Sprintf("%s pushed to %s", e.Pusher.Email, e.Repository.Name))
	if _, err := http.Get(fmt.Sprintf(format, *token, *channel, text)); err != nil {
		log.Println(err)
	}
}

func main() {
	flag.Parse()
	log.Fatal(http.ListenAndServe(":8080", webhook.New(*secret, slack{})))
}

Notify HipChat's room about recent push:

package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"strings"

	"github.com/rjeczalik/gh/webhook"
)

var (
	secret = flag.String("secret", "", "GitHub webhook secret")
	token  = flag.String("token", "", "HipChat personal API token")
	room   = flag.String("room", "", "HipChat room ID")
)

type hipchat struct{}

func (h hipchat) Push(e *webhook.PushEvent) {
	url := fmt.Sprintf("https://api.hipchat.com/v2/room/%s/notification", *room)
	body := fmt.Sprintf(`{"message":"%s pushed to %s"}`, e.Pusher.Email, e.Repository.Name)
	req, err := http.NewRequest("POST", url, strings.NewReader(body))
	if err != nil {
		log.Println(err)
		return
	}
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "Bearer "+*token)
	if _, err := http.DefaultClient.Do(req); err != nil {
		log.Println(err)
	}
}

func main() {
	flag.Parse()
	log.Fatal(http.ListenAndServe(":8080", webhook.New(*secret, hipchat{})))
}

cmd/webhook GoDoc

Command webhook starts a web server which listens on GitHub's POST requests. The payload of each request is verified against its signature, unmarshalled into corresponding event struct and the applied to the template script provided by a user.

Examples

Notify Slack's channel about recent push:

~ $ cat >slack.tsc <<EOF
> {{with $e := .}}
>   {{if eq $e.Name "push"}}
>     {{with $text := (urlquery (printf "%s pushed to %s" $e.Payload.Pusher.Email $e.Payload.Repository.Name))}}
>     {{with $url := (printf "https://slack.com/api/chat.postMessage?token=%s&channel=%s&text=%s" $e.Args.Token $e.Args.Channel $text)}}
>       {{exec "curl" "-X" "GET" $url}}
>     {{end}}
>     {{end}}
>   {{end}}
> {{end}}
> EOF
~ $ webhook -secret secret123 slack.tsc -- -token token123 -channel CH123

Notify HipChat's room about recent push:

~ $ cat >hipchat.tsc <<EOF
> {{with $e := .}}
>   {{if eq $e.Name "push"}}
>     {{with $auth := (printf "authorization: bearer %s" $e.Args.Token)}}
>     {{with $msg := (printf "{\"message_format\": \"text\", \"message\": \"%s pushed to %s\"}" $e.Payload.Pusher.Email $e.Payload.Repository.Name)}}
>     {{with $url := (printf "https://api.hipchat.com/v2/room/%s/notification" $e.Args.Room)}}
>       {{exec "curl" "-h" "content-type: application/json" "-h" $auth "-x" "post" "-d" $msg $url | log}}
>     {{end}}
>     {{end}}
>     {{end}}
>   {{end}}
> {{end}}
> EOF
~ $ webhook -secret secret123 hipchat.tsc -- -token token123 -room 123

Contributing to the webhook package

Occasionally it may happen that serving webhook may fail with serialization error. Since structs for event payloads are go-generated from either on-line GitHub Developer documentation or real GitHub's requests, they may not contain all fields or have wrong field types. If you notice webhook failures like the following:

delivery details

Take the following steps to fix the problem:

  • restart your webhook command with -dump flag (or wrap your *webhook.Handler with webhook.Dump):
~ $ webhook -dump /tmp -secret secret123 handler.tsc
  • redeliver the event, it's going to fail again, but this time it will be dumped to /tmp/pull_request-ef748000-d078-11e4-91b6-77fc544482ea.json file (named after the event and its X-GitHub-Delivery header)
  • copy the file to the testdata directory of webhook package and regenerate payloads:
~ $ scp core@remote:/tmp/pull_request-ef748000-d078-11e4-91b6-77fc544482ea.json ~/src/github.com/rjeczalik/gh/webhook/testdata
~ $ go generate github.com/rjeczalik/gh/...
~ $ go test github.com/rjeczalik/gh/...
  • if both the go generate and go test succeed, send pull request with modified payload.go and the JSON file
  • if either of them fail, re-run them command with -v flag and create issue with original error message and the verbose outputs

More Repositories

1

notify

File system event notification library on steroids.
Go
881
star
2

interfaces

Code generation tools for Go.
Go
416
star
3

bin

Looks for Golang executables in $PATH, guesses their origin and updates them or creates $GOPATH workspaces.
Go
45
star
4

refmt

Reformat HCL ⇄ JSON ⇄ YAML.
Go
25
star
5

pkgconfig

Go-centric and GOPATH-aware pkg-config replacement for a use with the cgo tool.
Go
21
star
6

terraform-aws-scylla

Terraform module for creating Scylla clusters on AWS
HCL
21
star
7

cmd

Handmade tools for day-to-day plumbing.
Go
20
star
8

which

Reads the import path and target platform strings from Golang executables.
Go
9
star
9

rapidjson

Yet another rapidjson svn fork, this time with CMake and maintenance patches.
C++
7
star
10

fakerpc

A fake server for recording and mocking HTTP-based RPC services.
Go
6
star
11

fs

Interface, mocks and codegen for the os package.
Go
5
star
12

gsh

SSH for Go on steroids
Go
4
star
13

terraform-aws-scylla-bench

Terraform module for load testing a Scylla cluster with scylla-bench.
HCL
4
star
14

ciexec

A command line tool for executing any CI configuration file (.travis.yml, .pulse.xml) like it was a shell script.
Go
4
star
15

cross

Go cross-compilation unchained.
Shell
3
star
16

wayback

Client for Wayback Availability JSON API.
Go
2
star
17

rw

General purpose io.Reader / io.Writer utility functions.
Go
1
star
18

alpine-peerjs

1
star
19

stat

Statistics and time series toys for the command line.
Go
1
star
20

covcat

Merges multiple Go coverage profiles into and outputs the result as nicely formatted JSON.
Go
1
star
21

bigstruct

Go
1
star
22

powermux

Go
1
star
23

zeitdb

Key/value db library for storing log files, backed by a git.
Go
1
star
24

dsn2mycnf

Converts MySQL DSN connection string to a my.cnf configuration file
Go
1
star