├── config └── event_templates │ ├── note.tpl │ ├── push.tpl │ ├── tag_push.tpl │ ├── job.tpl │ ├── merge_request.tpl │ └── pipeline.tpl ├── koyote.jpg ├── main.go ├── Dockerfile ├── .gitignore ├── pkg ├── config │ └── config.go ├── api │ └── api.go ├── events │ ├── events.go │ ├── template.go │ └── models.go └── telegram │ └── bot.go ├── LICENSE ├── go.mod ├── README.md └── go.sum /config/event_templates/note.tpl: -------------------------------------------------------------------------------- 1 | 📓 NOTE -------------------------------------------------------------------------------- /config/event_templates/push.tpl: -------------------------------------------------------------------------------- 1 | 🧑💻 CODE PUSHED -------------------------------------------------------------------------------- /config/event_templates/tag_push.tpl: -------------------------------------------------------------------------------- 1 | 🧑💻 TAG PUSHED -------------------------------------------------------------------------------- /koyote.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solyard/koyote/HEAD/koyote.jpg -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/koyote/pkg/api" 5 | "github.com/koyote/pkg/config" 6 | "github.com/koyote/pkg/telegram" 7 | ) 8 | 9 | func main() { 10 | config.LoadConfig() 11 | go telegram.StartBot() 12 | api.StartPolling() 13 | } 14 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine as build-env 2 | LABEL maintainer="dizstorm@gmail.com" 3 | COPY . /app 4 | WORKDIR /app 5 | RUN go mod download && CGO_ENABLED=0 go build -o /usr/bin/koyote . 6 | 7 | FROM alpine as final 8 | COPY --from=build-env /usr/bin/koyote /koyote 9 | ENTRYPOINT ["/koyote"] -------------------------------------------------------------------------------- /config/event_templates/job.tpl: -------------------------------------------------------------------------------- 1 | 🛠 BUILD 2 | {{ $status := .BuildStatus }} 3 | {{- if eq $status "success" -}} 🟢 SUCCESS {{ else }} 🔴 FAILURE {{- end }} {{ $status := .BuildStatus}} 4 | Status: {{- if eq $status "success" -}} 🟢 Success {{ else }} 🔴 Build Failed {{- end }} 5 | Project: {{ .ProjectName }} 6 | Initiator: {{ .User.Name }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | *test/ 17 | *prepeare_binaries/ -------------------------------------------------------------------------------- /config/event_templates/merge_request.tpl: -------------------------------------------------------------------------------- 1 | 🟡 MERGE REQUEST 2 | Initiator: {{ .User.Name }} 3 | Project: {{ .Project.Name }} 4 | MR Link: {{ .ObjectAttributes.URL }} 5 | MR Status: {{ if eq .ObjectAttributes.MergeStatus "can_be_merged" }}💚 CAN BE MERGE{{ else }}💔 CANNOT BE MERGED{{- end }} 6 | 7 | Please review and close merge request if you can do so. -------------------------------------------------------------------------------- /config/event_templates/pipeline.tpl: -------------------------------------------------------------------------------- 1 | 🛠 PIPELINE 2 | {{- $var := "" }} 3 | Stages: 4 | {{- range $buildStages := .Builds }} 5 | {{- if ne "success" $buildStages.Status }} {{ $var = "🔴 FAILURE"}} {{- else }} {{ $var = "🟢 SUCCESS"}} {{- end }} 6 | {{ if ne "success" $buildStages.Status }} ⛔️ {{ else }} ✅ {{ end }} {{ $buildStages.Stage | ToUpper }} 7 | {{- end}} 8 | Status: {{ $var }} 9 | Project: {{ .Project.Name }} -------------------------------------------------------------------------------- /pkg/config/config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "github.com/caarlos0/env/v6" 5 | log "github.com/gookit/slog" 6 | ) 7 | 8 | type ApplicationConfig struct { 9 | Global struct { 10 | ListenPort string `env:"KOYOTE_API_PORT" envDefault:"8081"` 11 | TelegramBotToken string `env:"KOYOTE_TELEGRAM_BOT_TOKEN,required"` 12 | } 13 | Events struct { 14 | Job bool `env:"KOYOTE_ENABLE_JOB_NOTIFICATION"` 15 | MergeRequest bool `env:"KOYOTE_ENABLE_MR_NOTIFICATION" envDefault:true` 16 | Note bool `env:"KOYOTE_ENABLE_NOTE_NOTIFICATION"` 17 | Pipeline bool `env:"KOYOTE_ENABLE_PIPELINE_NOTIFICATION" envDefault:true` 18 | Push bool `env:"KOYOTE_ENABLE_PUSH_NOTIFICATION"` 19 | TagPush bool `env:"KOYOTE_ENABLE_TAG_PUSH_NOTIFICATION"` 20 | } 21 | } 22 | 23 | var GlobalAppConfig ApplicationConfig 24 | 25 | func LoadConfig() { 26 | if err := env.Parse(&GlobalAppConfig); err != nil { 27 | log.Fatal("Error while parse envs for config to struct. Error: ", err) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Vladislav 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/koyote 2 | 3 | go 1.21.5 4 | 5 | require ( 6 | github.com/caarlos0/env/v6 v6.10.1 7 | github.com/gookit/slog v0.5.5 8 | github.com/gorilla/mux v1.8.1 9 | github.com/mymmrac/telego v0.29.1 10 | github.com/pkg/errors v0.9.1 11 | ) 12 | 13 | require ( 14 | github.com/andybalholm/brotli v1.1.0 // indirect 15 | github.com/bytedance/sonic v1.10.2 // indirect 16 | github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect 17 | github.com/chenzhuoyu/iasm v0.9.1 // indirect 18 | github.com/fasthttp/router v1.4.22 // indirect 19 | github.com/gookit/color v1.5.4 // indirect 20 | github.com/gookit/goutil v0.6.15 // indirect 21 | github.com/gookit/gsr v0.1.0 // indirect 22 | github.com/grbit/go-json v0.11.0 // indirect 23 | github.com/klauspost/compress v1.17.6 // indirect 24 | github.com/klauspost/cpuid/v2 v2.2.6 // indirect 25 | github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee // indirect 26 | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 27 | github.com/valyala/bytebufferpool v1.0.0 // indirect 28 | github.com/valyala/fasthttp v1.52.0 // indirect 29 | github.com/valyala/fastjson v1.6.4 // indirect 30 | github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect 31 | golang.org/x/arch v0.6.0 // indirect 32 | golang.org/x/sync v0.5.0 // indirect 33 | golang.org/x/sys v0.17.0 // indirect 34 | golang.org/x/text v0.14.0 // indirect 35 | ) 36 | -------------------------------------------------------------------------------- /pkg/api/api.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "net/http" 7 | 8 | log "github.com/gookit/slog" 9 | "github.com/gorilla/mux" 10 | "github.com/koyote/pkg/config" 11 | "github.com/koyote/pkg/events" 12 | ) 13 | 14 | func returnError(w http.ResponseWriter, r *http.Request) { 15 | http.Error(w, "Please add chatID like in example: /notify/123123123123", http.StatusNotFound) 16 | } 17 | 18 | func receiveEventJSON(w http.ResponseWriter, r *http.Request) { 19 | w.Header().Set("Content-Type", "application/json") 20 | vars := mux.Vars(r) 21 | 22 | body, err := ioutil.ReadAll(r.Body) 23 | if err != nil { 24 | log.Error("Error while read payload from request to Koyote. Error: ", err) 25 | } 26 | 27 | err = events.EventMatcher(body, vars["chat_id"], vars["thread_id"]) 28 | if err != nil { 29 | http.Error(w, fmt.Sprint("Error while compare Event to template. Error: ", err), http.StatusBadRequest) 30 | } 31 | } 32 | 33 | func StartPolling() { 34 | router := mux.NewRouter().StrictSlash(true) 35 | router.HandleFunc("/notify/{chat_id}", receiveEventJSON).Methods("POST") 36 | router.HandleFunc("/notify/{chat_id}/{thread_id}", receiveEventJSON).Methods("POST") 37 | router.HandleFunc("/notify", returnError) 38 | 39 | log.Info("Starting API on port", config.GlobalAppConfig.Global.ListenPort) 40 | log.Fatal(http.ListenAndServe(fmt.Sprintf(":%v", config.GlobalAppConfig.Global.ListenPort), router)) 41 | } 42 | -------------------------------------------------------------------------------- /pkg/events/events.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | 7 | "github.com/koyote/pkg/telegram" 8 | "github.com/pkg/errors" 9 | ) 10 | 11 | type Event interface { 12 | TemplateMessage() (string, error) 13 | } 14 | 15 | func (e GitlabJobEvent) TemplateMessage() (string, error) { 16 | result, err := templateJobEventMessage(e, "job.tpl") 17 | if err != nil { 18 | return "", errors.Wrap(err, "Error while templating message!") 19 | } 20 | 21 | return result, nil 22 | } 23 | 24 | func (e GitlabMergeRequestEvent) TemplateMessage() (string, error) { 25 | result, err := templateMREventMessage(e, "merge_request.tpl") 26 | if err != nil { 27 | return "", errors.Wrap(err, "Error while templating message!") 28 | } 29 | 30 | return result, nil 31 | } 32 | 33 | func (e GitlabNoteEvent) TemplateMessage() (string, error) { 34 | result, err := templateNoteEventMessage(e, "note.tpl") 35 | if err != nil { 36 | return "", errors.Wrap(err, "Error while templating message!") 37 | } 38 | 39 | return result, nil 40 | } 41 | 42 | func (e GitlabPipelineEvent) TemplateMessage() (string, error) { 43 | result, err := templatePipelineEventMessage(e, "pipeline.tpl") 44 | if err != nil { 45 | return "", errors.Wrap(err, "Error while templating message!") 46 | } 47 | 48 | return result, nil 49 | } 50 | 51 | func (e GitlabPushEvent) TemplateMessage() (string, error) { 52 | result, err := templatePushEventMessage(e, "push.tpl") 53 | if err != nil { 54 | return "", errors.Wrap(err, "Error while templating message!") 55 | } 56 | 57 | return result, nil 58 | } 59 | 60 | func EventMatcher(eventJSON []byte, chatID, threadID string) error { 61 | var receivedEventType GitlabEventTypeDetector 62 | err := json.Unmarshal(eventJSON, &receivedEventType) 63 | if err != nil { 64 | return errors.Wrap(err, "Error while templating message!") 65 | } 66 | 67 | event, err := eventComparator(receivedEventType.ObjectKind, eventJSON) 68 | if err != nil { 69 | return errors.Wrap(err, "Error while templating message!") 70 | } 71 | 72 | eventMessage, err := event.TemplateMessage() 73 | if err != nil { 74 | return errors.Wrap(err, "Error while templating message!") 75 | } 76 | 77 | if threadID == "" { 78 | err = telegram.SendEventMessage(chatID, eventMessage) 79 | } else { 80 | err = telegram.SendEventMessageToThread(chatID, threadID, eventMessage) 81 | } 82 | 83 | if err != nil { 84 | return errors.Wrap(err, "Error while send event to Telegram. Event may be lost :( ") 85 | } 86 | 87 | return nil 88 | } 89 | 90 | func eventComparator(eventType string, data []byte) (Event, error) { 91 | var event Event 92 | switch eventType { 93 | case "build": 94 | event = &GitlabJobEvent{} 95 | case "merge_request": 96 | event = &GitlabMergeRequestEvent{} 97 | case "note": 98 | event = &GitlabNoteEvent{} 99 | case "pipeline": 100 | event = &GitlabPipelineEvent{} 101 | case "push": 102 | event = &GitlabPushEvent{} 103 | default: 104 | return nil, fmt.Errorf("Unknown event type: %s", eventType) 105 | } 106 | 107 | return event, json.Unmarshal(data, &event) 108 | } 109 | -------------------------------------------------------------------------------- /pkg/events/template.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "os" 7 | "strings" 8 | "text/template" 9 | 10 | log "github.com/gookit/slog" 11 | ) 12 | 13 | func prepareTemplate(eventType, templateFilePath string) (*template.Template, error) { 14 | templatefuncMap := template.FuncMap{ 15 | "ToUpper": strings.ToUpper, 16 | } 17 | 18 | tplfile, err := os.ReadFile(fmt.Sprintf("config/event_templates/%v", templateFilePath)) 19 | if err != nil { 20 | return nil, err 21 | } 22 | 23 | template, err := template.New(eventType).Funcs(templatefuncMap).Parse(string(tplfile)) 24 | if err != nil { 25 | return nil, err 26 | } 27 | 28 | return template, nil 29 | } 30 | 31 | func templateJobEventMessage(gitlabEvent GitlabJobEvent, fileName string) (string, error) { 32 | template, err := prepareTemplate(gitlabEvent.ObjectKind, fileName) 33 | if err != nil { 34 | return "", err 35 | } 36 | 37 | var message bytes.Buffer 38 | err = template.Execute(&message, gitlabEvent) 39 | if err != nil { 40 | log.Error("Error while executing template. Error: ", err) 41 | return "", err 42 | } 43 | 44 | response := fmt.Sprintf("%v", &message) 45 | return response, nil 46 | } 47 | 48 | func templateMREventMessage(gitlabEvent GitlabMergeRequestEvent, fileName string) (string, error) { 49 | template, err := prepareTemplate(gitlabEvent.ObjectKind, fileName) 50 | if err != nil { 51 | return "", err 52 | } 53 | 54 | var message bytes.Buffer 55 | err = template.Execute(&message, gitlabEvent) 56 | if err != nil { 57 | log.Error("Error while executing template. Error: ", err) 58 | return "", err 59 | } 60 | 61 | response := fmt.Sprintf("%v", &message) 62 | return response, nil 63 | } 64 | 65 | func templateNoteEventMessage(gitlabEvent GitlabNoteEvent, fileName string) (string, error) { 66 | template, err := prepareTemplate(gitlabEvent.ObjectKind, fileName) 67 | if err != nil { 68 | return "", err 69 | } 70 | 71 | var message bytes.Buffer 72 | err = template.Execute(&message, gitlabEvent) 73 | if err != nil { 74 | log.Error("Error while executing template. Error: ", err) 75 | return "", err 76 | } 77 | 78 | response := fmt.Sprintf("%v", &message) 79 | return response, nil 80 | } 81 | 82 | func templatePipelineEventMessage(gitlabEvent GitlabPipelineEvent, fileName string) (string, error) { 83 | template, err := prepareTemplate(gitlabEvent.ObjectKind, fileName) 84 | if err != nil { 85 | return "", err 86 | } 87 | 88 | var message bytes.Buffer 89 | err = template.Execute(&message, gitlabEvent) 90 | if err != nil { 91 | return "", err 92 | } 93 | 94 | response := fmt.Sprintf("%v", &message) 95 | return response, nil 96 | } 97 | 98 | func templatePushEventMessage(gitlabEvent GitlabPushEvent, fileName string) (string, error) { 99 | template, err := prepareTemplate(gitlabEvent.ObjectKind, fileName) 100 | if err != nil { 101 | return "", err 102 | } 103 | 104 | var message bytes.Buffer 105 | err = template.Execute(&message, gitlabEvent) 106 | if err != nil { 107 | log.Error("Error while executing template. Error: ", err) 108 | return "", err 109 | } 110 | 111 | response := fmt.Sprintf("%v", &message) 112 | return response, nil 113 | } 114 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |
3 |
Koyote - Fast GitLab Event Notifications for Telegram
6 | 7 |Logo by MJ 5.2 :)
79 | 80 | -------------------------------------------------------------------------------- /pkg/telegram/bot.go: -------------------------------------------------------------------------------- 1 | package telegram 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | 7 | log "github.com/gookit/slog" 8 | "github.com/koyote/pkg/config" 9 | "github.com/mymmrac/telego" 10 | th "github.com/mymmrac/telego/telegohandler" 11 | "github.com/pkg/errors" 12 | ) 13 | 14 | var Bot *telego.Bot 15 | 16 | func StartBot() { 17 | // Initialise BOT 18 | botToken := config.GlobalAppConfig.Global.TelegramBotToken 19 | bot, err := telego.NewBot(botToken) 20 | if err != nil { 21 | log.Fatal(err) 22 | } 23 | 24 | log.Info("Telegram bot started!") 25 | Bot = bot 26 | // Start Polling 27 | updates, _ := bot.UpdatesViaLongPolling(nil) 28 | defer bot.StopLongPolling() 29 | 30 | // Create bot handler and specify from where to get updates 31 | bh, _ := th.NewBotHandler(bot, updates) 32 | 33 | // Stop handling updates 34 | defer bh.Stop() 35 | 36 | bh.Handle(func(bot *telego.Bot, update telego.Update) { 37 | _, _ = bot.SendMessage( 38 | &telego.SendMessageParams{ 39 | ChatID: update.Message.Chat.ChatID(), 40 | Text: fmt.Sprintf("Hello %s! Use /help command to get available commands!", update.Message.From.FirstName), 41 | ParseMode: "HTML", 42 | LinkPreviewOptions: &telego.LinkPreviewOptions{IsDisabled: true}, 43 | ReplyParameters: &telego.ReplyParameters{MessageID: update.Message.MessageID}, 44 | }, 45 | ) 46 | }, th.CommandEqual("start")) 47 | 48 | bh.Handle(func(bot *telego.Bot, update telego.Update) { 49 | _, _ = bot.SendMessage( 50 | &telego.SendMessageParams{ 51 | ChatID: update.Message.Chat.ChatID(), 52 | Text: fmt.Sprintf(` 53 | Hello %s! Have a look on supported commands: 54 | 55 | /chatID - Return current chatID 56 | /threadID - Return current threadID (If 0 then you are in General Thread or chat without Threads support)`, update.Message.From.FirstName), 57 | ParseMode: "HTML", 58 | LinkPreviewOptions: &telego.LinkPreviewOptions{IsDisabled: true}, 59 | ReplyParameters: &telego.ReplyParameters{MessageID: update.Message.MessageID}, 60 | }, 61 | ) 62 | }, th.CommandEqual("help")) 63 | 64 | bh.Handle(func(bot *telego.Bot, update telego.Update) { 65 | _, _ = bot.SendMessage( 66 | &telego.SendMessageParams{ 67 | ChatID: update.Message.Chat.ChatID(), 68 | Text: fmt.Sprintf("Current Thread ID:%v", update.Message.MessageThreadID),
69 | ParseMode: "HTML",
70 | LinkPreviewOptions: &telego.LinkPreviewOptions{IsDisabled: true},
71 | ReplyParameters: &telego.ReplyParameters{MessageID: update.Message.MessageID},
72 | },
73 | )
74 | }, th.CommandEqual("threadID"))
75 |
76 | bh.Handle(func(bot *telego.Bot, update telego.Update) {
77 | _, _ = bot.SendMessage(
78 | &telego.SendMessageParams{
79 | ChatID: update.Message.Chat.ChatID(),
80 | Text: fmt.Sprintf("Current chat ID: %v", update.Message.Chat.ID),
81 | ParseMode: "HTML",
82 | LinkPreviewOptions: &telego.LinkPreviewOptions{IsDisabled: true},
83 | ReplyParameters: &telego.ReplyParameters{MessageID: update.Message.MessageID},
84 | },
85 | )
86 | }, th.CommandEqual("chatID"))
87 |
88 | bh.Handle(func(bot *telego.Bot, update telego.Update) {
89 | _, _ = bot.SendMessage(
90 | &telego.SendMessageParams{
91 | ChatID: update.Message.Chat.ChatID(),
92 | Text: "Unknown command, use /help to get additional info about commands",
93 | ParseMode: "HTML",
94 | LinkPreviewOptions: &telego.LinkPreviewOptions{IsDisabled: true},
95 | ReplyParameters: &telego.ReplyParameters{MessageID: update.Message.MessageID},
96 | },
97 | )
98 | }, th.AnyCommand())
99 |
100 | // Start handling updates
101 | bh.Start()
102 | }
103 |
104 | func SendEventMessage(chatID string, eventMessage string) error {
105 | chatIDInt, err := strconv.Atoi(chatID)
106 | if err != nil {
107 | return err
108 | }
109 | _, err = Bot.SendMessage(
110 | &telego.SendMessageParams{
111 | ChatID: telego.ChatID{ID: int64(chatIDInt)},
112 | Text: eventMessage,
113 | ParseMode: "HTML",
114 | LinkPreviewOptions: &telego.LinkPreviewOptions{IsDisabled: true},
115 | },
116 | )
117 |
118 | return errors.Wrap(err, "Error while sending message to Telegram")
119 | }
120 |
121 | func SendEventMessageToThread(chatID, threadID, eventMessage string) error {
122 | chatIDInt, err := strconv.Atoi(chatID)
123 | if err != nil {
124 | return err
125 | }
126 |
127 | threadIDInt, err := strconv.Atoi(threadID)
128 | if err != nil {
129 | return err
130 | }
131 |
132 | _, err = Bot.SendMessage(
133 | &telego.SendMessageParams{
134 | ChatID: telego.ChatID{ID: int64(chatIDInt)},
135 | MessageThreadID: int(threadIDInt),
136 | Text: eventMessage,
137 | ParseMode: "HTML",
138 | LinkPreviewOptions: &telego.LinkPreviewOptions{IsDisabled: true},
139 | },
140 | )
141 |
142 | return errors.Wrap(err, "Error while sending message to Telegram")
143 | }
144 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
2 | github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
3 | github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
4 | github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
5 | github.com/bytedance/sonic v1.10.2 h1:GQebETVBxYB7JGWJtLBi07OVzWwt+8dWA00gEVW2ZFE=
6 | github.com/bytedance/sonic v1.10.2/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
7 | github.com/caarlos0/env/v6 v6.10.1 h1:t1mPSxNpei6M5yAeu1qtRdPAK29Nbcf/n3G7x+b3/II=
8 | github.com/caarlos0/env/v6 v6.10.1/go.mod h1:hvp/ryKXKipEkcuYjs9mI4bBCg+UI0Yhgm5Zu0ddvwc=
9 | github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
10 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
11 | github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
12 | github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
13 | github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
14 | github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0=
15 | github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
16 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
17 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
18 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
19 | github.com/fasthttp/router v1.4.22 h1:qwWcYBbndVDwts4dKaz+A2ehsnbKilmiP6pUhXBfYKo=
20 | github.com/fasthttp/router v1.4.22/go.mod h1:KeMvHLqhlB9vyDWD5TSvTccl9qeWrjSSiTJrJALHKV0=
21 | github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0=
22 | github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w=
23 | github.com/gookit/goutil v0.6.15 h1:mMQ0ElojNZoyPD0eVROk5QXJPh2uKR4g06slgPDF5Jo=
24 | github.com/gookit/goutil v0.6.15/go.mod h1:qdKdYEHQdEtyH+4fNdQNZfJHhI0jUZzHxQVAV3DaMDY=
25 | github.com/gookit/gsr v0.1.0 h1:0gadWaYGU4phMs0bma38t+Do5OZowRMEVlHv31p0Zig=
26 | github.com/gookit/gsr v0.1.0/go.mod h1:7wv4Y4WCnil8+DlDYHBjidzrEzfHhXEoFjEA0pPPWpI=
27 | github.com/gookit/slog v0.5.5 h1:XoyK3NilKzuC/umvnqTQDHTOnpC8R6pvlr/ht9PyfgU=
28 | github.com/gookit/slog v0.5.5/go.mod h1:RfIwzoaQ8wZbKdcqG7+3EzbkMqcp2TUn3mcaSZAw2EQ=
29 | github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
30 | github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
31 | github.com/grbit/go-json v0.11.0 h1:bAbyMdYrYl/OjYsSqLH99N2DyQ291mHy726Mx+sYrnc=
32 | github.com/grbit/go-json v0.11.0/go.mod h1:IYpHsdybQ386+6g3VE6AXQ3uTGa5mquBme5/ZWmtzek=
33 | github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI=
34 | github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
35 | github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
36 | github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
37 | github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
38 | github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
39 | github.com/mymmrac/telego v0.29.1 h1:nsNnK0mS18OL+unoDjDI6BVfafJBbT8Wtj7rCzEWoM8=
40 | github.com/mymmrac/telego v0.29.1/go.mod h1:ZLD1+L2TQRr97NPOCoN1V2w8y9kmFov33OfZ3qT8cF4=
41 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
42 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
43 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
44 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
45 | github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee h1:8Iv5m6xEo1NR1AvpV+7XmhI4r39LGNzwUL4YpMuL5vk=
46 | github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee/go.mod h1:qwtSXrKuJh/zsFQ12yEE89xfCrGKK63Rr7ctU/uCo4g=
47 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
48 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
49 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
50 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
51 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
52 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
53 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
54 | github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
55 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
56 | github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
57 | github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
58 | github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
59 | github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
60 | github.com/valyala/fasthttp v1.52.0 h1:wqBQpxH71XW0e2g+Og4dzQM8pk34aFYlA1Ga8db7gU0=
61 | github.com/valyala/fasthttp v1.52.0/go.mod h1:hf5C4QnVMkNXMspnsUlfM3WitlgYflyhHYoKol/szxQ=
62 | github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ=
63 | github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
64 | github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
65 | github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
66 | go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
67 | go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
68 | golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
69 | golang.org/x/arch v0.6.0 h1:S0JTfE48HbRj80+4tbvZDYsJ3tGv6BUU3XxyZ7CirAc=
70 | golang.org/x/arch v0.6.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
71 | golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E=
72 | golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
73 | golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
74 | golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
75 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
76 | golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
77 | golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
78 | golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
79 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
80 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
81 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
82 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
83 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
84 | nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
85 | rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
86 |
--------------------------------------------------------------------------------
/pkg/events/models.go:
--------------------------------------------------------------------------------
1 | package events
2 |
3 | import "time"
4 |
5 | type GitlabEventTypeDetector struct {
6 | ObjectKind string `json:"object_kind"`
7 | }
8 |
9 | type GitlabPushEvent struct {
10 | ObjectKind string `json:"object_kind"`
11 | EventName string `json:"event_name"`
12 | Before string `json:"before"`
13 | After string `json:"after"`
14 | Ref string `json:"ref"`
15 | CheckoutSha string `json:"checkout_sha"`
16 | Message interface{} `json:"message"`
17 | UserID int `json:"user_id"`
18 | UserName string `json:"user_name"`
19 | UserUsername string `json:"user_username"`
20 | UserEmail string `json:"user_email"`
21 | UserAvatar string `json:"user_avatar"`
22 | ProjectID int `json:"project_id"`
23 | Project struct {
24 | ID int `json:"id"`
25 | Name string `json:"name"`
26 | Description string `json:"description"`
27 | WebURL string `json:"web_url"`
28 | AvatarURL interface{} `json:"avatar_url"`
29 | GitSSHURL string `json:"git_ssh_url"`
30 | GitHTTPURL string `json:"git_http_url"`
31 | Namespace string `json:"namespace"`
32 | VisibilityLevel int `json:"visibility_level"`
33 | PathWithNamespace string `json:"path_with_namespace"`
34 | DefaultBranch string `json:"default_branch"`
35 | CiConfigPath string `json:"ci_config_path"`
36 | Homepage string `json:"homepage"`
37 | URL string `json:"url"`
38 | SSHURL string `json:"ssh_url"`
39 | HTTPURL string `json:"http_url"`
40 | } `json:"project"`
41 | Commits []struct {
42 | ID string `json:"id"`
43 | Message string `json:"message"`
44 | Title string `json:"title"`
45 | Timestamp time.Time `json:"timestamp"`
46 | URL string `json:"url"`
47 | Author struct {
48 | Name string `json:"name"`
49 | Email string `json:"email"`
50 | } `json:"author"`
51 | Added []interface{} `json:"added"`
52 | Modified []string `json:"modified"`
53 | Removed []interface{} `json:"removed"`
54 | } `json:"commits"`
55 | TotalCommitsCount int `json:"total_commits_count"`
56 | PushOptions struct {
57 | } `json:"push_options"`
58 | Repository struct {
59 | Name string `json:"name"`
60 | URL string `json:"url"`
61 | Description string `json:"description"`
62 | Homepage string `json:"homepage"`
63 | GitHTTPURL string `json:"git_http_url"`
64 | GitSSHURL string `json:"git_ssh_url"`
65 | VisibilityLevel int `json:"visibility_level"`
66 | } `json:"repository"`
67 | }
68 |
69 | type GitlabTagPushEvent struct {
70 | ObjectKind string `json:"object_kind"`
71 | EventName string `json:"event_name"`
72 | Before string `json:"before"`
73 | After string `json:"after"`
74 | Ref string `json:"ref"`
75 | CheckoutSha string `json:"checkout_sha"`
76 | Message interface{} `json:"message"`
77 | UserID int `json:"user_id"`
78 | UserName string `json:"user_name"`
79 | UserUsername string `json:"user_username"`
80 | UserEmail string `json:"user_email"`
81 | UserAvatar string `json:"user_avatar"`
82 | ProjectID int `json:"project_id"`
83 | Project struct {
84 | ID int `json:"id"`
85 | Name string `json:"name"`
86 | Description string `json:"description"`
87 | WebURL string `json:"web_url"`
88 | AvatarURL interface{} `json:"avatar_url"`
89 | GitSSHURL string `json:"git_ssh_url"`
90 | GitHTTPURL string `json:"git_http_url"`
91 | Namespace string `json:"namespace"`
92 | VisibilityLevel int `json:"visibility_level"`
93 | PathWithNamespace string `json:"path_with_namespace"`
94 | DefaultBranch string `json:"default_branch"`
95 | CiConfigPath string `json:"ci_config_path"`
96 | Homepage string `json:"homepage"`
97 | URL string `json:"url"`
98 | SSHURL string `json:"ssh_url"`
99 | HTTPURL string `json:"http_url"`
100 | } `json:"project"`
101 | Commits []struct {
102 | ID string `json:"id"`
103 | Message string `json:"message"`
104 | Title string `json:"title"`
105 | Timestamp time.Time `json:"timestamp"`
106 | URL string `json:"url"`
107 | Author struct {
108 | Name string `json:"name"`
109 | Email string `json:"email"`
110 | } `json:"author"`
111 | Added []interface{} `json:"added"`
112 | Modified []string `json:"modified"`
113 | Removed []interface{} `json:"removed"`
114 | } `json:"commits"`
115 | TotalCommitsCount int `json:"total_commits_count"`
116 | PushOptions struct {
117 | } `json:"push_options"`
118 | Repository struct {
119 | Name string `json:"name"`
120 | URL string `json:"url"`
121 | Description string `json:"description"`
122 | Homepage string `json:"homepage"`
123 | GitHTTPURL string `json:"git_http_url"`
124 | GitSSHURL string `json:"git_ssh_url"`
125 | VisibilityLevel int `json:"visibility_level"`
126 | } `json:"repository"`
127 | }
128 |
129 | type GitlabNoteEvent struct {
130 | ObjectKind string `json:"object_kind"`
131 | EventType string `json:"event_type"`
132 | User struct {
133 | ID int `json:"id"`
134 | Name string `json:"name"`
135 | Username string `json:"username"`
136 | AvatarURL string `json:"avatar_url"`
137 | Email string `json:"email"`
138 | } `json:"user"`
139 | ProjectID int `json:"project_id"`
140 | Project struct {
141 | ID int `json:"id"`
142 | Name string `json:"name"`
143 | Description string `json:"description"`
144 | WebURL string `json:"web_url"`
145 | AvatarURL interface{} `json:"avatar_url"`
146 | GitSSHURL string `json:"git_ssh_url"`
147 | GitHTTPURL string `json:"git_http_url"`
148 | Namespace string `json:"namespace"`
149 | VisibilityLevel int `json:"visibility_level"`
150 | PathWithNamespace string `json:"path_with_namespace"`
151 | DefaultBranch string `json:"default_branch"`
152 | CiConfigPath string `json:"ci_config_path"`
153 | Homepage string `json:"homepage"`
154 | URL string `json:"url"`
155 | SSHURL string `json:"ssh_url"`
156 | HTTPURL string `json:"http_url"`
157 | } `json:"project"`
158 | ObjectAttributes struct {
159 | Attachment interface{} `json:"attachment"`
160 | AuthorID int `json:"author_id"`
161 | ChangePosition interface{} `json:"change_position"`
162 | CommitID string `json:"commit_id"`
163 | CreatedAt time.Time `json:"created_at"`
164 | DiscussionID string `json:"discussion_id"`
165 | ID int `json:"id"`
166 | LineCode interface{} `json:"line_code"`
167 | Note string `json:"note"`
168 | NoteableID interface{} `json:"noteable_id"`
169 | NoteableType string `json:"noteable_type"`
170 | OriginalPosition interface{} `json:"original_position"`
171 | Position interface{} `json:"position"`
172 | ProjectID int `json:"project_id"`
173 | ResolvedAt interface{} `json:"resolved_at"`
174 | ResolvedByID interface{} `json:"resolved_by_id"`
175 | ResolvedByPush interface{} `json:"resolved_by_push"`
176 | StDiff interface{} `json:"st_diff"`
177 | System bool `json:"system"`
178 | Type interface{} `json:"type"`
179 | UpdatedAt time.Time `json:"updated_at"`
180 | UpdatedByID interface{} `json:"updated_by_id"`
181 | Description string `json:"description"`
182 | URL string `json:"url"`
183 | } `json:"object_attributes"`
184 | Repository struct {
185 | Name string `json:"name"`
186 | URL string `json:"url"`
187 | Description string `json:"description"`
188 | Homepage string `json:"homepage"`
189 | } `json:"repository"`
190 | Commit struct {
191 | ID string `json:"id"`
192 | Message string `json:"message"`
193 | Title string `json:"title"`
194 | Timestamp time.Time `json:"timestamp"`
195 | URL string `json:"url"`
196 | Author struct {
197 | Name string `json:"name"`
198 | Email string `json:"email"`
199 | } `json:"author"`
200 | } `json:"commit"`
201 | }
202 |
203 | type AutoGenerated struct {
204 | ObjectKind string `json:"object_kind"`
205 | EventType string `json:"event_type"`
206 | User struct {
207 | ID int `json:"id"`
208 | Name string `json:"name"`
209 | Username string `json:"username"`
210 | AvatarURL string `json:"avatar_url"`
211 | Email string `json:"email"`
212 | } `json:"user"`
213 | Project struct {
214 | ID int `json:"id"`
215 | Name string `json:"name"`
216 | Description string `json:"description"`
217 | WebURL string `json:"web_url"`
218 | AvatarURL interface{} `json:"avatar_url"`
219 | GitSSHURL string `json:"git_ssh_url"`
220 | GitHTTPURL string `json:"git_http_url"`
221 | Namespace string `json:"namespace"`
222 | VisibilityLevel int `json:"visibility_level"`
223 | PathWithNamespace string `json:"path_with_namespace"`
224 | DefaultBranch string `json:"default_branch"`
225 | CiConfigPath string `json:"ci_config_path"`
226 | Homepage string `json:"homepage"`
227 | URL string `json:"url"`
228 | SSHURL string `json:"ssh_url"`
229 | HTTPURL string `json:"http_url"`
230 | } `json:"project"`
231 | ObjectAttributes struct {
232 | AssigneeID interface{} `json:"assignee_id"`
233 | AuthorID int `json:"author_id"`
234 | CreatedAt time.Time `json:"created_at"`
235 | Description string `json:"description"`
236 | HeadPipelineID interface{} `json:"head_pipeline_id"`
237 | ID int `json:"id"`
238 | Iid int `json:"iid"`
239 | LastEditedAt interface{} `json:"last_edited_at"`
240 | LastEditedByID interface{} `json:"last_edited_by_id"`
241 | MergeCommitSha interface{} `json:"merge_commit_sha"`
242 | MergeError interface{} `json:"merge_error"`
243 | MergeParams struct {
244 | ForceRemoveSourceBranch string `json:"force_remove_source_branch"`
245 | } `json:"merge_params"`
246 | MergeStatus string `json:"merge_status"`
247 | MergeUserID interface{} `json:"merge_user_id"`
248 | MergeWhenPipelineSucceeds bool `json:"merge_when_pipeline_succeeds"`
249 | MilestoneID interface{} `json:"milestone_id"`
250 | SourceBranch string `json:"source_branch"`
251 | SourceProjectID int `json:"source_project_id"`
252 | StateID int `json:"state_id"`
253 | TargetBranch string `json:"target_branch"`
254 | TargetProjectID int `json:"target_project_id"`
255 | TimeEstimate int `json:"time_estimate"`
256 | Title string `json:"title"`
257 | UpdatedAt time.Time `json:"updated_at"`
258 | UpdatedByID interface{} `json:"updated_by_id"`
259 | URL string `json:"url"`
260 | Source struct {
261 | ID int `json:"id"`
262 | Name string `json:"name"`
263 | Description string `json:"description"`
264 | WebURL string `json:"web_url"`
265 | AvatarURL interface{} `json:"avatar_url"`
266 | GitSSHURL string `json:"git_ssh_url"`
267 | GitHTTPURL string `json:"git_http_url"`
268 | Namespace string `json:"namespace"`
269 | VisibilityLevel int `json:"visibility_level"`
270 | PathWithNamespace string `json:"path_with_namespace"`
271 | DefaultBranch string `json:"default_branch"`
272 | CiConfigPath string `json:"ci_config_path"`
273 | Homepage string `json:"homepage"`
274 | URL string `json:"url"`
275 | SSHURL string `json:"ssh_url"`
276 | HTTPURL string `json:"http_url"`
277 | } `json:"source"`
278 | Target struct {
279 | ID int `json:"id"`
280 | Name string `json:"name"`
281 | Description string `json:"description"`
282 | WebURL string `json:"web_url"`
283 | AvatarURL interface{} `json:"avatar_url"`
284 | GitSSHURL string `json:"git_ssh_url"`
285 | GitHTTPURL string `json:"git_http_url"`
286 | Namespace string `json:"namespace"`
287 | VisibilityLevel int `json:"visibility_level"`
288 | PathWithNamespace string `json:"path_with_namespace"`
289 | DefaultBranch string `json:"default_branch"`
290 | CiConfigPath string `json:"ci_config_path"`
291 | Homepage string `json:"homepage"`
292 | URL string `json:"url"`
293 | SSHURL string `json:"ssh_url"`
294 | HTTPURL string `json:"http_url"`
295 | } `json:"target"`
296 | LastCommit struct {
297 | ID string `json:"id"`
298 | Message string `json:"message"`
299 | Title string `json:"title"`
300 | Timestamp time.Time `json:"timestamp"`
301 | URL string `json:"url"`
302 | Author struct {
303 | Name string `json:"name"`
304 | Email string `json:"email"`
305 | } `json:"author"`
306 | } `json:"last_commit"`
307 | WorkInProgress bool `json:"work_in_progress"`
308 | TotalTimeSpent int `json:"total_time_spent"`
309 | HumanTotalTimeSpent interface{} `json:"human_total_time_spent"`
310 | HumanTimeEstimate interface{} `json:"human_time_estimate"`
311 | AssigneeIds []interface{} `json:"assignee_ids"`
312 | State string `json:"state"`
313 | } `json:"object_attributes"`
314 | Labels []interface{} `json:"labels"`
315 | Changes struct {
316 | } `json:"changes"`
317 | Repository struct {
318 | Name string `json:"name"`
319 | URL string `json:"url"`
320 | Description string `json:"description"`
321 | Homepage string `json:"homepage"`
322 | } `json:"repository"`
323 | }
324 |
325 | type GitlabMergeRequestEvent struct {
326 | ObjectKind string `json:"object_kind"`
327 | EventType string `json:"event_type"`
328 | User struct {
329 | ID int `json:"id"`
330 | Name string `json:"name"`
331 | Username string `json:"username"`
332 | AvatarURL string `json:"avatar_url"`
333 | Email string `json:"email"`
334 | } `json:"user"`
335 | Project struct {
336 | ID int `json:"id"`
337 | Name string `json:"name"`
338 | Description string `json:"description"`
339 | WebURL string `json:"web_url"`
340 | AvatarURL interface{} `json:"avatar_url"`
341 | GitSSHURL string `json:"git_ssh_url"`
342 | GitHTTPURL string `json:"git_http_url"`
343 | Namespace string `json:"namespace"`
344 | VisibilityLevel int `json:"visibility_level"`
345 | PathWithNamespace string `json:"path_with_namespace"`
346 | DefaultBranch string `json:"default_branch"`
347 | CiConfigPath string `json:"ci_config_path"`
348 | Homepage string `json:"homepage"`
349 | URL string `json:"url"`
350 | SSHURL string `json:"ssh_url"`
351 | HTTPURL string `json:"http_url"`
352 | } `json:"project"`
353 | ObjectAttributes struct {
354 | AssigneeID interface{} `json:"assignee_id"`
355 | AuthorID int `json:"author_id"`
356 | CreatedAt time.Time `json:"created_at"`
357 | Description string `json:"description"`
358 | HeadPipelineID interface{} `json:"head_pipeline_id"`
359 | ID int `json:"id"`
360 | Iid int `json:"iid"`
361 | LastEditedAt interface{} `json:"last_edited_at"`
362 | LastEditedByID interface{} `json:"last_edited_by_id"`
363 | MergeCommitSha interface{} `json:"merge_commit_sha"`
364 | MergeError interface{} `json:"merge_error"`
365 | MergeParams struct {
366 | ForceRemoveSourceBranch string `json:"force_remove_source_branch"`
367 | } `json:"merge_params"`
368 | MergeStatus string `json:"merge_status"`
369 | MergeUserID interface{} `json:"merge_user_id"`
370 | MergeWhenPipelineSucceeds bool `json:"merge_when_pipeline_succeeds"`
371 | MilestoneID interface{} `json:"milestone_id"`
372 | SourceBranch string `json:"source_branch"`
373 | SourceProjectID int `json:"source_project_id"`
374 | StateID int `json:"state_id"`
375 | TargetBranch string `json:"target_branch"`
376 | TargetProjectID int `json:"target_project_id"`
377 | TimeEstimate int `json:"time_estimate"`
378 | Title string `json:"title"`
379 | UpdatedAt time.Time `json:"updated_at"`
380 | UpdatedByID interface{} `json:"updated_by_id"`
381 | URL string `json:"url"`
382 | Source struct {
383 | ID int `json:"id"`
384 | Name string `json:"name"`
385 | Description string `json:"description"`
386 | WebURL string `json:"web_url"`
387 | AvatarURL interface{} `json:"avatar_url"`
388 | GitSSHURL string `json:"git_ssh_url"`
389 | GitHTTPURL string `json:"git_http_url"`
390 | Namespace string `json:"namespace"`
391 | VisibilityLevel int `json:"visibility_level"`
392 | PathWithNamespace string `json:"path_with_namespace"`
393 | DefaultBranch string `json:"default_branch"`
394 | CiConfigPath string `json:"ci_config_path"`
395 | Homepage string `json:"homepage"`
396 | URL string `json:"url"`
397 | SSHURL string `json:"ssh_url"`
398 | HTTPURL string `json:"http_url"`
399 | } `json:"source"`
400 | Target struct {
401 | ID int `json:"id"`
402 | Name string `json:"name"`
403 | Description string `json:"description"`
404 | WebURL string `json:"web_url"`
405 | AvatarURL interface{} `json:"avatar_url"`
406 | GitSSHURL string `json:"git_ssh_url"`
407 | GitHTTPURL string `json:"git_http_url"`
408 | Namespace string `json:"namespace"`
409 | VisibilityLevel int `json:"visibility_level"`
410 | PathWithNamespace string `json:"path_with_namespace"`
411 | DefaultBranch string `json:"default_branch"`
412 | CiConfigPath string `json:"ci_config_path"`
413 | Homepage string `json:"homepage"`
414 | URL string `json:"url"`
415 | SSHURL string `json:"ssh_url"`
416 | HTTPURL string `json:"http_url"`
417 | } `json:"target"`
418 | LastCommit struct {
419 | ID string `json:"id"`
420 | Message string `json:"message"`
421 | Title string `json:"title"`
422 | Timestamp time.Time `json:"timestamp"`
423 | URL string `json:"url"`
424 | Author struct {
425 | Name string `json:"name"`
426 | Email string `json:"email"`
427 | } `json:"author"`
428 | } `json:"last_commit"`
429 | WorkInProgress bool `json:"work_in_progress"`
430 | TotalTimeSpent int `json:"total_time_spent"`
431 | HumanTotalTimeSpent interface{} `json:"human_total_time_spent"`
432 | HumanTimeEstimate interface{} `json:"human_time_estimate"`
433 | AssigneeIds []interface{} `json:"assignee_ids"`
434 | State string `json:"state"`
435 | } `json:"object_attributes"`
436 | Labels []interface{} `json:"labels"`
437 | Changes struct {
438 | } `json:"changes"`
439 | Repository struct {
440 | Name string `json:"name"`
441 | URL string `json:"url"`
442 | Description string `json:"description"`
443 | Homepage string `json:"homepage"`
444 | } `json:"repository"`
445 | }
446 |
447 | type GitlabJobEvent struct {
448 | ObjectKind string `json:"object_kind"`
449 | Ref string `json:"ref"`
450 | Tag bool `json:"tag"`
451 | BeforeSha string `json:"before_sha"`
452 | Sha string `json:"sha"`
453 | BuildID int `json:"build_id"`
454 | BuildName string `json:"build_name"`
455 | BuildStage string `json:"build_stage"`
456 | BuildStatus string `json:"build_status"`
457 | BuildStartedAt time.Time `json:"build_started_at"`
458 | BuildFinishedAt time.Time `json:"build_finished_at"`
459 | BuildDuration float64 `json:"build_duration"`
460 | BuildAllowFailure bool `json:"build_allow_failure"`
461 | BuildFailureReason string `json:"build_failure_reason"`
462 | PipelineID int `json:"pipeline_id"`
463 | Runner interface{} `json:"runner"`
464 | ProjectID int `json:"project_id"`
465 | ProjectName string `json:"project_name"`
466 | User struct {
467 | ID int `json:"id"`
468 | Name string `json:"name"`
469 | Username string `json:"username"`
470 | AvatarURL string `json:"avatar_url"`
471 | Email string `json:"email"`
472 | } `json:"user"`
473 | Commit struct {
474 | ID int `json:"id"`
475 | Sha string `json:"sha"`
476 | Message string `json:"message"`
477 | AuthorName string `json:"author_name"`
478 | AuthorEmail string `json:"author_email"`
479 | AuthorURL string `json:"author_url"`
480 | Status string `json:"status"`
481 | Duration int `json:"duration"`
482 | StartedAt time.Time `json:"started_at"`
483 | FinishedAt time.Time `json:"finished_at"`
484 | } `json:"commit"`
485 | Repository struct {
486 | Name string `json:"name"`
487 | URL string `json:"url"`
488 | Description string `json:"description"`
489 | Homepage string `json:"homepage"`
490 | GitHTTPURL string `json:"git_http_url"`
491 | GitSSHURL string `json:"git_ssh_url"`
492 | VisibilityLevel int `json:"visibility_level"`
493 | } `json:"repository"`
494 | }
495 |
496 | type GitlabPipelineEvent struct {
497 | ObjectKind string `json:"object_kind"`
498 | ObjectAttributes struct {
499 | ID int `json:"id"`
500 | Ref string `json:"ref"`
501 | Tag bool `json:"tag"`
502 | Sha string `json:"sha"`
503 | BeforeSha string `json:"before_sha"`
504 | Source string `json:"source"`
505 | Status string `json:"status"`
506 | DetailedStatus string `json:"detailed_status"`
507 | Stages []string `json:"stages"`
508 | CreatedAt time.Time `json:"created_at"`
509 | FinishedAt time.Time `json:"finished_at"`
510 | Duration int `json:"duration"`
511 | Variables []interface{} `json:"variables"`
512 | } `json:"object_attributes"`
513 | MergeRequest interface{} `json:"merge_request"`
514 | User struct {
515 | ID int `json:"id"`
516 | Name string `json:"name"`
517 | Username string `json:"username"`
518 | AvatarURL string `json:"avatar_url"`
519 | Email string `json:"email"`
520 | } `json:"user"`
521 | Project struct {
522 | ID int `json:"id"`
523 | Name string `json:"name"`
524 | Description string `json:"description"`
525 | WebURL string `json:"web_url"`
526 | AvatarURL interface{} `json:"avatar_url"`
527 | GitSSHURL string `json:"git_ssh_url"`
528 | GitHTTPURL string `json:"git_http_url"`
529 | Namespace string `json:"namespace"`
530 | VisibilityLevel int `json:"visibility_level"`
531 | PathWithNamespace string `json:"path_with_namespace"`
532 | DefaultBranch string `json:"default_branch"`
533 | CiConfigPath string `json:"ci_config_path"`
534 | } `json:"project"`
535 | Commit struct {
536 | ID string `json:"id"`
537 | Message string `json:"message"`
538 | Title string `json:"title"`
539 | Timestamp time.Time `json:"timestamp"`
540 | URL string `json:"url"`
541 | Author struct {
542 | Name string `json:"name"`
543 | Email string `json:"email"`
544 | } `json:"author"`
545 | } `json:"commit"`
546 | Builds []struct {
547 | ID int `json:"id"`
548 | Stage string `json:"stage"`
549 | Name string `json:"name"`
550 | Status string `json:"status"`
551 | CreatedAt time.Time `json:"created_at"`
552 | StartedAt time.Time `json:"started_at"`
553 | FinishedAt time.Time `json:"finished_at"`
554 | When string `json:"when"`
555 | Manual bool `json:"manual"`
556 | AllowFailure bool `json:"allow_failure"`
557 | User struct {
558 | ID int `json:"id"`
559 | Name string `json:"name"`
560 | Username string `json:"username"`
561 | AvatarURL string `json:"avatar_url"`
562 | Email string `json:"email"`
563 | } `json:"user"`
564 | Runner interface{} `json:"runner"`
565 | ArtifactsFile struct {
566 | Filename interface{} `json:"filename"`
567 | Size interface{} `json:"size"`
568 | } `json:"artifacts_file"`
569 | } `json:"builds"`
570 | }
571 |
--------------------------------------------------------------------------------