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 := ¬eEvent{} 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} 118