event_parsing.go

  1package gitlab
  2
  3import (
  4	"encoding/json"
  5	"fmt"
  6	"net/http"
  7)
  8
  9// EventType represents a Gitlab event type.
 10type EventType string
 11
 12// List of available event types.
 13const (
 14	EventTypeBuild        EventType = "Build Hook"
 15	EventTypeIssue        EventType = "Issue Hook"
 16	EventTypeJob          EventType = "Job Hook"
 17	EventTypeMergeRequest EventType = "Merge Request Hook"
 18	EventTypeNote         EventType = "Note Hook"
 19	EventTypePipeline     EventType = "Pipeline Hook"
 20	EventTypePush         EventType = "Push Hook"
 21	EventTypeTagPush      EventType = "Tag Push Hook"
 22	EventTypeWikiPage     EventType = "Wiki Page Hook"
 23)
 24
 25const (
 26	noteableTypeCommit       = "Commit"
 27	noteableTypeMergeRequest = "MergeRequest"
 28	noteableTypeIssue        = "Issue"
 29	noteableTypeSnippet      = "Snippet"
 30)
 31
 32type noteEvent struct {
 33	ObjectKind       string `json:"object_kind"`
 34	ObjectAttributes struct {
 35		NoteableType string `json:"noteable_type"`
 36	} `json:"object_attributes"`
 37}
 38
 39const eventTypeHeader = "X-Gitlab-Event"
 40
 41// WebhookEventType returns the event type for the given request.
 42func WebhookEventType(r *http.Request) EventType {
 43	return EventType(r.Header.Get(eventTypeHeader))
 44}
 45
 46// ParseWebhook parses the event payload. For recognized event types, a
 47// value of the corresponding struct type will be returned. An error will
 48// be returned for unrecognized event types.
 49//
 50// Example usage:
 51//
 52// func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 53//     payload, err := ioutil.ReadAll(r.Body)
 54//     if err != nil { ... }
 55//     event, err := gitlab.ParseWebhook(gitlab.WebhookEventType(r), payload)
 56//     if err != nil { ... }
 57//     switch event := event.(type) {
 58//     case *gitlab.PushEvent:
 59//         processPushEvent(event)
 60//     case *gitlab.MergeEvent:
 61//         processMergeEvent(event)
 62//     ...
 63//     }
 64// }
 65//
 66func ParseWebhook(eventType EventType, payload []byte) (event interface{}, err error) {
 67	switch eventType {
 68	case EventTypeBuild:
 69		event = &BuildEvent{}
 70	case EventTypeIssue:
 71		event = &IssueEvent{}
 72	case EventTypeJob:
 73		event = &JobEvent{}
 74	case EventTypeMergeRequest:
 75		event = &MergeEvent{}
 76	case EventTypePipeline:
 77		event = &PipelineEvent{}
 78	case EventTypePush:
 79		event = &PushEvent{}
 80	case EventTypeTagPush:
 81		event = &TagEvent{}
 82	case EventTypeWikiPage:
 83		event = &WikiPageEvent{}
 84	case EventTypeNote:
 85		note := &noteEvent{}
 86		err := json.Unmarshal(payload, note)
 87		if err != nil {
 88			return nil, err
 89		}
 90
 91		if note.ObjectKind != "note" {
 92			return nil, fmt.Errorf("unexpected object kind %s", note.ObjectKind)
 93		}
 94
 95		switch note.ObjectAttributes.NoteableType {
 96		case noteableTypeCommit:
 97			event = &CommitCommentEvent{}
 98		case noteableTypeMergeRequest:
 99			event = &MergeCommentEvent{}
100		case noteableTypeIssue:
101			event = &IssueCommentEvent{}
102		case noteableTypeSnippet:
103			event = &SnippetCommentEvent{}
104		default:
105			return nil, fmt.Errorf("unexpected noteable type %s", note.ObjectAttributes.NoteableType)
106		}
107
108	default:
109		return nil, fmt.Errorf("unexpected event type: %s", eventType)
110	}
111
112	if err := json.Unmarshal(payload, event); err != nil {
113		return nil, err
114	}
115
116	return event, nil
117}