demand

When push/pull request/issue/release and other events occur on Github, they will be synchronized to the enterprise wechat internal group

The technology principle

  • Github provides a Webhook configuration that sends a request to a configured URL when a subscription event occurs, informing you of the event
  • The enterprise wechat internal group provides the function of adding robots, and messages can be sent to the enterprise internal group by calling the robot sending message interface

So we just need to develop a service that receives Github notifications, calls the enterprise wechat robot interface based on the type of event, and sends mass messages internally

Configure enterprise wechat internal group robots

  • Enter the group Settings page, and you can see the entry of robot configuration

  • Add a robot

  • Get the webhook address of the robot

Configuration making

  • Enter the notification address (for example, fastwego.dev/ API /github/…).
  • Set the secret

Development robot

configuration

  • Update Github Secret and enterprise wechat robot Webhook URL configuration to.envFile:
SECRET=xxxx
WEBHOOK_URL=xxx
LISTEN=:80
Copy the code
  • Write code:
package main

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha1"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"github.com/spf13/viper"
	"io/ioutil"
	"net/http"
)

func init(a) {
	// Load the configuration file
	viper.SetConfigFile(".env")
	_ = viper.ReadInConfig()
}

func main(a) {

	http.HandleFunc("/api/github/webhook".func(w http.ResponseWriter, r *http.Request) {

		payload, err := ioutil.ReadAll(r.Body)

		fmt.Println(string(payload))

		iferr ! =nil || len(payload) == 0 {
			return
		}

		event := r.Header.Get("X-GitHub-Event")
		if event == "" {
			return
		}

		secret := viper.GetString("SECRET")
		if len(secret) > 0 {
			signature := r.Header.Get("X-Hub-Signature")
			if len(signature) == 0 {
				return
			}
			mac := hmac.New(sha1.New, []byte(secret))
			_, _ = mac.Write(payload)
			expectedMAC := hex.EncodeToString(mac.Sum(nil))

			if! hmac.Equal([]byte(signature[5:), []byte(expectedMAC)) {
				return
			}
		}

		e := struct {
			Repository struct {
				FullName string `json:"full_name"`
			} `json:"repository"`} {}var repo string

		err = json.Unmarshal(payload, &e)
		iferr ! =nil {
			repo = "unknown"
		}

		repo = e.Repository.FullName

		notify := struct {
			Msgtype string `json:"msgtype"`
			Markdown    struct {
				Content string `json:"content"`
			} `json:"markdown"`
		}{}

		notify.Msgtype = "markdown"
		notify.Markdown.Content = fmt.Sprintf("## Event: %s \n https://github.com/%s", event, repo)

		fmt.Println(notify)

		payload, err = json.Marshal(notify)
		response, err := http.Post(viper.GetString("WEBHOOK_URL"), "application/json", bytes.NewReader(payload))
		iferr ! =nil {
			fmt.Println(err)
			return
		}

		all, err := ioutil.ReadAll(response.Body)
		fmt.Println(string(all), err)

	})

	_ = http.ListenAndServe(viper.GetString("LISTEN"), nil)}Copy the code

Compile & deploy to server

GOOS=linux go build

chmod +x ./github-webhook-bot && ./github-webhook-bot

Finally send message effect

conclusion

Congratulations to you! A Github bot was developed in five minutes

Full demo code: github.com/fastwego/wx…