irc-webhooks/src/webhooks.go

140 lines
3.9 KiB
Go

package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strings"
)
func ListenForWebHook(config Config, msgChan chan string) {
http.HandleFunc("/", CreateHandler(msgChan))
err := http.ListenAndServe(config.BindHost+":"+config.BindPort, nil)
if err != nil {
fmt.Println(err)
}
}
func shortHash(hash string) string {
return hash[0:7]
}
func CreateHandler(msgChan chan string) http.HandlerFunc {
return func(writer http.ResponseWriter, request *http.Request) {
defer request.Body.Close()
data, err := ioutil.ReadAll(request.Body)
if err != nil {
panic(err)
}
switch eventType := request.Header.Get("X-Gitea-Event"); eventType {
default:
fmt.Printf("Unknown event type: %q\n", eventType)
handleUnknown(data, msgChan)
case "":
// Not a gitea event.
fmt.Printf("Got a non-event HTTP request %+v\n", request)
case "push":
handlePush(data, msgChan)
case "issues":
handleIssueAction(data, msgChan)
case "issue_comment":
handleIssueComment(data, msgChan)
case "create":
handleCreate(data, msgChan)
}
}
}
func printSep() {
fmt.Println("---")
}
func handleUnknown(data []byte, msgChan chan string) {
printSep()
fmt.Println(string(data))
}
func handlePush(data []byte, msgChan chan string) {
pushData := Push{}
json.Unmarshal(data, &pushData)
outIrcMessage := strings.Builder{}
outIrcMessage.WriteString(fmt.Sprintf(
"[%s] %s pushed %d commit(s) to ref %s: %s..%s",
pushData.Repository.FullName,
pushData.Pusher.Login,
len(pushData.Commits),
pushData.Ref,
shortHash(pushData.Before),
shortHash(pushData.After),
))
msgChan <- outIrcMessage.String()
count := 0
for _, commit := range pushData.Commits {
if count > 4 {
break
}
commitDesc := strings.SplitN(commit.Message, "\n", 1)[0]
msgChan <- fmt.Sprintf(
"[%s] commit %s created by %s (%s): %s",
pushData.Repository.FullName,
shortHash(commit.Hash),
commit.Author.Name,
commit.Author.Email,
commitDesc,
)
count++
}
}
func handleIssueAction(data []byte, msgChan chan string) {
action := IssueAction{}
json.Unmarshal(data, &action)
outMsg := strings.Builder{}
outMsg.WriteString(fmt.Sprintf("[%s] ", action.Repository.FullName))
switch action.Action {
case "opened":
outMsg.WriteString(fmt.Sprintf("%s opened an issue: %q", action.Sender.Login, action.Issue.Title))
case "closed":
outMsg.WriteString(fmt.Sprintf("%s closed issue %q", action.Sender.Login, action.Issue.Title))
default:
outMsg.WriteString(fmt.Sprintf("%s performed an unknown action (%s) on issue %d", action.Sender.Login, action.Action, int(action.Issue.Id)))
fmt.Println(string(data))
}
msgChan <- outMsg.String()
}
func handleIssueComment(data []byte, msgChan chan string) {
action := IssueAction{}
json.Unmarshal(data, &action)
msgChan <- fmt.Sprintf("[%s] %s commented on issue %d (%s)", action.Repository.FullName, action.Sender.Login, int(action.Issue.Id), action.Issue.Title)
}
func handleCreate(data []byte, msgChan chan string) {
created := CreateAction{}
json.Unmarshal(data, &created)
switch created.RefType {
case "branch":
handleBranchCreate(created, msgChan)
default:
fmt.Printf("Unknown create reftype %q:\n", created.RefType)
fmt.Println(string(data))
}
}
func handleBranchCreate(branchAction CreateAction, msgChan chan string) {
msgChan <- fmt.Sprintf("[%s] %s created branch %s", branchAction.Repository.FullName, branchAction.Sender.Login, branchAction.Ref)
}