Skip to content

Commit

Permalink
GIthub Discussions and Discussion Comments Webhooks (#808)
Browse files Browse the repository at this point in the history
* feat: added github discussions and discussion comment webhooks

* fix: remove additional logging

* "fix: remove white space"

Co-authored-by: Felipe Martin <812088+fmartingr@users.noreply.github.com>

* "fix: correct spelling of discussion"

Co-authored-by: Felipe Martin <812088+fmartingr@users.noreply.github.com>

* fix: spelling of discussions

Co-authored-by: Felipe Martin <812088+fmartingr@users.noreply.github.com>

* Update server/plugin/webhook.go

Co-authored-by: Felipe Martin <812088+fmartingr@users.noreply.github.com>

* Update server/plugin/webhook.go

Co-authored-by: Felipe Martin <812088+fmartingr@users.noreply.github.com>

* Update server/plugin/webhook.go

Co-authored-by: Felipe Martin <812088+fmartingr@users.noreply.github.com>

* fix: correct spacing in template for discussion additons

* fix: update webhook consts for lint error

* update error for discussion

Co-authored-by: Raghav Aggarwal <raghav.aggarwal@brightscout.com>

* update error for webhook discussion

Co-authored-by: Raghav Aggarwal <raghav.aggarwal@brightscout.com>

* fix: update templates, remove duplicate check in webhook handler, and use const feature key

* fix: typo in const name for featureDiscussion

* fix typo

Co-authored-by: Doug Lauder <wiggin77@warpmail.net>

* fix: update spelling of const for feature check

* fix: const spelling for feature discussions

* fix: revert package-lock.json for e2e tests

---------

Co-authored-by: Felipe Martin <812088+fmartingr@users.noreply.github.com>
Co-authored-by: Raghav Aggarwal <raghav.aggarwal@brightscout.com>
Co-authored-by: Doug Lauder <wiggin77@warpmail.net>
  • Loading branch information
4 people authored Aug 28, 2024
1 parent c935551 commit 489c828
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 30 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ apply:
## Install go tools
install-go-tools:
@echo Installing go tools
$(GO) install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.51.1
$(GO) install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.59.1
$(GO) install gotest.tools/gotestsum@v1.7.0

## Runs eslint and golangci-lint
Expand Down
54 changes: 29 additions & 25 deletions server/plugin/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,37 +15,41 @@ import (
)

const (
featureIssueCreation = "issue_creations"
featureIssues = "issues"
featurePulls = "pulls"
featurePullsMerged = "pulls_merged"
featurePullsCreated = "pulls_created"
featurePushes = "pushes"
featureCreates = "creates"
featureDeletes = "deletes"
featureIssueComments = "issue_comments"
featurePullReviews = "pull_reviews"
featureStars = "stars"
featureReleases = "releases"
featureIssueCreation = "issue_creations"
featureIssues = "issues"
featurePulls = "pulls"
featurePullsMerged = "pulls_merged"
featurePullsCreated = "pulls_created"
featurePushes = "pushes"
featureCreates = "creates"
featureDeletes = "deletes"
featureIssueComments = "issue_comments"
featurePullReviews = "pull_reviews"
featureStars = "stars"
featureReleases = "releases"
featureDiscussions = "discussions"
featureDiscussionComments = "discussion_comments"
)

const (
PerPageValue = 50
)

var validFeatures = map[string]bool{
featureIssueCreation: true,
featureIssues: true,
featurePulls: true,
featurePullsMerged: true,
featurePullsCreated: true,
featurePushes: true,
featureCreates: true,
featureDeletes: true,
featureIssueComments: true,
featurePullReviews: true,
featureStars: true,
featureReleases: true,
featureIssueCreation: true,
featureIssues: true,
featurePulls: true,
featurePullsMerged: true,
featurePullsCreated: true,
featurePushes: true,
featureCreates: true,
featureDeletes: true,
featureIssueComments: true,
featurePullReviews: true,
featureStars: true,
featureReleases: true,
featureDiscussions: true,
featureDiscussionComments: true,
}

type Features string
Expand Down Expand Up @@ -897,7 +901,7 @@ func getAutocompleteData(config *Configuration) *model.AutocompleteData {

subscriptionsAdd := model.NewAutocompleteData("add", "[owner/repo] [features] [flags]", "Subscribe the current channel to receive notifications about opened pull requests and issues for an organization or repository. [features] and [flags] are optional arguments")
subscriptionsAdd.AddTextArgument("Owner/repo to subscribe to", "[owner/repo]", "")
subscriptionsAdd.AddNamedTextArgument("features", "Comma-delimited list of one or more of: issues, pulls, pulls_merged, pulls_created, pushes, creates, deletes, issue_creations, issue_comments, pull_reviews, releases, label:\"<labelname>\". Defaults to pulls,issues,creates,deletes", "", `/[^,-\s]+(,[^,-\s]+)*/`, false)
subscriptionsAdd.AddNamedTextArgument("features", "Comma-delimited list of one or more of: issues, pulls, pulls_merged, pulls_created, pushes, creates, deletes, issue_creations, issue_comments, pull_reviews, releases, discussions, discussion_comments, label:\"<labelname>\". Defaults to pulls,issues,creates,deletes", "", `/[^,-\s]+(,[^,-\s]+)*/`, false)

if config.GitHubOrg != "" {
subscriptionsAdd.AddNamedStaticListArgument("exclude-org-member", "Events triggered by organization members will not be delivered (the organization config should be set, otherwise this flag has not effect)", false, []model.AutocompleteListItem{
Expand Down
8 changes: 8 additions & 0 deletions server/plugin/subscriptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,14 @@ func (s *Subscription) Release() bool {
return strings.Contains(s.Features.String(), featureReleases)
}

func (s *Subscription) Discussions() bool {
return strings.Contains(s.Features.String(), featureDiscussions)
}

func (s *Subscription) DiscussionComments() bool {
return strings.Contains(s.Features.String(), featureDiscussionComments)
}

func (s *Subscription) Label() string {
if !strings.Contains(s.Features.String(), "label:") {
return ""
Expand Down
12 changes: 12 additions & 0 deletions server/plugin/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,8 @@ Assignees: {{range $i, $el := .Assignees -}} {{- if $i}}, {{end}}{{template "use
" * `pull_reviews` - includes pull request reviews\n" +
" * `releases` - includes release created and deleted\n" +
" * `label:<labelname>` - limit pull request and issue events to only this label. Must include `pulls` or `issues` in feature list when using a label.\n" +
" * `discussions` - includes new discussions\n" +
" * `discussion_comments` - includes new discussion comments\n" +
" * Defaults to `pulls,issues,creates,deletes`\n\n" +
" * `--exclude-org-member` - events triggered by organization members will not be delivered (the GitHub organization config should be set, otherwise this flag has not effect)\n" +
" * `--render-style` - notifications will be delivered in the specified style (for example, the body of a pull request will not be displayed). Supported values are `collapsed`, `skip-body` or `default` (same as omitting the flag).\n" +
Expand All @@ -440,6 +442,16 @@ It now has **{{.GetRepo.GetStargazersCount}}** stars.`))
{{- if eq .GetAction "created" }} created a release {{template "release" .GetRelease}}
{{- else if eq .GetAction "deleted" }} deleted a release {{template "release" .GetRelease}}
{{- end -}}`))

template.Must(masterTemplate.New("newDiscussion").Funcs(funcMap).Parse(`
{{template "user" .GetSender}} started a new discussion [#{{.GetDiscussion.GetNumber}} {{.GetDiscussion.GetTitle}}]({{.GetDiscussion.GetHTMLURL}}) on {{template "repo" .GetRepo}}
`))

template.Must(masterTemplate.New("newDiscussionComment").Funcs(funcMap).Parse(`
{{template "repo" .GetRepo}} New comment by {{template "user" .GetSender}} on discussion [#{{.GetDiscussion.GetNumber}} {{.GetDiscussion.GetTitle}}]({{.GetDiscussion.GetHTMLURL}}):
{{.GetComment.GetBody | trimBody | replaceAllGitHubUsernames}}
`))
}

func registerGitHubToUsernameMappingCallback(callback func(string) string) {
Expand Down
98 changes: 94 additions & 4 deletions server/plugin/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ const (
postPropGithubObjectID = "gh_object_id"
postPropGithubObjectType = "gh_object_type"

githubObjectTypeIssue = "issue"
githubObjectTypeIssueComment = "issue_comment"
githubObjectTypePRReviewComment = "pr_review_comment"
githubObjectTypeIssue = "issue"
githubObjectTypeIssueComment = "issue_comment"
githubObjectTypePRReviewComment = "pr_review_comment"
githubObjectTypeDiscussionComment = "discussion_comment"
)

// RenderConfig holds various configuration options to be used in a template
Expand Down Expand Up @@ -185,7 +186,6 @@ func (wb *WebhookBroker) Close() {

func (p *Plugin) handleWebhook(w http.ResponseWriter, r *http.Request) {
config := p.getConfiguration()

body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, "Bad request body", http.StatusBadRequest)
Expand Down Expand Up @@ -287,6 +287,16 @@ func (p *Plugin) handleWebhook(w http.ResponseWriter, r *http.Request) {
handler = func() {
p.postReleaseEvent(event)
}
case *github.DiscussionEvent:
repo = event.GetRepo()
handler = func() {
p.postDiscussionEvent(event)
}
case *github.DiscussionCommentEvent:
repo = event.GetRepo()
handler = func() {
p.postDiscussionCommentEvent(event)
}
}

if handler == nil {
Expand Down Expand Up @@ -1383,3 +1393,83 @@ func (p *Plugin) postReleaseEvent(event *github.ReleaseEvent) {
}
}
}

func (p *Plugin) postDiscussionEvent(event *github.DiscussionEvent) {
repo := event.GetRepo()

subs := p.GetSubscribedChannelsForRepository(repo)
if len(subs) == 0 {
return
}

newDiscussionMessage, err := renderTemplate("newDiscussion", event)
if err != nil {
p.client.Log.Warn("Failed to render template", "error", err.Error())
return
}

for _, sub := range subs {
if !sub.Discussions() {
continue
}

if p.excludeConfigOrgMember(event.GetSender(), sub) {
continue
}

post := p.makeBotPost(newDiscussionMessage, "custom_git_discussion")

repoName := strings.ToLower(repo.GetFullName())
discussionNumber := event.GetDiscussion().GetNumber()

post.AddProp(postPropGithubRepo, repoName)
post.AddProp(postPropGithubObjectID, discussionNumber)
post.AddProp(postPropGithubObjectType, "discussion")
post.ChannelId = sub.ChannelID
if err = p.client.Post.CreatePost(post); err != nil {
p.client.Log.Warn("Error creating discussion notification post", "Post", post, "Error", err.Error())
}
}
}

func (p *Plugin) postDiscussionCommentEvent(event *github.DiscussionCommentEvent) {
repo := event.GetRepo()

subs := p.GetSubscribedChannelsForRepository(repo)
if len(subs) == 0 {
return
}

if event.GetAction() != actionCreated {
return
}

newDiscussionCommentMessage, err := renderTemplate("newDiscussionComment", event)
if err != nil {
p.client.Log.Warn("Failed to render template", "error", err.Error())
return
}
for _, sub := range subs {
if !sub.DiscussionComments() {
continue
}

if p.excludeConfigOrgMember(event.GetSender(), sub) {
continue
}

post := p.makeBotPost(newDiscussionCommentMessage, "custom_git_dis_comment")

repoName := strings.ToLower(repo.GetFullName())
commentID := event.GetComment().GetID()

post.AddProp(postPropGithubRepo, repoName)
post.AddProp(postPropGithubObjectID, commentID)
post.AddProp(postPropGithubObjectType, githubObjectTypeDiscussionComment)

post.ChannelId = sub.ChannelID
if err = p.client.Post.CreatePost(post); err != nil {
p.client.Log.Warn("Error creating discussion comment post", "Post", post, "Error", err.Error())
}
}
}

0 comments on commit 489c828

Please sign in to comment.