From 215521dc4aa6b683bac8e3bb2b63d64e46d4776a Mon Sep 17 00:00:00 2001 From: Daniel Grier Date: Fri, 12 Apr 2019 23:58:12 +1000 Subject: [PATCH 01/17] Add todo list for issue 5964 - Also add MS Teams comparison Signed-off-by: Daniel Grier --- CHANGESREQUIRED.md | 20 +++++++++++++++++++ docs/content/doc/features/comparison.en-us.md | 1 + 2 files changed, 21 insertions(+) create mode 100644 CHANGESREQUIRED.md diff --git a/CHANGESREQUIRED.md b/CHANGESREQUIRED.md new file mode 100644 index 0000000000000..3c06fd08c9c92 --- /dev/null +++ b/CHANGESREQUIRED.md @@ -0,0 +1,20 @@ +# Changes Required - Issue 5964 + +https://github.com/go-gitea/gitea/issues/5964 + +- [ ] `models/webhook_msteams.go` +- [ ] `templates/repo/settings/webhook/discord.tmpl` +- [ ] `templates/org/settings/hook_new.tmpl` +- [ ] `templates/repo/settings/webhook/new.tmpl` +- [ ] `templates/admin/hook_new.tmpl` +- [ ] `templates/repo/settings/webhook/list.tmpl` +- [ ] `routers/repo/webhook.go` +- [ ] `models/webhook.go` +- [ ] `routers/routes/routes.go` +- [ ] `.drone.yml` ? +- [ ] `modules/setting/webhook.go` +- [ ] `modules/auth/repo_form.go` ? +- [X] `docs/content/doc/features/comparison.en-us.md` +- [ ] `CHANGELOG.md` +- [ ] `options/locale/*.ini` +- [ ] `templates/swagger/v1_json.tmpl` ? \ No newline at end of file diff --git a/docs/content/doc/features/comparison.en-us.md b/docs/content/doc/features/comparison.en-us.md index 6f732307a2234..617301986cfb2 100644 --- a/docs/content/doc/features/comparison.en-us.md +++ b/docs/content/doc/features/comparison.en-us.md @@ -122,4 +122,5 @@ _Symbols used in table:_ | Two factor authentication (2FA) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | | Mattermost/Slack integration | ✓ | ✓ | ⁄ | ✓ | ✓ | ⁄ | ✓ | | Discord integration | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ | +| Microsoft Teams integration | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ | | External CI/CD status display | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | From cb66a4a4ef3a09427f4d44db54bec76c980e6045 Mon Sep 17 00:00:00 2001 From: Daniel Grier Date: Sat, 13 Apr 2019 01:17:21 +1000 Subject: [PATCH 02/17] Add MSTEAMS webhook integration/structs Signed-off-by: Daniel Grier --- CHANGESREQUIRED.md | 6 +- models/webhook.go | 4 + models/webhook_msteams.go | 704 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 712 insertions(+), 2 deletions(-) create mode 100644 models/webhook_msteams.go diff --git a/CHANGESREQUIRED.md b/CHANGESREQUIRED.md index 3c06fd08c9c92..6c312346c695b 100644 --- a/CHANGESREQUIRED.md +++ b/CHANGESREQUIRED.md @@ -2,7 +2,7 @@ https://github.com/go-gitea/gitea/issues/5964 -- [ ] `models/webhook_msteams.go` +- [X] `models/webhook_msteams.go` - [ ] `templates/repo/settings/webhook/discord.tmpl` - [ ] `templates/org/settings/hook_new.tmpl` - [ ] `templates/repo/settings/webhook/new.tmpl` @@ -17,4 +17,6 @@ https://github.com/go-gitea/gitea/issues/5964 - [X] `docs/content/doc/features/comparison.en-us.md` - [ ] `CHANGELOG.md` - [ ] `options/locale/*.ini` -- [ ] `templates/swagger/v1_json.tmpl` ? \ No newline at end of file +- [ ] `templates/swagger/v1_json.tmpl` ? + +Use https://messagecardplayground.azurewebsites.net/ \ No newline at end of file diff --git a/models/webhook.go b/models/webhook.go index eb22e959754f8..3a7b145ace1ec 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -456,6 +456,7 @@ const ( GITEA DISCORD DINGTALK + MSTEAMS ) var hookTaskTypes = map[string]HookTaskType{ @@ -464,6 +465,7 @@ var hookTaskTypes = map[string]HookTaskType{ "slack": SLACK, "discord": DISCORD, "dingtalk": DINGTALK, + "teams": MSTEAMS, } // ToHookTaskType returns HookTaskType by given name. @@ -484,6 +486,8 @@ func (t HookTaskType) Name() string { return "discord" case DINGTALK: return "dingtalk" + case MSTEAMS: + return "teams" } return "" } diff --git a/models/webhook_msteams.go b/models/webhook_msteams.go new file mode 100644 index 0000000000000..3b6b3d45aa1d8 --- /dev/null +++ b/models/webhook_msteams.go @@ -0,0 +1,704 @@ +// Copyright 2017 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package models + +import ( + "encoding/json" + "errors" + "fmt" + "strings" + + "code.gitea.io/gitea/modules/git" + api "code.gitea.io/sdk/gitea" +) + +type ( + // MSTeamsFact for Fact Structure + MSTeamsFact struct { + Name string `json:"name"` + Value string `json:"value"` + } + + // MSTeamsSection is a MessageCard section + MSTeamsSection struct { + ActivityTitle string `json:"activityTitle"` + ActivitySubtitle string `json:"activitySubtitle"` + ActivityImage string `json:"activityImage"` + Facts []MSTeamsFact `json:"facts"` + Text string `json:"text"` + } + + // MSTeamsAction is an action (creates buttons, links etc) + MSTeamsAction struct { + Type string `json:"@type"` + Name string `json:"name"` + Targets []MSTeamsActionTarget `json:"targets,omitempty"` + } + + // MSTeamsActionTarget is the actual link to follow, etc + MSTeamsActionTarget struct { + Os string `json:"os"` + URI string `json:"uri"` + } + + // MSTeamsPayload is the parent object + MSTeamsPayload struct { + Type string `json:"@type"` + Context string `json:"@context"` + ThemeColor string `json:"themeColor"` + Title string `json:"title"` + Sections []MSTeamsSection `json:"sections"` + PotentialAction []MSTeamsAction `json:"potentialAction"` + } + + // MSTeamsMeta contains the MSTeams metadata + MSTeamsMeta struct { + Username string `json:"username"` + IconURL string `json:"icon_url"` + } +) + +// SetSecret sets the MSTeams secret +func (p *MSTeamsPayload) SetSecret(_ string) {} + +// JSONPayload Marshals the MSTeamsPayload to json +func (p *MSTeamsPayload) JSONPayload() ([]byte, error) { + data, err := json.MarshalIndent(p, "", " ") + if err != nil { + return []byte{}, err + } + return data, nil +} + +func getMSTeamsCreatePayload(p *api.CreatePayload, meta *MSTeamsMeta) (*MSTeamsPayload, error) { + // created tag/branch + refName := git.RefEndName(p.Ref) + title := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName) + + return &MSTeamsPayload{ + Type: "MessageCard", + Context: "https://schema.org/extensions", + ThemeColor: fmt.Sprintf("%x", successColor), + Title: title, + Sections: []MSTeamsSection{ + MSTeamsSection{ + ActivityTitle: p.Sender.FullName, + ActivitySubtitle: p.Sender.UserName, + ActivityImage: p.Sender.AvatarURL, + Facts: []MSTeamsFact{ + MSTeamsFact{ + Name: "Repository:", + Value: p.Repo.FullName, + }, + MSTeamsFact{ + Name: fmt.Sprintf("%s:", p.RefType), + Value: refName, + }, + }, + }, + }, + PotentialAction: []MSTeamsAction{ + MSTeamsAction{ + Type: "OpenUri", + Name: "View in Gitea", + Targets: []MSTeamsActionTarget{ + MSTeamsActionTarget{ + Os: "default", + URI: p.Repo.HTMLURL + "/src/" + refName, + }, + }, + }, + }, + }, nil +} + +func getMSTeamsDeletePayload(p *api.DeletePayload, meta *MSTeamsMeta) (*MSTeamsPayload, error) { + // deleted tag/branch + refName := git.RefEndName(p.Ref) + title := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName) + + return &MSTeamsPayload{ + Type: "MessageCard", + Context: "https://schema.org/extensions", + ThemeColor: fmt.Sprintf("%x", warnColor), + Title: title, + Sections: []MSTeamsSection{ + MSTeamsSection{ + ActivityTitle: p.Sender.FullName, + ActivitySubtitle: p.Sender.UserName, + ActivityImage: p.Sender.AvatarURL, + Facts: []MSTeamsFact{ + MSTeamsFact{ + Name: "Repository:", + Value: p.Repo.FullName, + }, + MSTeamsFact{ + Name: fmt.Sprintf("%s:", p.RefType), + Value: refName, + }, + }, + }, + }, + PotentialAction: []MSTeamsAction{ + MSTeamsAction{ + Type: "OpenUri", + Name: "View in Gitea", + Targets: []MSTeamsActionTarget{ + MSTeamsActionTarget{ + Os: "default", + URI: p.Repo.HTMLURL + "/src/" + refName, + }, + }, + }, + }, + }, nil +} + +func getMSTeamsForkPayload(p *api.ForkPayload, meta *MSTeamsMeta) (*MSTeamsPayload, error) { + // fork + title := fmt.Sprintf("%s is forked to %s", p.Forkee.FullName, p.Repo.FullName) + + return &MSTeamsPayload{ + Type: "MessageCard", + Context: "https://schema.org/extensions", + ThemeColor: fmt.Sprintf("%x", successColor), + Title: title, + Sections: []MSTeamsSection{ + MSTeamsSection{ + ActivityTitle: p.Sender.FullName, + ActivitySubtitle: p.Sender.UserName, + ActivityImage: p.Sender.AvatarURL, + Facts: []MSTeamsFact{ + MSTeamsFact{ + Name: "Forkee:", + Value: p.Forkee.FullName, + }, + MSTeamsFact{ + Name: "Repository:", + Value: p.Repo.FullName, + }, + }, + }, + }, + PotentialAction: []MSTeamsAction{ + MSTeamsAction{ + Type: "OpenUri", + Name: "View in Gitea", + Targets: []MSTeamsActionTarget{ + MSTeamsActionTarget{ + Os: "default", + URI: p.Repo.HTMLURL, + }, + }, + }, + }, + }, nil +} + +func getMSTeamsPushPayload(p *api.PushPayload, meta *MSTeamsMeta) (*MSTeamsPayload, error) { + var ( + branchName = git.RefEndName(p.Ref) + commitDesc string + ) + + var titleLink string + if len(p.Commits) == 1 { + commitDesc = "1 new commit" + titleLink = p.Commits[0].URL + } else { + commitDesc = fmt.Sprintf("%d new commits", len(p.Commits)) + titleLink = p.CompareURL + } + if titleLink == "" { + titleLink = p.Repo.HTMLURL + "/src/" + branchName + } + + title := fmt.Sprintf("[%s:%s] %s", p.Repo.FullName, branchName, commitDesc) + + var text string + // for each commit, generate attachment text + for i, commit := range p.Commits { + text += fmt.Sprintf("[%s](%s) %s - %s", commit.ID[:7], commit.URL, + strings.TrimRight(commit.Message, "\r\n"), commit.Author.Name) + // add linebreak to each commit but the last + if i < len(p.Commits)-1 { + text += "\n" + } + } + + return &MSTeamsPayload{ + Type: "MessageCard", + Context: "https://schema.org/extensions", + ThemeColor: fmt.Sprintf("%x", successColor), + Title: title, + Sections: []MSTeamsSection{ + MSTeamsSection{ + ActivityTitle: p.Sender.FullName, + ActivitySubtitle: p.Sender.UserName, + ActivityImage: p.Sender.AvatarURL, + Facts: []MSTeamsFact{ + MSTeamsFact{ + Name: "Repository:", + Value: p.Repo.FullName, + }, + MSTeamsFact{ + Name: "Commit count:", + Value: fmt.Sprintf("%d", len(p.Commits)), + }, + }, + }, + }, + PotentialAction: []MSTeamsAction{ + MSTeamsAction{ + Type: "OpenUri", + Name: "View in Gitea", + Targets: []MSTeamsActionTarget{ + MSTeamsActionTarget{ + Os: "default", + URI: titleLink, + }, + }, + }, + }, + }, nil +} + +func getMSTeamsIssuesPayload(p *api.IssuePayload, meta *MSTeamsMeta) (*MSTeamsPayload, error) { + var text, title string + var color int + url := fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Issue.Index) + switch p.Action { + case api.HookIssueOpened: + title = fmt.Sprintf("[%s] Issue opened: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title) + text = p.Issue.Body + color = warnColor + case api.HookIssueClosed: + title = fmt.Sprintf("[%s] Issue closed: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title) + color = failedColor + text = p.Issue.Body + case api.HookIssueReOpened: + title = fmt.Sprintf("[%s] Issue re-opened: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title) + text = p.Issue.Body + color = warnColor + case api.HookIssueEdited: + title = fmt.Sprintf("[%s] Issue edited: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title) + text = p.Issue.Body + color = warnColor + case api.HookIssueAssigned: + title = fmt.Sprintf("[%s] Issue assigned to %s: #%d %s", p.Repository.FullName, + p.Issue.Assignee.UserName, p.Index, p.Issue.Title) + text = p.Issue.Body + color = successColor + case api.HookIssueUnassigned: + title = fmt.Sprintf("[%s] Issue unassigned: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title) + text = p.Issue.Body + color = warnColor + case api.HookIssueLabelUpdated: + title = fmt.Sprintf("[%s] Issue labels updated: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title) + text = p.Issue.Body + color = warnColor + case api.HookIssueLabelCleared: + title = fmt.Sprintf("[%s] Issue labels cleared: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title) + text = p.Issue.Body + color = warnColor + case api.HookIssueSynchronized: + title = fmt.Sprintf("[%s] Issue synchronized: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title) + text = p.Issue.Body + color = warnColor + case api.HookIssueMilestoned: + title = fmt.Sprintf("[%s] Issue milestone: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title) + text = p.Issue.Body + color = warnColor + case api.HookIssueDemilestoned: + title = fmt.Sprintf("[%s] Issue clear milestone: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title) + text = p.Issue.Body + color = warnColor + } + + return &MSTeamsPayload{ + Type: "MessageCard", + Context: "https://schema.org/extensions", + ThemeColor: fmt.Sprintf("%x", color), + Title: title, + Sections: []MSTeamsSection{ + MSTeamsSection{ + ActivityTitle: p.Sender.FullName, + ActivitySubtitle: p.Sender.UserName, + ActivityImage: p.Sender.AvatarURL, + Text: text, + Facts: []MSTeamsFact{ + MSTeamsFact{ + Name: "Repository:", + Value: p.Repository.FullName, + }, + MSTeamsFact{ + Name: "Issue #:", + Value: fmt.Sprintf("%d", p.Issue.ID), + }, + }, + }, + }, + PotentialAction: []MSTeamsAction{ + MSTeamsAction{ + Type: "OpenUri", + Name: "View in Gitea", + Targets: []MSTeamsActionTarget{ + MSTeamsActionTarget{ + Os: "default", + URI: url, + }, + }, + }, + }, + }, nil +} + +func getMSTeamsIssueCommentPayload(p *api.IssueCommentPayload, MSTeams *MSTeamsMeta) (*MSTeamsPayload, error) { + title := fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title) + url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID)) + content := "" + var color int + switch p.Action { + case api.HookIssueCommentCreated: + title = "New comment: " + title + content = p.Comment.Body + color = successColor + case api.HookIssueCommentEdited: + title = "Comment edited: " + title + content = p.Comment.Body + color = warnColor + case api.HookIssueCommentDeleted: + title = "Comment deleted: " + title + url = fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Issue.Index) + content = p.Comment.Body + color = warnColor + } + + return &MSTeamsPayload{ + Type: "MessageCard", + Context: "https://schema.org/extensions", + ThemeColor: fmt.Sprintf("%x", color), + Title: title, + Sections: []MSTeamsSection{ + MSTeamsSection{ + ActivityTitle: p.Sender.FullName, + ActivitySubtitle: p.Sender.UserName, + ActivityImage: p.Sender.AvatarURL, + Text: content, + Facts: []MSTeamsFact{ + MSTeamsFact{ + Name: "Repository:", + Value: p.Repository.FullName, + }, + MSTeamsFact{ + Name: "Issue #:", + Value: fmt.Sprintf("%d", p.Issue.ID), + }, + }, + }, + }, + PotentialAction: []MSTeamsAction{ + MSTeamsAction{ + Type: "OpenUri", + Name: "View in Gitea", + Targets: []MSTeamsActionTarget{ + MSTeamsActionTarget{ + Os: "default", + URI: url, + }, + }, + }, + }, + }, nil +} + +func getMSTeamsPullRequestPayload(p *api.PullRequestPayload, meta *MSTeamsMeta) (*MSTeamsPayload, error) { + var text, title string + var color int + switch p.Action { + case api.HookIssueOpened: + title = fmt.Sprintf("[%s] Pull request opened: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title) + text = p.PullRequest.Body + color = warnColor + case api.HookIssueClosed: + if p.PullRequest.HasMerged { + title = fmt.Sprintf("[%s] Pull request merged: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title) + color = successColor + } else { + title = fmt.Sprintf("[%s] Pull request closed: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title) + color = failedColor + } + text = p.PullRequest.Body + case api.HookIssueReOpened: + title = fmt.Sprintf("[%s] Pull request re-opened: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title) + text = p.PullRequest.Body + color = warnColor + case api.HookIssueEdited: + title = fmt.Sprintf("[%s] Pull request edited: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title) + text = p.PullRequest.Body + color = warnColor + case api.HookIssueAssigned: + list := make([]string, len(p.PullRequest.Assignees)) + for i, user := range p.PullRequest.Assignees { + list[i] = user.UserName + } + title = fmt.Sprintf("[%s] Pull request assigned to %s: #%d by %s", p.Repository.FullName, + strings.Join(list, ", "), + p.Index, p.PullRequest.Title) + text = p.PullRequest.Body + color = successColor + case api.HookIssueUnassigned: + title = fmt.Sprintf("[%s] Pull request unassigned: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title) + text = p.PullRequest.Body + color = warnColor + case api.HookIssueLabelUpdated: + title = fmt.Sprintf("[%s] Pull request labels updated: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title) + text = p.PullRequest.Body + color = warnColor + case api.HookIssueLabelCleared: + title = fmt.Sprintf("[%s] Pull request labels cleared: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title) + text = p.PullRequest.Body + color = warnColor + case api.HookIssueSynchronized: + title = fmt.Sprintf("[%s] Pull request synchronized: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title) + text = p.PullRequest.Body + color = warnColor + case api.HookIssueMilestoned: + title = fmt.Sprintf("[%s] Pull request milestone: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title) + text = p.PullRequest.Body + color = warnColor + case api.HookIssueDemilestoned: + title = fmt.Sprintf("[%s] Pull request clear milestone: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title) + text = p.PullRequest.Body + color = warnColor + } + + return &MSTeamsPayload{ + Type: "MessageCard", + Context: "https://schema.org/extensions", + ThemeColor: fmt.Sprintf("%x", color), + Title: title, + Sections: []MSTeamsSection{ + MSTeamsSection{ + ActivityTitle: p.Sender.FullName, + ActivitySubtitle: p.Sender.UserName, + ActivityImage: p.Sender.AvatarURL, + Text: text, + Facts: []MSTeamsFact{ + MSTeamsFact{ + Name: "Repository:", + Value: p.Repository.FullName, + }, + MSTeamsFact{ + Name: "Pull request #:", + Value: fmt.Sprintf("%d", p.PullRequest.ID), + }, + }, + }, + }, + PotentialAction: []MSTeamsAction{ + MSTeamsAction{ + Type: "OpenUri", + Name: "View in Gitea", + Targets: []MSTeamsActionTarget{ + MSTeamsActionTarget{ + Os: "default", + URI: p.PullRequest.HTMLURL, + }, + }, + }, + }, + }, nil +} + +func getMSTeamsPullRequestApprovalPayload(p *api.PullRequestPayload, meta *MSTeamsMeta, event HookEventType) (*MSTeamsPayload, error) { + var text, title string + var color int + switch p.Action { + case api.HookIssueSynchronized: + action, err := parseHookPullRequestEventType(event) + if err != nil { + return nil, err + } + + title = fmt.Sprintf("[%s] Pull request review %s: #%d %s", p.Repository.FullName, action, p.Index, p.PullRequest.Title) + text = p.PullRequest.Body + color = warnColor + } + + return &MSTeamsPayload{ + Type: "MessageCard", + Context: "https://schema.org/extensions", + ThemeColor: fmt.Sprintf("%x", color), + Title: title, + Sections: []MSTeamsSection{ + MSTeamsSection{ + ActivityTitle: p.Sender.FullName, + ActivitySubtitle: p.Sender.UserName, + ActivityImage: p.Sender.AvatarURL, + Text: text, + Facts: []MSTeamsFact{ + MSTeamsFact{ + Name: "Repository:", + Value: p.Repository.FullName, + }, + MSTeamsFact{ + Name: "Pull request #:", + Value: fmt.Sprintf("%d", p.PullRequest.ID), + }, + }, + }, + }, + PotentialAction: []MSTeamsAction{ + MSTeamsAction{ + Type: "OpenUri", + Name: "View in Gitea", + Targets: []MSTeamsActionTarget{ + MSTeamsActionTarget{ + Os: "default", + URI: p.PullRequest.HTMLURL, + }, + }, + }, + }, + }, nil +} + +func getMSTeamsRepositoryPayload(p *api.RepositoryPayload, meta *MSTeamsMeta) (*MSTeamsPayload, error) { + var title, url string + var color int + switch p.Action { + case api.HookRepoCreated: + title = fmt.Sprintf("[%s] Repository created", p.Repository.FullName) + url = p.Repository.HTMLURL + color = successColor + case api.HookRepoDeleted: + title = fmt.Sprintf("[%s] Repository deleted", p.Repository.FullName) + color = warnColor + } + + return &MSTeamsPayload{ + Type: "MessageCard", + Context: "https://schema.org/extensions", + ThemeColor: fmt.Sprintf("%x", color), + Title: title, + Sections: []MSTeamsSection{ + MSTeamsSection{ + ActivityTitle: p.Sender.FullName, + ActivitySubtitle: p.Sender.UserName, + ActivityImage: p.Sender.AvatarURL, + Facts: []MSTeamsFact{ + MSTeamsFact{ + Name: "Repository:", + Value: p.Repository.FullName, + }, + }, + }, + }, + PotentialAction: []MSTeamsAction{ + MSTeamsAction{ + Type: "OpenUri", + Name: "View in Gitea", + Targets: []MSTeamsActionTarget{ + MSTeamsActionTarget{ + Os: "default", + URI: url, + }, + }, + }, + }, + }, nil +} + +func getMSTeamsReleasePayload(p *api.ReleasePayload, meta *MSTeamsMeta) (*MSTeamsPayload, error) { + var title, url string + var color int + switch p.Action { + case api.HookReleasePublished: + title = fmt.Sprintf("[%s] Release created", p.Release.TagName) + url = p.Release.URL + color = successColor + case api.HookReleaseUpdated: + title = fmt.Sprintf("[%s] Release updated", p.Release.TagName) + url = p.Release.URL + color = successColor + case api.HookReleaseDeleted: + title = fmt.Sprintf("[%s] Release deleted", p.Release.TagName) + url = p.Release.URL + color = successColor + } + + return &MSTeamsPayload{ + Type: "MessageCard", + Context: "https://schema.org/extensions", + ThemeColor: fmt.Sprintf("%x", color), + Title: title, + Sections: []MSTeamsSection{ + MSTeamsSection{ + ActivityTitle: p.Sender.FullName, + ActivitySubtitle: p.Sender.UserName, + ActivityImage: p.Sender.AvatarURL, + Text: p.Release.Note, + Facts: []MSTeamsFact{ + MSTeamsFact{ + Name: "Repository:", + Value: p.Repository.FullName, + }, + MSTeamsFact{ + Name: "Tag:", + Value: p.Release.TagName, + }, + }, + }, + }, + PotentialAction: []MSTeamsAction{ + MSTeamsAction{ + Type: "OpenUri", + Name: "View in Gitea", + Targets: []MSTeamsActionTarget{ + MSTeamsActionTarget{ + Os: "default", + URI: url, + }, + }, + }, + }, + }, nil +} + +// GetMSTeamsPayload converts a MSTeams webhook into a MSTeamsPayload +func GetMSTeamsPayload(p api.Payloader, event HookEventType, meta string) (*MSTeamsPayload, error) { + s := new(MSTeamsPayload) + + MSTeams := &MSTeamsMeta{} + if err := json.Unmarshal([]byte(meta), &MSTeams); err != nil { + return s, errors.New("GetMSTeamsPayload meta json:" + err.Error()) + } + + switch event { + case HookEventCreate: + return getMSTeamsCreatePayload(p.(*api.CreatePayload), MSTeams) + case HookEventDelete: + return getMSTeamsDeletePayload(p.(*api.DeletePayload), MSTeams) + case HookEventFork: + return getMSTeamsForkPayload(p.(*api.ForkPayload), MSTeams) + case HookEventIssues: + return getMSTeamsIssuesPayload(p.(*api.IssuePayload), MSTeams) + case HookEventIssueComment: + return getMSTeamsIssueCommentPayload(p.(*api.IssueCommentPayload), MSTeams) + case HookEventPush: + return getMSTeamsPushPayload(p.(*api.PushPayload), MSTeams) + case HookEventPullRequest: + return getMSTeamsPullRequestPayload(p.(*api.PullRequestPayload), MSTeams) + case HookEventPullRequestRejected, HookEventPullRequestApproved, HookEventPullRequestComment: + return getMSTeamsPullRequestApprovalPayload(p.(*api.PullRequestPayload), MSTeams, event) + case HookEventRepository: + return getMSTeamsRepositoryPayload(p.(*api.RepositoryPayload), MSTeams) + case HookEventRelease: + return getMSTeamsReleasePayload(p.(*api.ReleasePayload), MSTeams) + } + + return s, nil +} From 702ee4bdde71f83ad00ce625d07d4fa052bbffc1 Mon Sep 17 00:00:00 2001 From: Daniel Grier Date: Mon, 15 Apr 2019 22:08:54 +1000 Subject: [PATCH 03/17] Add Microsoft Teams working webhook functionality Signed-off-by: Daniel Grier --- CHANGESREQUIRED.md | 22 ------ models/webhook.go | 9 ++- models/webhook_msteams.go | 63 ++++++++------- modules/auth/repo_form.go | 11 +++ modules/setting/webhook.go | 2 +- options/locale/locale_en-US.ini | 1 + public/img/msteams.png | Bin 0 -> 6154 bytes routers/repo/webhook.go | 78 +++++++++++++++++++ routers/routes/routes.go | 4 + templates/admin/hook_new.tmpl | 3 + templates/org/settings/hook_new.tmpl | 3 + templates/repo/settings/webhook/list.tmpl | 3 + templates/repo/settings/webhook/msteams.tmpl | 11 +++ templates/repo/settings/webhook/new.tmpl | 3 + 14 files changed, 156 insertions(+), 57 deletions(-) delete mode 100644 CHANGESREQUIRED.md create mode 100644 public/img/msteams.png create mode 100644 templates/repo/settings/webhook/msteams.tmpl diff --git a/CHANGESREQUIRED.md b/CHANGESREQUIRED.md deleted file mode 100644 index 6c312346c695b..0000000000000 --- a/CHANGESREQUIRED.md +++ /dev/null @@ -1,22 +0,0 @@ -# Changes Required - Issue 5964 - -https://github.com/go-gitea/gitea/issues/5964 - -- [X] `models/webhook_msteams.go` -- [ ] `templates/repo/settings/webhook/discord.tmpl` -- [ ] `templates/org/settings/hook_new.tmpl` -- [ ] `templates/repo/settings/webhook/new.tmpl` -- [ ] `templates/admin/hook_new.tmpl` -- [ ] `templates/repo/settings/webhook/list.tmpl` -- [ ] `routers/repo/webhook.go` -- [ ] `models/webhook.go` -- [ ] `routers/routes/routes.go` -- [ ] `.drone.yml` ? -- [ ] `modules/setting/webhook.go` -- [ ] `modules/auth/repo_form.go` ? -- [X] `docs/content/doc/features/comparison.en-us.md` -- [ ] `CHANGELOG.md` -- [ ] `options/locale/*.ini` -- [ ] `templates/swagger/v1_json.tmpl` ? - -Use https://messagecardplayground.azurewebsites.net/ \ No newline at end of file diff --git a/models/webhook.go b/models/webhook.go index 3a7b145ace1ec..87847522253d1 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -465,7 +465,7 @@ var hookTaskTypes = map[string]HookTaskType{ "slack": SLACK, "discord": DISCORD, "dingtalk": DINGTALK, - "teams": MSTEAMS, + "msteams": MSTEAMS, } // ToHookTaskType returns HookTaskType by given name. @@ -487,7 +487,7 @@ func (t HookTaskType) Name() string { case DINGTALK: return "dingtalk" case MSTEAMS: - return "teams" + return "msteams" } return "" } @@ -661,6 +661,11 @@ func prepareWebhook(e Engine, w *Webhook, repo *Repository, event HookEventType, if err != nil { return fmt.Errorf("GetDingtalkPayload: %v", err) } + case MSTEAMS: + payloader, err = GetMSTeamsPayload(p, event, w.Meta) + if err != nil { + return fmt.Errorf("GetMSTeamsPayload: %v", err) + } default: p.SetSecret(w.Secret) payloader = p diff --git a/models/webhook_msteams.go b/models/webhook_msteams.go index 3b6b3d45aa1d8..35b025ec71e45 100644 --- a/models/webhook_msteams.go +++ b/models/webhook_msteams.go @@ -6,7 +6,6 @@ package models import ( "encoding/json" - "errors" "fmt" "strings" @@ -49,15 +48,10 @@ type ( Context string `json:"@context"` ThemeColor string `json:"themeColor"` Title string `json:"title"` + Summary string `json:"summary"` Sections []MSTeamsSection `json:"sections"` PotentialAction []MSTeamsAction `json:"potentialAction"` } - - // MSTeamsMeta contains the MSTeams metadata - MSTeamsMeta struct { - Username string `json:"username"` - IconURL string `json:"icon_url"` - } ) // SetSecret sets the MSTeams secret @@ -72,7 +66,7 @@ func (p *MSTeamsPayload) JSONPayload() ([]byte, error) { return data, nil } -func getMSTeamsCreatePayload(p *api.CreatePayload, meta *MSTeamsMeta) (*MSTeamsPayload, error) { +func getMSTeamsCreatePayload(p *api.CreatePayload) (*MSTeamsPayload, error) { // created tag/branch refName := git.RefEndName(p.Ref) title := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName) @@ -82,6 +76,7 @@ func getMSTeamsCreatePayload(p *api.CreatePayload, meta *MSTeamsMeta) (*MSTeamsP Context: "https://schema.org/extensions", ThemeColor: fmt.Sprintf("%x", successColor), Title: title, + Summary: title, Sections: []MSTeamsSection{ MSTeamsSection{ ActivityTitle: p.Sender.FullName, @@ -114,7 +109,7 @@ func getMSTeamsCreatePayload(p *api.CreatePayload, meta *MSTeamsMeta) (*MSTeamsP }, nil } -func getMSTeamsDeletePayload(p *api.DeletePayload, meta *MSTeamsMeta) (*MSTeamsPayload, error) { +func getMSTeamsDeletePayload(p *api.DeletePayload) (*MSTeamsPayload, error) { // deleted tag/branch refName := git.RefEndName(p.Ref) title := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName) @@ -124,6 +119,7 @@ func getMSTeamsDeletePayload(p *api.DeletePayload, meta *MSTeamsMeta) (*MSTeamsP Context: "https://schema.org/extensions", ThemeColor: fmt.Sprintf("%x", warnColor), Title: title, + Summary: title, Sections: []MSTeamsSection{ MSTeamsSection{ ActivityTitle: p.Sender.FullName, @@ -156,7 +152,7 @@ func getMSTeamsDeletePayload(p *api.DeletePayload, meta *MSTeamsMeta) (*MSTeamsP }, nil } -func getMSTeamsForkPayload(p *api.ForkPayload, meta *MSTeamsMeta) (*MSTeamsPayload, error) { +func getMSTeamsForkPayload(p *api.ForkPayload) (*MSTeamsPayload, error) { // fork title := fmt.Sprintf("%s is forked to %s", p.Forkee.FullName, p.Repo.FullName) @@ -165,6 +161,7 @@ func getMSTeamsForkPayload(p *api.ForkPayload, meta *MSTeamsMeta) (*MSTeamsPaylo Context: "https://schema.org/extensions", ThemeColor: fmt.Sprintf("%x", successColor), Title: title, + Summary: title, Sections: []MSTeamsSection{ MSTeamsSection{ ActivityTitle: p.Sender.FullName, @@ -197,7 +194,7 @@ func getMSTeamsForkPayload(p *api.ForkPayload, meta *MSTeamsMeta) (*MSTeamsPaylo }, nil } -func getMSTeamsPushPayload(p *api.PushPayload, meta *MSTeamsMeta) (*MSTeamsPayload, error) { +func getMSTeamsPushPayload(p *api.PushPayload) (*MSTeamsPayload, error) { var ( branchName = git.RefEndName(p.Ref) commitDesc string @@ -233,6 +230,7 @@ func getMSTeamsPushPayload(p *api.PushPayload, meta *MSTeamsMeta) (*MSTeamsPaylo Context: "https://schema.org/extensions", ThemeColor: fmt.Sprintf("%x", successColor), Title: title, + Summary: title, Sections: []MSTeamsSection{ MSTeamsSection{ ActivityTitle: p.Sender.FullName, @@ -265,7 +263,7 @@ func getMSTeamsPushPayload(p *api.PushPayload, meta *MSTeamsMeta) (*MSTeamsPaylo }, nil } -func getMSTeamsIssuesPayload(p *api.IssuePayload, meta *MSTeamsMeta) (*MSTeamsPayload, error) { +func getMSTeamsIssuesPayload(p *api.IssuePayload) (*MSTeamsPayload, error) { var text, title string var color int url := fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Issue.Index) @@ -322,6 +320,7 @@ func getMSTeamsIssuesPayload(p *api.IssuePayload, meta *MSTeamsMeta) (*MSTeamsPa Context: "https://schema.org/extensions", ThemeColor: fmt.Sprintf("%x", color), Title: title, + Summary: title, Sections: []MSTeamsSection{ MSTeamsSection{ ActivityTitle: p.Sender.FullName, @@ -355,7 +354,7 @@ func getMSTeamsIssuesPayload(p *api.IssuePayload, meta *MSTeamsMeta) (*MSTeamsPa }, nil } -func getMSTeamsIssueCommentPayload(p *api.IssueCommentPayload, MSTeams *MSTeamsMeta) (*MSTeamsPayload, error) { +func getMSTeamsIssueCommentPayload(p *api.IssueCommentPayload) (*MSTeamsPayload, error) { title := fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title) url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID)) content := "" @@ -381,6 +380,7 @@ func getMSTeamsIssueCommentPayload(p *api.IssueCommentPayload, MSTeams *MSTeamsM Context: "https://schema.org/extensions", ThemeColor: fmt.Sprintf("%x", color), Title: title, + Summary: title, Sections: []MSTeamsSection{ MSTeamsSection{ ActivityTitle: p.Sender.FullName, @@ -414,7 +414,7 @@ func getMSTeamsIssueCommentPayload(p *api.IssueCommentPayload, MSTeams *MSTeamsM }, nil } -func getMSTeamsPullRequestPayload(p *api.PullRequestPayload, meta *MSTeamsMeta) (*MSTeamsPayload, error) { +func getMSTeamsPullRequestPayload(p *api.PullRequestPayload) (*MSTeamsPayload, error) { var text, title string var color int switch p.Action { @@ -480,6 +480,7 @@ func getMSTeamsPullRequestPayload(p *api.PullRequestPayload, meta *MSTeamsMeta) Context: "https://schema.org/extensions", ThemeColor: fmt.Sprintf("%x", color), Title: title, + Summary: title, Sections: []MSTeamsSection{ MSTeamsSection{ ActivityTitle: p.Sender.FullName, @@ -513,7 +514,7 @@ func getMSTeamsPullRequestPayload(p *api.PullRequestPayload, meta *MSTeamsMeta) }, nil } -func getMSTeamsPullRequestApprovalPayload(p *api.PullRequestPayload, meta *MSTeamsMeta, event HookEventType) (*MSTeamsPayload, error) { +func getMSTeamsPullRequestApprovalPayload(p *api.PullRequestPayload, event HookEventType) (*MSTeamsPayload, error) { var text, title string var color int switch p.Action { @@ -533,6 +534,7 @@ func getMSTeamsPullRequestApprovalPayload(p *api.PullRequestPayload, meta *MSTea Context: "https://schema.org/extensions", ThemeColor: fmt.Sprintf("%x", color), Title: title, + Summary: title, Sections: []MSTeamsSection{ MSTeamsSection{ ActivityTitle: p.Sender.FullName, @@ -566,7 +568,7 @@ func getMSTeamsPullRequestApprovalPayload(p *api.PullRequestPayload, meta *MSTea }, nil } -func getMSTeamsRepositoryPayload(p *api.RepositoryPayload, meta *MSTeamsMeta) (*MSTeamsPayload, error) { +func getMSTeamsRepositoryPayload(p *api.RepositoryPayload) (*MSTeamsPayload, error) { var title, url string var color int switch p.Action { @@ -584,6 +586,7 @@ func getMSTeamsRepositoryPayload(p *api.RepositoryPayload, meta *MSTeamsMeta) (* Context: "https://schema.org/extensions", ThemeColor: fmt.Sprintf("%x", color), Title: title, + Summary: title, Sections: []MSTeamsSection{ MSTeamsSection{ ActivityTitle: p.Sender.FullName, @@ -612,7 +615,7 @@ func getMSTeamsRepositoryPayload(p *api.RepositoryPayload, meta *MSTeamsMeta) (* }, nil } -func getMSTeamsReleasePayload(p *api.ReleasePayload, meta *MSTeamsMeta) (*MSTeamsPayload, error) { +func getMSTeamsReleasePayload(p *api.ReleasePayload) (*MSTeamsPayload, error) { var title, url string var color int switch p.Action { @@ -635,6 +638,7 @@ func getMSTeamsReleasePayload(p *api.ReleasePayload, meta *MSTeamsMeta) (*MSTeam Context: "https://schema.org/extensions", ThemeColor: fmt.Sprintf("%x", color), Title: title, + Summary: title, Sections: []MSTeamsSection{ MSTeamsSection{ ActivityTitle: p.Sender.FullName, @@ -672,32 +676,27 @@ func getMSTeamsReleasePayload(p *api.ReleasePayload, meta *MSTeamsMeta) (*MSTeam func GetMSTeamsPayload(p api.Payloader, event HookEventType, meta string) (*MSTeamsPayload, error) { s := new(MSTeamsPayload) - MSTeams := &MSTeamsMeta{} - if err := json.Unmarshal([]byte(meta), &MSTeams); err != nil { - return s, errors.New("GetMSTeamsPayload meta json:" + err.Error()) - } - switch event { case HookEventCreate: - return getMSTeamsCreatePayload(p.(*api.CreatePayload), MSTeams) + return getMSTeamsCreatePayload(p.(*api.CreatePayload)) case HookEventDelete: - return getMSTeamsDeletePayload(p.(*api.DeletePayload), MSTeams) + return getMSTeamsDeletePayload(p.(*api.DeletePayload)) case HookEventFork: - return getMSTeamsForkPayload(p.(*api.ForkPayload), MSTeams) + return getMSTeamsForkPayload(p.(*api.ForkPayload)) case HookEventIssues: - return getMSTeamsIssuesPayload(p.(*api.IssuePayload), MSTeams) + return getMSTeamsIssuesPayload(p.(*api.IssuePayload)) case HookEventIssueComment: - return getMSTeamsIssueCommentPayload(p.(*api.IssueCommentPayload), MSTeams) + return getMSTeamsIssueCommentPayload(p.(*api.IssueCommentPayload)) case HookEventPush: - return getMSTeamsPushPayload(p.(*api.PushPayload), MSTeams) + return getMSTeamsPushPayload(p.(*api.PushPayload)) case HookEventPullRequest: - return getMSTeamsPullRequestPayload(p.(*api.PullRequestPayload), MSTeams) + return getMSTeamsPullRequestPayload(p.(*api.PullRequestPayload)) case HookEventPullRequestRejected, HookEventPullRequestApproved, HookEventPullRequestComment: - return getMSTeamsPullRequestApprovalPayload(p.(*api.PullRequestPayload), MSTeams, event) + return getMSTeamsPullRequestApprovalPayload(p.(*api.PullRequestPayload), event) case HookEventRepository: - return getMSTeamsRepositoryPayload(p.(*api.RepositoryPayload), MSTeams) + return getMSTeamsRepositoryPayload(p.(*api.RepositoryPayload)) case HookEventRelease: - return getMSTeamsReleasePayload(p.(*api.ReleasePayload), MSTeams) + return getMSTeamsReleasePayload(p.(*api.ReleasePayload)) } return s, nil diff --git a/modules/auth/repo_form.go b/modules/auth/repo_form.go index 0a97b08c71564..cc7c915aa015e 100644 --- a/modules/auth/repo_form.go +++ b/modules/auth/repo_form.go @@ -263,6 +263,17 @@ func (f *NewDingtalkHookForm) Validate(ctx *macaron.Context, errs binding.Errors return validate(errs, ctx.Data, f, ctx.Locale) } +// NewMSTeamsHookForm form for creating MS Teams hook +type NewMSTeamsHookForm struct { + PayloadURL string `binding:"Required;ValidUrl"` + WebhookForm +} + +// Validate validates the fields +func (f *NewMSTeamsHookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { + return validate(errs, ctx.Data, f, ctx.Locale) +} + // .___ // | | ______ ________ __ ____ // | |/ ___// ___/ | \_/ __ \ diff --git a/modules/setting/webhook.go b/modules/setting/webhook.go index 741963e545fd8..9e90173975dec 100644 --- a/modules/setting/webhook.go +++ b/modules/setting/webhook.go @@ -25,6 +25,6 @@ func newWebhookService() { Webhook.QueueLength = sec.Key("QUEUE_LENGTH").MustInt(1000) Webhook.DeliverTimeout = sec.Key("DELIVER_TIMEOUT").MustInt(5) Webhook.SkipTLSVerify = sec.Key("SKIP_TLS_VERIFY").MustBool() - Webhook.Types = []string{"gitea", "gogs", "slack", "discord", "dingtalk"} + Webhook.Types = []string{"gitea", "gogs", "slack", "discord", "dingtalk", "msteams"} Webhook.PagingNum = sec.Key("PAGING_NUM").MustInt(10) } diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index ce726ed562efa..a2ed6e654737e 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1197,6 +1197,7 @@ settings.slack_domain = Domain settings.slack_channel = Channel settings.add_discord_hook_desc = Integrate Discord into your repository. settings.add_dingtalk_hook_desc = Integrate Dingtalk into your repository. +settings.add_msteams_hook_desc = Integrate Microsoft Teams into your repository. settings.deploy_keys = Deploy Keys settings.add_deploy_key = Add Deploy Key settings.deploy_key_desc = Deploy keys have read-only pull access to the repository. diff --git a/public/img/msteams.png b/public/img/msteams.png new file mode 100644 index 0000000000000000000000000000000000000000..27313918e1ce7824a1971156d03b2f251da91634 GIT binary patch literal 6154 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 seP~N~o(qn2bHc6&|Nr^9deAk&oE^P {{else if eq .HookType "dingtalk"}} + {{else if eq .HookType "msteams"}} + {{end}} @@ -29,6 +31,7 @@ {{template "repo/settings/webhook/slack" .}} {{template "repo/settings/webhook/discord" .}} {{template "repo/settings/webhook/dingtalk" .}} + {{template "repo/settings/webhook/msteams" .}} {{template "repo/settings/webhook/history" .}} diff --git a/templates/org/settings/hook_new.tmpl b/templates/org/settings/hook_new.tmpl index 809009b66b7b4..6c5d83cd06414 100644 --- a/templates/org/settings/hook_new.tmpl +++ b/templates/org/settings/hook_new.tmpl @@ -19,6 +19,8 @@ {{else if eq .HookType "dingtalk"}} + {{else if eq .HookType "msteams"}} + {{end}} @@ -28,6 +30,7 @@ {{template "repo/settings/webhook/slack" .}} {{template "repo/settings/webhook/discord" .}} {{template "repo/settings/webhook/dingtalk" .}} + {{template "repo/settings/webhook/msteams" .}} {{template "repo/settings/webhook/history" .}} diff --git a/templates/repo/settings/webhook/list.tmpl b/templates/repo/settings/webhook/list.tmpl index d2985c367695d..48f62f0f0c130 100644 --- a/templates/repo/settings/webhook/list.tmpl +++ b/templates/repo/settings/webhook/list.tmpl @@ -20,6 +20,9 @@ Dingtalk + + Microsoft Teams + diff --git a/templates/repo/settings/webhook/msteams.tmpl b/templates/repo/settings/webhook/msteams.tmpl new file mode 100644 index 0000000000000..146cf533e8b10 --- /dev/null +++ b/templates/repo/settings/webhook/msteams.tmpl @@ -0,0 +1,11 @@ +{{if eq .HookType "msteams"}} +

{{.i18n.Tr "repo.settings.add_msteams_hook_desc" "https://teams.microsoft.com" | Str2html}}

+
+ {{.CsrfTokenHtml}} +
+ + +
+ {{template "repo/settings/webhook/settings" .}} +
+{{end}} diff --git a/templates/repo/settings/webhook/new.tmpl b/templates/repo/settings/webhook/new.tmpl index 1b3d114577a4e..174d4c26af917 100644 --- a/templates/repo/settings/webhook/new.tmpl +++ b/templates/repo/settings/webhook/new.tmpl @@ -17,6 +17,8 @@ {{else if eq .HookType "dingtalk"}} + {{else if eq .HookType "msteams"}} + {{end}} @@ -26,6 +28,7 @@ {{template "repo/settings/webhook/slack" .}} {{template "repo/settings/webhook/discord" .}} {{template "repo/settings/webhook/dingtalk" .}} + {{template "repo/settings/webhook/msteams" .}} {{template "repo/settings/webhook/history" .}} From fd430f503ceaecea4004129e660ebbb9b278f2da Mon Sep 17 00:00:00 2001 From: Daniel Grier Date: Mon, 15 Apr 2019 22:16:51 +1000 Subject: [PATCH 04/17] Remove unnecessary code for MSTeams metadata Signed-off-by: Daniel Grier --- routers/repo/webhook.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/routers/repo/webhook.go b/routers/repo/webhook.go index 896dc45db65e5..4ad22f6f15e45 100644 --- a/routers/repo/webhook.go +++ b/routers/repo/webhook.go @@ -123,12 +123,6 @@ func WebhooksNew(ctx *context.Context) { "IconURL": setting.AppURL + "img/favicon.png", } } - if hookType == "msteams" { - ctx.Data["MSTeamsHook"] = map[string]interface{}{ - "Username": "Gitea", - "IconURL": setting.AppURL + "img/favicon.png", - } - } ctx.Data["BaseLink"] = orCtx.Link ctx.HTML(200, orCtx.NewTemplate) From 559a50a58b38b96bf6cc4cd831d04325c56884a2 Mon Sep 17 00:00:00 2001 From: Daniel Grier Date: Mon, 15 Apr 2019 22:37:30 +1000 Subject: [PATCH 05/17] Fix failed fmt-check on models/webhook_msteams.go Signed-off-by: Daniel Grier --- models/webhook_msteams.go | 98 +++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/models/webhook_msteams.go b/models/webhook_msteams.go index 35b025ec71e45..9b23cfaa7949f 100644 --- a/models/webhook_msteams.go +++ b/models/webhook_msteams.go @@ -78,16 +78,16 @@ func getMSTeamsCreatePayload(p *api.CreatePayload) (*MSTeamsPayload, error) { Title: title, Summary: title, Sections: []MSTeamsSection{ - MSTeamsSection{ + { ActivityTitle: p.Sender.FullName, ActivitySubtitle: p.Sender.UserName, ActivityImage: p.Sender.AvatarURL, Facts: []MSTeamsFact{ - MSTeamsFact{ + { Name: "Repository:", Value: p.Repo.FullName, }, - MSTeamsFact{ + { Name: fmt.Sprintf("%s:", p.RefType), Value: refName, }, @@ -95,11 +95,11 @@ func getMSTeamsCreatePayload(p *api.CreatePayload) (*MSTeamsPayload, error) { }, }, PotentialAction: []MSTeamsAction{ - MSTeamsAction{ + { Type: "OpenUri", Name: "View in Gitea", Targets: []MSTeamsActionTarget{ - MSTeamsActionTarget{ + { Os: "default", URI: p.Repo.HTMLURL + "/src/" + refName, }, @@ -121,16 +121,16 @@ func getMSTeamsDeletePayload(p *api.DeletePayload) (*MSTeamsPayload, error) { Title: title, Summary: title, Sections: []MSTeamsSection{ - MSTeamsSection{ + { ActivityTitle: p.Sender.FullName, ActivitySubtitle: p.Sender.UserName, ActivityImage: p.Sender.AvatarURL, Facts: []MSTeamsFact{ - MSTeamsFact{ + { Name: "Repository:", Value: p.Repo.FullName, }, - MSTeamsFact{ + { Name: fmt.Sprintf("%s:", p.RefType), Value: refName, }, @@ -138,11 +138,11 @@ func getMSTeamsDeletePayload(p *api.DeletePayload) (*MSTeamsPayload, error) { }, }, PotentialAction: []MSTeamsAction{ - MSTeamsAction{ + { Type: "OpenUri", Name: "View in Gitea", Targets: []MSTeamsActionTarget{ - MSTeamsActionTarget{ + { Os: "default", URI: p.Repo.HTMLURL + "/src/" + refName, }, @@ -163,16 +163,16 @@ func getMSTeamsForkPayload(p *api.ForkPayload) (*MSTeamsPayload, error) { Title: title, Summary: title, Sections: []MSTeamsSection{ - MSTeamsSection{ + { ActivityTitle: p.Sender.FullName, ActivitySubtitle: p.Sender.UserName, ActivityImage: p.Sender.AvatarURL, Facts: []MSTeamsFact{ - MSTeamsFact{ + { Name: "Forkee:", Value: p.Forkee.FullName, }, - MSTeamsFact{ + { Name: "Repository:", Value: p.Repo.FullName, }, @@ -180,11 +180,11 @@ func getMSTeamsForkPayload(p *api.ForkPayload) (*MSTeamsPayload, error) { }, }, PotentialAction: []MSTeamsAction{ - MSTeamsAction{ + { Type: "OpenUri", Name: "View in Gitea", Targets: []MSTeamsActionTarget{ - MSTeamsActionTarget{ + { Os: "default", URI: p.Repo.HTMLURL, }, @@ -232,16 +232,16 @@ func getMSTeamsPushPayload(p *api.PushPayload) (*MSTeamsPayload, error) { Title: title, Summary: title, Sections: []MSTeamsSection{ - MSTeamsSection{ + { ActivityTitle: p.Sender.FullName, ActivitySubtitle: p.Sender.UserName, ActivityImage: p.Sender.AvatarURL, Facts: []MSTeamsFact{ - MSTeamsFact{ + { Name: "Repository:", Value: p.Repo.FullName, }, - MSTeamsFact{ + { Name: "Commit count:", Value: fmt.Sprintf("%d", len(p.Commits)), }, @@ -249,11 +249,11 @@ func getMSTeamsPushPayload(p *api.PushPayload) (*MSTeamsPayload, error) { }, }, PotentialAction: []MSTeamsAction{ - MSTeamsAction{ + { Type: "OpenUri", Name: "View in Gitea", Targets: []MSTeamsActionTarget{ - MSTeamsActionTarget{ + { Os: "default", URI: titleLink, }, @@ -322,17 +322,17 @@ func getMSTeamsIssuesPayload(p *api.IssuePayload) (*MSTeamsPayload, error) { Title: title, Summary: title, Sections: []MSTeamsSection{ - MSTeamsSection{ + { ActivityTitle: p.Sender.FullName, ActivitySubtitle: p.Sender.UserName, ActivityImage: p.Sender.AvatarURL, Text: text, Facts: []MSTeamsFact{ - MSTeamsFact{ + { Name: "Repository:", Value: p.Repository.FullName, }, - MSTeamsFact{ + { Name: "Issue #:", Value: fmt.Sprintf("%d", p.Issue.ID), }, @@ -340,11 +340,11 @@ func getMSTeamsIssuesPayload(p *api.IssuePayload) (*MSTeamsPayload, error) { }, }, PotentialAction: []MSTeamsAction{ - MSTeamsAction{ + { Type: "OpenUri", Name: "View in Gitea", Targets: []MSTeamsActionTarget{ - MSTeamsActionTarget{ + { Os: "default", URI: url, }, @@ -382,17 +382,17 @@ func getMSTeamsIssueCommentPayload(p *api.IssueCommentPayload) (*MSTeamsPayload, Title: title, Summary: title, Sections: []MSTeamsSection{ - MSTeamsSection{ + { ActivityTitle: p.Sender.FullName, ActivitySubtitle: p.Sender.UserName, ActivityImage: p.Sender.AvatarURL, Text: content, Facts: []MSTeamsFact{ - MSTeamsFact{ + { Name: "Repository:", Value: p.Repository.FullName, }, - MSTeamsFact{ + { Name: "Issue #:", Value: fmt.Sprintf("%d", p.Issue.ID), }, @@ -400,11 +400,11 @@ func getMSTeamsIssueCommentPayload(p *api.IssueCommentPayload) (*MSTeamsPayload, }, }, PotentialAction: []MSTeamsAction{ - MSTeamsAction{ + { Type: "OpenUri", Name: "View in Gitea", Targets: []MSTeamsActionTarget{ - MSTeamsActionTarget{ + { Os: "default", URI: url, }, @@ -482,17 +482,17 @@ func getMSTeamsPullRequestPayload(p *api.PullRequestPayload) (*MSTeamsPayload, e Title: title, Summary: title, Sections: []MSTeamsSection{ - MSTeamsSection{ + { ActivityTitle: p.Sender.FullName, ActivitySubtitle: p.Sender.UserName, ActivityImage: p.Sender.AvatarURL, Text: text, Facts: []MSTeamsFact{ - MSTeamsFact{ + { Name: "Repository:", Value: p.Repository.FullName, }, - MSTeamsFact{ + { Name: "Pull request #:", Value: fmt.Sprintf("%d", p.PullRequest.ID), }, @@ -500,11 +500,11 @@ func getMSTeamsPullRequestPayload(p *api.PullRequestPayload) (*MSTeamsPayload, e }, }, PotentialAction: []MSTeamsAction{ - MSTeamsAction{ + { Type: "OpenUri", Name: "View in Gitea", Targets: []MSTeamsActionTarget{ - MSTeamsActionTarget{ + { Os: "default", URI: p.PullRequest.HTMLURL, }, @@ -536,17 +536,17 @@ func getMSTeamsPullRequestApprovalPayload(p *api.PullRequestPayload, event HookE Title: title, Summary: title, Sections: []MSTeamsSection{ - MSTeamsSection{ + { ActivityTitle: p.Sender.FullName, ActivitySubtitle: p.Sender.UserName, ActivityImage: p.Sender.AvatarURL, Text: text, Facts: []MSTeamsFact{ - MSTeamsFact{ + { Name: "Repository:", Value: p.Repository.FullName, }, - MSTeamsFact{ + { Name: "Pull request #:", Value: fmt.Sprintf("%d", p.PullRequest.ID), }, @@ -554,11 +554,11 @@ func getMSTeamsPullRequestApprovalPayload(p *api.PullRequestPayload, event HookE }, }, PotentialAction: []MSTeamsAction{ - MSTeamsAction{ + { Type: "OpenUri", Name: "View in Gitea", Targets: []MSTeamsActionTarget{ - MSTeamsActionTarget{ + { Os: "default", URI: p.PullRequest.HTMLURL, }, @@ -588,12 +588,12 @@ func getMSTeamsRepositoryPayload(p *api.RepositoryPayload) (*MSTeamsPayload, err Title: title, Summary: title, Sections: []MSTeamsSection{ - MSTeamsSection{ + { ActivityTitle: p.Sender.FullName, ActivitySubtitle: p.Sender.UserName, ActivityImage: p.Sender.AvatarURL, Facts: []MSTeamsFact{ - MSTeamsFact{ + { Name: "Repository:", Value: p.Repository.FullName, }, @@ -601,11 +601,11 @@ func getMSTeamsRepositoryPayload(p *api.RepositoryPayload) (*MSTeamsPayload, err }, }, PotentialAction: []MSTeamsAction{ - MSTeamsAction{ + { Type: "OpenUri", Name: "View in Gitea", Targets: []MSTeamsActionTarget{ - MSTeamsActionTarget{ + { Os: "default", URI: url, }, @@ -640,17 +640,17 @@ func getMSTeamsReleasePayload(p *api.ReleasePayload) (*MSTeamsPayload, error) { Title: title, Summary: title, Sections: []MSTeamsSection{ - MSTeamsSection{ + { ActivityTitle: p.Sender.FullName, ActivitySubtitle: p.Sender.UserName, ActivityImage: p.Sender.AvatarURL, Text: p.Release.Note, Facts: []MSTeamsFact{ - MSTeamsFact{ + { Name: "Repository:", Value: p.Repository.FullName, }, - MSTeamsFact{ + { Name: "Tag:", Value: p.Release.TagName, }, @@ -658,11 +658,11 @@ func getMSTeamsReleasePayload(p *api.ReleasePayload) (*MSTeamsPayload, error) { }, }, PotentialAction: []MSTeamsAction{ - MSTeamsAction{ + { Type: "OpenUri", Name: "View in Gitea", Targets: []MSTeamsActionTarget{ - MSTeamsActionTarget{ + { Os: "default", URI: url, }, From 15b22b02da578d547b87c82b9139b4f8733ec76d Mon Sep 17 00:00:00 2001 From: Daniel Grier Date: Mon, 15 Apr 2019 22:39:42 +1000 Subject: [PATCH 06/17] Update copyright to 2019 Signed-off-by: Daniel Grier --- models/webhook_msteams.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/webhook_msteams.go b/models/webhook_msteams.go index 9b23cfaa7949f..b0fc4e7a2e516 100644 --- a/models/webhook_msteams.go +++ b/models/webhook_msteams.go @@ -1,4 +1,4 @@ -// Copyright 2017 The Gitea Authors. All rights reserved. +// Copyright 2019 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. From f2332472cd004ab1395b424e3c40860561269d24 Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Thu, 18 Apr 2019 22:58:13 -0400 Subject: [PATCH 07/17] make fmt --- models/webhook.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/models/webhook.go b/models/webhook.go index fadf8258e8c2a..9c27a1da21a42 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -466,7 +466,7 @@ const ( DISCORD DINGTALK TELEGRAM - MSTEAMS + MSTEAMS ) var hookTaskTypes = map[string]HookTaskType{ @@ -476,7 +476,7 @@ var hookTaskTypes = map[string]HookTaskType{ "discord": DISCORD, "dingtalk": DINGTALK, "telegram": TELEGRAM, - "msteams": MSTEAMS, + "msteams": MSTEAMS, } // ToHookTaskType returns HookTaskType by given name. @@ -499,7 +499,7 @@ func (t HookTaskType) Name() string { return "dingtalk" case TELEGRAM: return "telegram" - case MSTEAMS: + case MSTEAMS: return "msteams" } return "" @@ -674,7 +674,7 @@ func prepareWebhook(e Engine, w *Webhook, repo *Repository, event HookEventType, if err != nil { return fmt.Errorf("GetDingtalkPayload: %v", err) } - case TELEGRAM: + case TELEGRAM: payloader, err = GetTelegramPayload(p, event, w.Meta) if err != nil { return fmt.Errorf("GetTelegramPayload: %v", err) From 0f9c445d982d849c619eb80d6c1367d71d6f2867 Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Thu, 18 Apr 2019 22:58:50 -0400 Subject: [PATCH 08/17] fix syntax --- models/webhook.go | 1 + 1 file changed, 1 insertion(+) diff --git a/models/webhook.go b/models/webhook.go index 9c27a1da21a42..9be89241a4c82 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -678,6 +678,7 @@ func prepareWebhook(e Engine, w *Webhook, repo *Repository, event HookEventType, payloader, err = GetTelegramPayload(p, event, w.Meta) if err != nil { return fmt.Errorf("GetTelegramPayload: %v", err) + } case MSTEAMS: payloader, err = GetMSTeamsPayload(p, event, w.Meta) if err != nil { From 42861831cc70c9a8a922b073172610715db3489e Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Thu, 18 Apr 2019 22:59:47 -0400 Subject: [PATCH 09/17] fix sytax --- modules/auth/repo_form.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auth/repo_form.go b/modules/auth/repo_form.go index 45b8ed0a41aa0..fd6891288d998 100644 --- a/modules/auth/repo_form.go +++ b/modules/auth/repo_form.go @@ -278,7 +278,7 @@ func (f *NewTelegramHookForm) Validate(ctx *macaron.Context, errs binding.Errors // NewMSTeamsHookForm form for creating MS Teams hook type NewMSTeamsHookForm struct { PayloadURL string `binding:"Required;ValidUrl"` - WebhookForm + WebhookForm } // Validate validates the fields From 021601f4d309be0af8c389ac279f85e7f1c87cf1 Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Thu, 18 Apr 2019 23:01:07 -0400 Subject: [PATCH 10/17] make fmt --- routers/repo/webhook.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/routers/repo/webhook.go b/routers/repo/webhook.go index fbdb0688b105f..5f070febdb67d 100644 --- a/routers/repo/webhook.go +++ b/routers/repo/webhook.go @@ -382,7 +382,7 @@ func TelegramHooksNewPost(ctx *context.Context, form auth.NewTelegramHookForm) { // MSTeamsHooksNewPost response for creating MS Teams hook func MSTeamsHooksNewPost(ctx *context.Context, form auth.NewMSTeamsHookForm) { - ctx.Data["Title"] = ctx.Tr("repo.settings") + ctx.Data["Title"] = ctx.Tr("repo.settings") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksNew"] = true ctx.Data["Webhook"] = models.Webhook{HookEvent: &models.HookEvent{}} @@ -407,7 +407,7 @@ func MSTeamsHooksNewPost(ctx *context.Context, form auth.NewMSTeamsHookForm) { return } - w := &models.Webhook{ + w := &models.Webhook{ RepoID: orCtx.RepoID, URL: form.PayloadURL, ContentType: models.ContentTypeJSON, @@ -415,7 +415,7 @@ func MSTeamsHooksNewPost(ctx *context.Context, form auth.NewMSTeamsHookForm) { IsActive: form.Active, HookTaskType: models.MSTEAMS, Meta: "", - OrgID: orCtx.OrgID, + OrgID: orCtx.OrgID, } if err := w.UpdateEvent(); err != nil { ctx.ServerError("UpdateEvent", err) @@ -788,7 +788,7 @@ func TelegramHooksEditPost(ctx *context.Context, form auth.NewTelegramHookForm) // MSTeamsHooksEditPost response for editing MS Teams hook func MSTeamsHooksEditPost(ctx *context.Context, form auth.NewMSTeamsHookForm) { - ctx.Data["Title"] = ctx.Tr("repo.settings") + ctx.Data["Title"] = ctx.Tr("repo.settings") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksEdit"] = true @@ -804,7 +804,7 @@ func MSTeamsHooksEditPost(ctx *context.Context, form auth.NewMSTeamsHookForm) { } w.URL = form.PayloadURL - w.HookEvent = ParseHookEvent(form.WebhookForm) + w.HookEvent = ParseHookEvent(form.WebhookForm) w.IsActive = form.Active if err := w.UpdateEvent(); err != nil { ctx.ServerError("UpdateEvent", err) From 03c5ea3e35d1bb0e326690abaeb8f28eb4835c62 Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Thu, 18 Apr 2019 23:01:45 -0400 Subject: [PATCH 11/17] make fmt --- templates/org/settings/hook_new.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/org/settings/hook_new.tmpl b/templates/org/settings/hook_new.tmpl index e0ed0604a45bf..5db91011d8917 100644 --- a/templates/org/settings/hook_new.tmpl +++ b/templates/org/settings/hook_new.tmpl @@ -33,7 +33,7 @@ {{template "repo/settings/webhook/discord" .}} {{template "repo/settings/webhook/dingtalk" .}} {{template "repo/settings/webhook/telegram" .}} - {{template "repo/settings/webhook/msteams" .}} + {{template "repo/settings/webhook/msteams" .}} {{template "repo/settings/webhook/history" .}} From bd75ccf26febfbcefc54efd55ac9bd780931b931 Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Thu, 18 Apr 2019 23:02:16 -0400 Subject: [PATCH 12/17] make fmt --- templates/repo/settings/webhook/list.tmpl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/repo/settings/webhook/list.tmpl b/templates/repo/settings/webhook/list.tmpl index 877dc57631f26..8fdae45b1b1ba 100644 --- a/templates/repo/settings/webhook/list.tmpl +++ b/templates/repo/settings/webhook/list.tmpl @@ -22,7 +22,8 @@ Telegram - + + Microsoft Teams From 5dae071c650869aad6166a27be86e6e09d027909 Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Thu, 18 Apr 2019 23:02:31 -0400 Subject: [PATCH 13/17] make fmt --- templates/repo/settings/webhook/new.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/repo/settings/webhook/new.tmpl b/templates/repo/settings/webhook/new.tmpl index 80325e5968051..358827c0f8222 100644 --- a/templates/repo/settings/webhook/new.tmpl +++ b/templates/repo/settings/webhook/new.tmpl @@ -17,7 +17,7 @@ {{else if eq .HookType "dingtalk"}} - {{else if eq .HookType "telegram"}} + {{else if eq .HookType "telegram"}} {{else if eq .HookType "msteams"}} @@ -31,7 +31,7 @@ {{template "repo/settings/webhook/discord" .}} {{template "repo/settings/webhook/dingtalk" .}} {{template "repo/settings/webhook/telegram" .}} - {{template "repo/settings/webhook/msteams" .}} + {{template "repo/settings/webhook/msteams" .}} {{template "repo/settings/webhook/history" .}} From 34980575b89c5f4dee1657b3eee9f22ecfa3b60f Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Thu, 18 Apr 2019 23:03:21 -0400 Subject: [PATCH 14/17] make fmt --- routers/routes/routes.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/routers/routes/routes.go b/routers/routes/routes.go index fe1a2da91f818..db42eecf8c7c6 100644 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -616,8 +616,8 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost) m.Post("/discord/new", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksNewPost) m.Post("/dingtalk/new", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksNewPost) - m.Post("/telegram/new", bindIgnErr(auth.NewTelegramHookForm{}), repo.TelegramHooksNewPost) - m.Post("/msteams/new", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksNewPost) + m.Post("/telegram/new", bindIgnErr(auth.NewTelegramHookForm{}), repo.TelegramHooksNewPost) + m.Post("/msteams/new", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksNewPost) m.Get("/:id", repo.WebHooksEdit) m.Post("/:id/test", repo.TestWebhook) m.Post("/gitea/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost) @@ -625,8 +625,8 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost) m.Post("/discord/:id", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksEditPost) m.Post("/dingtalk/:id", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksEditPost) - m.Post("/telegram/:id", bindIgnErr(auth.NewTelegramHookForm{}), repo.TelegramHooksEditPost) - m.Post("/msteams/:id", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost) + m.Post("/telegram/:id", bindIgnErr(auth.NewTelegramHookForm{}), repo.TelegramHooksEditPost) + m.Post("/msteams/:id", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost) m.Group("/git", func() { m.Get("", repo.GitHooks) From 9e75a3a94f8d06e2a4c57e75ca259112b42f8a9a Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Thu, 18 Apr 2019 23:05:22 -0400 Subject: [PATCH 15/17] Update webhook.go --- routers/repo/webhook.go | 1 + 1 file changed, 1 insertion(+) diff --git a/routers/repo/webhook.go b/routers/repo/webhook.go index 5f070febdb67d..730408fa104c3 100644 --- a/routers/repo/webhook.go +++ b/routers/repo/webhook.go @@ -427,6 +427,7 @@ func MSTeamsHooksNewPost(ctx *context.Context, form auth.NewMSTeamsHookForm) { ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success")) ctx.Redirect(orCtx.Link) +} // SlackHooksNewPost response for creating slack hook func SlackHooksNewPost(ctx *context.Context, form auth.NewSlackHookForm) { From 5941acac8ff3edee7cdcde3c9ef2e2bf5e84d1a1 Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Thu, 18 Apr 2019 23:09:01 -0400 Subject: [PATCH 16/17] Update webhook.go --- routers/repo/webhook.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/routers/repo/webhook.go b/routers/repo/webhook.go index 730408fa104c3..2423c7402da3a 100644 --- a/routers/repo/webhook.go +++ b/routers/repo/webhook.go @@ -398,15 +398,6 @@ func MSTeamsHooksNewPost(ctx *context.Context, form auth.NewMSTeamsHookForm) { return } - meta, err := json.Marshal(&models.TelegramMeta{ - BotToken: form.BotToken, - ChatID: form.ChatID, - }) - if err != nil { - ctx.ServerError("Marshal", err) - return - } - w := &models.Webhook{ RepoID: orCtx.RepoID, URL: form.PayloadURL, From cc06e155b3264560789a82ccf3e81865ede65290 Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Thu, 18 Apr 2019 23:12:07 -0400 Subject: [PATCH 17/17] make fmt --- routers/repo/webhook.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/routers/repo/webhook.go b/routers/repo/webhook.go index 2423c7402da3a..6cf636f2470ac 100644 --- a/routers/repo/webhook.go +++ b/routers/repo/webhook.go @@ -778,7 +778,7 @@ func TelegramHooksEditPost(ctx *context.Context, form auth.NewTelegramHookForm) ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID)) } - // MSTeamsHooksEditPost response for editing MS Teams hook +// MSTeamsHooksEditPost response for editing MS Teams hook func MSTeamsHooksEditPost(ctx *context.Context, form auth.NewMSTeamsHookForm) { ctx.Data["Title"] = ctx.Tr("repo.settings") ctx.Data["PageIsSettingsHooks"] = true @@ -809,7 +809,7 @@ func MSTeamsHooksEditPost(ctx *context.Context, form auth.NewMSTeamsHookForm) { ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success")) ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID)) } - + // TestWebhook test if web hook is work fine func TestWebhook(ctx *context.Context) { hookID := ctx.ParamsInt64(":id")