You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

github.go 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. package httplistener
  2. import (
  3. "fmt"
  4. "github.com/spf13/viper"
  5. "gopkg.in/go-playground/webhooks.v5/github"
  6. "net/http"
  7. "strings"
  8. )
  9. func interestingIssueAction(action string) bool {
  10. switch action {
  11. case "opened", "closed", "reopened":
  12. return true
  13. }
  14. return false
  15. }
  16. func (hl *HTTPListener) githubHandler(w http.ResponseWriter, request *http.Request) {
  17. if request.Method != "POST" {
  18. http.NotFound(w, request)
  19. return
  20. }
  21. hook, err := github.New(github.Options.Secret(viper.GetString("http.listeners.github.secret")))
  22. if err != nil {
  23. return
  24. }
  25. // All valid events we want to receive need to be listed here.
  26. payload, err := hook.Parse(request,
  27. github.ReleaseEvent, github.PushEvent, github.IssuesEvent, github.IssueCommentEvent,
  28. github.PullRequestEvent, github.CheckSuiteEvent)
  29. if err != nil {
  30. if err == github.ErrEventNotFound {
  31. // We've received an event we don't need to handle, return normally
  32. return
  33. }
  34. log.Warningf("Error parsing github webhook: %s", err)
  35. http.Error(w, "Error processing webhook", http.StatusBadRequest)
  36. return
  37. }
  38. msgs := []string{}
  39. repo := ""
  40. send := false
  41. switch payload.(type) {
  42. case github.ReleasePayload:
  43. pl := payload.(github.ReleasePayload)
  44. if pl.Action == "published" {
  45. send = true
  46. msgs, err = hl.renderTemplate("github.release", payload)
  47. repo = pl.Repository.Name
  48. }
  49. case github.PushPayload:
  50. pl := payload.(github.PushPayload)
  51. send = true
  52. msgs, err = hl.renderTemplate("github.push", payload)
  53. repo = pl.Repository.Name
  54. case github.IssuesPayload:
  55. pl := payload.(github.IssuesPayload)
  56. if interestingIssueAction(pl.Action) {
  57. send = true
  58. msgs, err = hl.renderTemplate("github.issue", payload)
  59. repo = pl.Repository.Name
  60. }
  61. case github.IssueCommentPayload:
  62. pl := payload.(github.IssueCommentPayload)
  63. if pl.Action == "created" {
  64. send = true
  65. msgs, err = hl.renderTemplate("github.issuecomment", payload)
  66. repo = pl.Repository.Name
  67. }
  68. case github.PullRequestPayload:
  69. pl := payload.(github.PullRequestPayload)
  70. if interestingIssueAction(pl.Action) {
  71. send = true
  72. msgs, err = hl.renderTemplate("github.pullrequest", payload)
  73. repo = pl.Repository.Name
  74. }
  75. case github.CheckSuitePayload:
  76. pl := payload.(github.CheckSuitePayload)
  77. if pl.CheckSuite.Status == "completed" && pl.CheckSuite.Conclusion == "failure" {
  78. send = true
  79. msgs, err = hl.renderTemplate("github.checksuite", payload)
  80. repo = pl.Repository.Name
  81. }
  82. }
  83. if err != nil {
  84. log.Errorf("Error rendering GitHub event template: %s", err)
  85. return
  86. }
  87. if send {
  88. repo = strings.ToLower(repo)
  89. channel := viper.GetString(fmt.Sprintf("http.listeners.github.repositories.%s", repo))
  90. if channel == "" {
  91. channel = viper.GetString("http.listeners.github.default_channel")
  92. }
  93. if channel == "" {
  94. log.Infof("%s GitHub event for unrecognised repository %s", request.RemoteAddr, repo)
  95. return
  96. }
  97. log.Infof("%s [%s -> %s] GitHub event received", request.RemoteAddr, repo, channel)
  98. for _, msg := range msgs {
  99. hl.irc.Privmsg(channel, msg)
  100. }
  101. }
  102. }