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 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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)
  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. }
  76. if err != nil {
  77. log.Errorf("Error rendering GitHub event template: %s", err)
  78. return
  79. }
  80. if send {
  81. repo = strings.ToLower(repo)
  82. channel := viper.GetString(fmt.Sprintf("http.listeners.github.repositories.%s", repo))
  83. if channel == "" {
  84. channel = viper.GetString("http.listeners.github.default_channel")
  85. }
  86. if channel == "" {
  87. log.Infof("%s GitHub event for unrecognised repository %s", request.RemoteAddr, repo)
  88. return
  89. }
  90. log.Infof("%s [%s -> %s] GitHub event received", request.RemoteAddr, repo, channel)
  91. for _, msg := range msgs {
  92. hl.irc.Privmsg(channel, msg)
  93. }
  94. }
  95. }