event_parsing.go 3.0 KB

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