diff --git a/models/webhook.go b/models/webhook.go
index a764455f5f39a..a7daae9c56939 100644
--- a/models/webhook.go
+++ b/models/webhook.go
@@ -141,6 +141,16 @@ func (w *Webhook) GetDiscordHook() *DiscordMeta {
return s
}
+// GetWorkwechatHook returns work wechat metadata
+func (w *Webhook) GetWorkwechatHook() *WorkwechatMeta {
+ s := &WorkwechatMeta{}
+
+ if err := json.Unmarshal([]byte(w.Meta), s); err != nil {
+ log.Error(4, "webhook.GetWorkwechatMetaHook(%d): %v", w.ID, err)
+ }
+ return s
+}
+
// History returns history of webhook by given conditions.
func (w *Webhook) History(page int) ([]*HookTask, error) {
return HookTasks(w.ID, page)
@@ -381,14 +391,16 @@ const (
GITEA
DISCORD
DINGTALK
+ WORKWECHAT
)
var hookTaskTypes = map[string]HookTaskType{
- "gitea": GITEA,
- "gogs": GOGS,
- "slack": SLACK,
- "discord": DISCORD,
- "dingtalk": DINGTALK,
+ "gitea": GITEA,
+ "gogs": GOGS,
+ "slack": SLACK,
+ "discord": DISCORD,
+ "dingtalk": DINGTALK,
+ "workwechat": WORKWECHAT,
}
// ToHookTaskType returns HookTaskType by given name.
@@ -409,6 +421,8 @@ func (t HookTaskType) Name() string {
return "discord"
case DINGTALK:
return "dingtalk"
+ case WORKWECHAT:
+ return "workwechat"
}
return ""
}
@@ -581,6 +595,11 @@ func prepareWebhook(e Engine, w *Webhook, repo *Repository, event HookEventType,
if err != nil {
return fmt.Errorf("GetDingtalkPayload: %v", err)
}
+ case WORKWECHAT:
+ payloader, err = GetWorkwechatPayload(p, event, w.Meta)
+ if err != nil {
+ return fmt.Errorf("GetWorkwechatPayload: %v", err)
+ }
default:
p.SetSecret(w.Secret)
payloader = p
diff --git a/models/webhook_workwechat.go b/models/webhook_workwechat.go
new file mode 100644
index 0000000000000..0f57338ca2069
--- /dev/null
+++ b/models/webhook_workwechat.go
@@ -0,0 +1,405 @@
+// Copyright 2018 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/git"
+ api "code.gitea.io/sdk/gitea"
+)
+
+type (
+ // Text message
+ Text struct {
+ Content string `json:"content"`
+ }
+
+ //TextCard message
+ TextCard struct {
+ Title string `json:"title"`
+ Description string `json:"description"`
+ URL string `json:"url"`
+ ButtonText string `json:"btntxt"`
+ }
+ //WorkwechatPayload represents
+ WorkwechatPayload struct {
+ ChatID string `json:"chatid"`
+ MsgType string `json:"msgtype"`
+ Text Text `json:"text"`
+ TextCard TextCard `json:"textcard"`
+ Safe int `json:"safe"`
+ }
+
+ // WorkwechatMeta contains the work wechat metadata
+ WorkwechatMeta struct {
+ ChatID string `json:"chatid"`
+ }
+)
+
+// SetSecret sets the workwechat secret
+func (p *WorkwechatPayload) SetSecret(_ string) {}
+
+// JSONPayload Marshals the WorkwechatPayload to json
+func (p *WorkwechatPayload) JSONPayload() ([]byte, error) {
+ data, err := json.MarshalIndent(p, "", " ")
+ if err != nil {
+ return []byte{}, err
+ }
+ return data, nil
+}
+
+func getWorkwechatCreatePayload(p *api.CreatePayload, meta *WorkwechatMeta) (*WorkwechatPayload, error) {
+ // created tag/branch
+ refName := git.RefEndName(p.Ref)
+ title := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName)
+
+ return &WorkwechatPayload{
+ ChatID: meta.ChatID,
+ MsgType: "textcard",
+ TextCard: TextCard{
+ Title: title,
+ Description: title,
+ ButtonText: fmt.Sprintf("view ref %s", refName),
+ URL: p.Repo.HTMLURL + "/src/" + refName,
+ },
+ }, nil
+}
+
+func getWorkwechatDeletePayload(p *api.DeletePayload, meta *WorkwechatMeta) (*WorkwechatPayload, error) {
+ // created tag/branch
+ refName := git.RefEndName(p.Ref)
+ title := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName)
+
+ return &WorkwechatPayload{
+ ChatID: meta.ChatID,
+ MsgType: "textcard",
+ TextCard: TextCard{
+ Title: title,
+ Description: title,
+ ButtonText: fmt.Sprintf("view ref %s", refName),
+ URL: p.Repo.HTMLURL + "/src/" + refName,
+ },
+ }, nil
+}
+
+func getWorkwechatForkPayload(p *api.ForkPayload, meta *WorkwechatMeta) (*WorkwechatPayload, error) {
+ title := fmt.Sprintf("%s is forked to %s", p.Forkee.FullName, p.Repo.FullName)
+
+ return &WorkwechatPayload{
+ ChatID: meta.ChatID,
+ MsgType: "textcard",
+ TextCard: TextCard{
+ Description: title,
+ Title: title,
+ ButtonText: fmt.Sprintf("view forked repo %s", p.Repo.FullName),
+ URL: p.Repo.HTMLURL,
+ },
+ }, nil
+}
+
+func getWorkwechatPushPayload(p *api.PushPayload, meta *WorkwechatMeta) (*WorkwechatPayload, error) {
+ var (
+ branchName = git.RefEndName(p.Ref)
+ commitDesc string
+ )
+
+ var titleLink, linkText string
+ if len(p.Commits) == 1 {
+ commitDesc = "1 new commit"
+ titleLink = p.Commits[0].URL
+ linkText = fmt.Sprintf("view commit %s", p.Commits[0].ID[:7])
+ } else {
+ commitDesc = fmt.Sprintf("%d new commits", len(p.Commits))
+ titleLink = p.CompareURL
+ linkText = fmt.Sprintf("view commit %s...%s", p.Commits[0].ID[:7], p.Commits[len(p.Commits)-1].ID[:7])
+ }
+ 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 {
+ var authorName string
+ if commit.Author != nil {
+ authorName = " - " + commit.Author.Name
+ }
+ text += fmt.Sprintf("[%s](%s) %s", commit.ID[:7], commit.URL,
+ strings.TrimRight(commit.Message, "\r\n")) + authorName
+ // add linebreak to each commit but the last
+ if i < len(p.Commits)-1 {
+ text += "\n"
+ }
+ }
+
+ return &WorkwechatPayload{
+ ChatID: meta.ChatID,
+ MsgType: "textcard",
+ TextCard: TextCard{
+ Description: text,
+ Title: title,
+ ButtonText: linkText,
+ URL: titleLink,
+ },
+ }, nil
+}
+
+func getWorkwechatIssuesPayload(p *api.IssuePayload, meta *WorkwechatMeta) (*WorkwechatPayload, error) {
+ var text, title string
+ 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
+ case api.HookIssueClosed:
+ title = fmt.Sprintf("[%s] Issue closed: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
+ 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
+ case api.HookIssueEdited:
+ title = fmt.Sprintf("[%s] Issue edited: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
+ text = p.Issue.Body
+ 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
+ case api.HookIssueUnassigned:
+ title = fmt.Sprintf("[%s] Issue unassigned: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
+ text = p.Issue.Body
+ case api.HookIssueLabelUpdated:
+ title = fmt.Sprintf("[%s] Issue labels updated: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
+ text = p.Issue.Body
+ case api.HookIssueLabelCleared:
+ title = fmt.Sprintf("[%s] Issue labels cleared: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
+ text = p.Issue.Body
+ case api.HookIssueSynchronized:
+ title = fmt.Sprintf("[%s] Issue synchronized: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
+ text = p.Issue.Body
+ case api.HookIssueMilestoned:
+ title = fmt.Sprintf("[%s] Issue milestone: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
+ text = p.Issue.Body
+ case api.HookIssueDemilestoned:
+ title = fmt.Sprintf("[%s] Issue clear milestone: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
+ text = p.Issue.Body
+ }
+
+ return &WorkwechatPayload{
+ ChatID: meta.ChatID,
+ MsgType: "textcard",
+ TextCard: TextCard{
+ Description: title + "\r\n\r\n" + text,
+ //Markdown: "# " + title + "\n" + text,
+ Title: title,
+ ButtonText: "view issue",
+ URL: p.Issue.URL,
+ },
+ }, nil
+}
+
+func getWorkwechatIssueCommentPayload(p *api.IssueCommentPayload, meta *WorkwechatMeta) (*WorkwechatPayload, 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))
+ var content string
+ switch p.Action {
+ case api.HookIssueCommentCreated:
+ title = "New comment: " + title
+ content = p.Comment.Body
+ case api.HookIssueCommentEdited:
+ title = "Comment edited: " + title
+ content = p.Comment.Body
+ case api.HookIssueCommentDeleted:
+ title = "Comment deleted: " + title
+ url = fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Issue.Index)
+ content = p.Comment.Body
+ }
+
+ return &WorkwechatPayload{
+ ChatID: meta.ChatID,
+ MsgType: "textcard",
+ TextCard: TextCard{
+ Description: title + "\r\n\r\n" + content,
+ Title: title,
+ ButtonText: "view issue comment",
+ URL: url,
+ },
+ }, nil
+}
+
+func getWorkwechatPullRequestPayload(p *api.PullRequestPayload, meta *WorkwechatMeta) (*WorkwechatPayload, error) {
+ var text, title string
+ 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
+ case api.HookIssueClosed:
+ if p.PullRequest.HasMerged {
+ title = fmt.Sprintf("[%s] Pull request merged: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
+ } else {
+ title = fmt.Sprintf("[%s] Pull request closed: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
+ }
+ 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
+ case api.HookIssueEdited:
+ title = fmt.Sprintf("[%s] Pull request edited: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
+ text = p.PullRequest.Body
+ case api.HookIssueAssigned:
+ list, err := MakeAssigneeList(&Issue{ID: p.PullRequest.ID})
+ if err != nil {
+ return &WorkwechatPayload{}, err
+ }
+ title = fmt.Sprintf("[%s] Pull request assigned to %s: #%d %s", p.Repository.FullName,
+ list, p.Index, p.PullRequest.Title)
+ text = p.PullRequest.Body
+ case api.HookIssueUnassigned:
+ title = fmt.Sprintf("[%s] Pull request unassigned: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
+ text = p.PullRequest.Body
+ 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
+ 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
+ case api.HookIssueSynchronized:
+ title = fmt.Sprintf("[%s] Pull request synchronized: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
+ text = p.PullRequest.Body
+ case api.HookIssueMilestoned:
+ title = fmt.Sprintf("[%s] Pull request milestone: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
+ text = p.PullRequest.Body
+ 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
+ }
+
+ return &WorkwechatPayload{
+ ChatID: meta.ChatID,
+ MsgType: "textcard",
+ TextCard: TextCard{
+ Description: title + "\r\n\r\n" + text,
+ //Markdown: "# " + title + "\n" + text,
+ Title: title,
+ ButtonText: "view pull request",
+ URL: p.PullRequest.HTMLURL,
+ },
+ }, nil
+}
+
+func getWorkwechatRepositoryPayload(p *api.RepositoryPayload, meta *WorkwechatMeta) (*WorkwechatPayload, error) {
+ var title, url string
+ switch p.Action {
+ case api.HookRepoCreated:
+ title = fmt.Sprintf("[%s] Repository created", p.Repository.FullName)
+ url = p.Repository.HTMLURL
+ return &WorkwechatPayload{
+ ChatID: meta.ChatID,
+ MsgType: "textcard",
+ TextCard: TextCard{
+ Description: title,
+ Title: title,
+ ButtonText: "view repository",
+ URL: url,
+ },
+ }, nil
+ case api.HookRepoDeleted:
+ title = fmt.Sprintf("[%s] Repository deleted", p.Repository.FullName)
+ return &WorkwechatPayload{
+ MsgType: "text",
+ Text: struct {
+ Content string `json:"content"`
+ }{
+ Content: title,
+ },
+ }, nil
+ }
+
+ return nil, nil
+}
+
+func getWorkwechatReleasePayload(p *api.ReleasePayload, meta *WorkwechatMeta) (*WorkwechatPayload, error) {
+ var title, url string
+ switch p.Action {
+ case api.HookReleasePublished:
+ title = fmt.Sprintf("[%s] Release created", p.Release.TagName)
+ url = p.Release.URL
+ return &WorkwechatPayload{
+ ChatID: meta.ChatID,
+ MsgType: "textcard",
+ TextCard: TextCard{
+ Description: title,
+ Title: title,
+ ButtonText: "view release",
+ URL: url,
+ },
+ }, nil
+ case api.HookReleaseUpdated:
+ title = fmt.Sprintf("[%s] Release updated", p.Release.TagName)
+ url = p.Release.URL
+ return &WorkwechatPayload{
+ ChatID: meta.ChatID,
+ MsgType: "textcard",
+ TextCard: TextCard{
+ Description: title,
+ Title: title,
+ ButtonText: "view release",
+ URL: url,
+ },
+ }, nil
+
+ case api.HookReleaseDeleted:
+ title = fmt.Sprintf("[%s] Release deleted", p.Release.TagName)
+ url = p.Release.URL
+ return &WorkwechatPayload{
+ ChatID: meta.ChatID,
+ MsgType: "textcard",
+ TextCard: TextCard{
+ Description: title,
+ Title: title,
+ ButtonText: "view release",
+ URL: url,
+ },
+ }, nil
+ }
+
+ return nil, nil
+}
+
+// GetWorkwechatPayload converts a work wechat webhook into a WorkwechatPayload
+func GetWorkwechatPayload(p api.Payloader, event HookEventType, meta string) (*WorkwechatPayload, error) {
+ s := new(WorkwechatPayload)
+
+ workwechatMeta := &WorkwechatMeta{}
+ if err := json.Unmarshal([]byte(meta), &workwechatMeta); err != nil {
+ return s, errors.New("GetWorkwechatPayload meta json:" + err.Error())
+ }
+ switch event {
+ case HookEventCreate:
+ return getWorkwechatCreatePayload(p.(*api.CreatePayload), workwechatMeta)
+ case HookEventDelete:
+ return getWorkwechatDeletePayload(p.(*api.DeletePayload), workwechatMeta)
+ case HookEventFork:
+ return getWorkwechatForkPayload(p.(*api.ForkPayload), workwechatMeta)
+ case HookEventIssues:
+ return getWorkwechatIssuesPayload(p.(*api.IssuePayload), workwechatMeta)
+ case HookEventIssueComment:
+ return getWorkwechatIssueCommentPayload(p.(*api.IssueCommentPayload), workwechatMeta)
+ case HookEventPush:
+ return getWorkwechatPushPayload(p.(*api.PushPayload), workwechatMeta)
+ case HookEventPullRequest:
+ return getWorkwechatPullRequestPayload(p.(*api.PullRequestPayload), workwechatMeta)
+ case HookEventRepository:
+ return getWorkwechatRepositoryPayload(p.(*api.RepositoryPayload), workwechatMeta)
+ case HookEventRelease:
+ return getWorkwechatReleasePayload(p.(*api.ReleasePayload), workwechatMeta)
+ }
+
+ return s, nil
+}
diff --git a/modules/auth/repo_form.go b/modules/auth/repo_form.go
index 0a97b08c71564..21a2282abf898 100644
--- a/modules/auth/repo_form.go
+++ b/modules/auth/repo_form.go
@@ -263,6 +263,18 @@ func (f *NewDingtalkHookForm) Validate(ctx *macaron.Context, errs binding.Errors
return validate(errs, ctx.Data, f, ctx.Locale)
}
+// NewWorkwechatHookForm form for creating work wechat hook
+type NewWorkwechatHookForm struct {
+ PayloadURL string `binding:"Required;ValidUrl"`
+ ChatID string `form:"chatid"`
+ WebhookForm
+}
+
+// Validate validates the fields
+func (f *NewWorkwechatHookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
+ return validate(errs, ctx.Data, f, ctx.Locale)
+}
+
// .___
// | | ______ ________ __ ____
// | |/ ___// ___/ | \_/ __ \
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index 4c016f3489bb2..1c5b557ee095e 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -1219,6 +1219,7 @@ func NewContext() {
// Explicitly disable credential helper, otherwise Git credentials might leak
git.GlobalCommandArgs = append(git.GlobalCommandArgs, "-c", "credential.helper=")
}
+
}
// NewServices initializes the services
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index c5a62cb4885a6..57a62018b230e 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -1158,6 +1158,8 @@ 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_workwechat_hook_desc = Integrate Work Wechat into your repository.
+settings.workwechat_chatid=Chat ID
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/workwechat.ico b/public/img/workwechat.ico
new file mode 100644
index 0000000000000..a7f24f5aaad28
Binary files /dev/null and b/public/img/workwechat.ico differ
diff --git a/routers/api/v1/convert/convert.go b/routers/api/v1/convert/convert.go
index 6569d21ab89a0..a106ba1b8b875 100644
--- a/routers/api/v1/convert/convert.go
+++ b/routers/api/v1/convert/convert.go
@@ -166,8 +166,10 @@ func ToHook(repoLink string, w *models.Webhook) *api.Hook {
config["username"] = s.Username
config["icon_url"] = s.IconURL
config["color"] = s.Color
+ } else if w.HookTaskType == models.WORKWECHAT {
+ s := w.GetWorkwechatHook()
+ config["chatid"] = s.ChatID
}
-
return &api.Hook{
ID: w.ID,
Type: w.HookTaskType.Name(),
diff --git a/routers/repo/webhook.go b/routers/repo/webhook.go
index 6c69354c700eb..559383cded09e 100644
--- a/routers/repo/webhook.go
+++ b/routers/repo/webhook.go
@@ -105,6 +105,10 @@ func WebhooksNew(ctx *context.Context) {
"Username": "Gitea",
"IconURL": setting.AppURL + "img/favicon.png",
}
+ } else if hookType == "workwechat" {
+ ctx.Data["WorkwechatHook"] = map[string]interface{}{
+ "ChatID": "gitea",
+ }
}
ctx.Data["BaseLink"] = orCtx.Link
@@ -314,6 +318,52 @@ func DingtalkHooksNewPost(ctx *context.Context, form auth.NewDingtalkHookForm) {
ctx.Redirect(orCtx.Link + "/settings/hooks")
}
+// WorkwechatHooksNewPost response for creating work wechat hook
+func WorkwechatHooksNewPost(ctx *context.Context, form auth.NewWorkwechatHookForm) {
+ ctx.Data["Title"] = ctx.Tr("repo.settings")
+ ctx.Data["PageIsSettingsHooks"] = true
+ ctx.Data["PageIsSettingsHooksNew"] = true
+ ctx.Data["Webhook"] = models.Webhook{HookEvent: &models.HookEvent{}}
+
+ orCtx, err := getOrgRepoCtx(ctx)
+ if err != nil {
+ ctx.ServerError("getOrgRepoCtx", err)
+ return
+ }
+
+ if ctx.HasError() {
+ ctx.HTML(200, orCtx.NewTemplate)
+ return
+ }
+ meta, err := json.Marshal(&models.WorkwechatMeta{
+ ChatID: form.ChatID,
+ })
+ if err != nil {
+ ctx.ServerError("Marshal", err)
+ return
+ }
+ w := &models.Webhook{
+ RepoID: orCtx.RepoID,
+ URL: form.PayloadURL,
+ ContentType: models.ContentTypeJSON,
+ HookEvent: ParseHookEvent(form.WebhookForm),
+ IsActive: form.Active,
+ HookTaskType: models.WORKWECHAT,
+ Meta: string(meta),
+ OrgID: orCtx.OrgID,
+ }
+ if err := w.UpdateEvent(); err != nil {
+ ctx.ServerError("UpdateEvent", err)
+ return
+ } else if err := models.CreateWebhook(w); err != nil {
+ ctx.ServerError("CreateWebhook", err)
+ return
+ }
+
+ ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success"))
+ ctx.Redirect(orCtx.Link + "/settings/hooks")
+}
+
// SlackHooksNewPost response for creating slack hook
func SlackHooksNewPost(ctx *context.Context, form auth.NewSlackHookForm) {
ctx.Data["Title"] = ctx.Tr("repo.settings")
@@ -402,6 +452,8 @@ func checkWebhook(ctx *context.Context) (*orgRepoCtx, *models.Webhook) {
ctx.Data["SlackHook"] = w.GetSlackHook()
case models.DISCORD:
ctx.Data["DiscordHook"] = w.GetDiscordHook()
+ case models.WORKWECHAT:
+ ctx.Data["WorkwechatHook"] = w.GetWorkwechatHook()
}
ctx.Data["History"], err = w.History(1)
@@ -596,7 +648,7 @@ func DiscordHooksEditPost(ctx *context.Context, form auth.NewDiscordHookForm) {
ctx.Redirect(fmt.Sprintf("%s/settings/hooks/%d", orCtx.Link, w.ID))
}
-// DingtalkHooksEditPost response for editing discord hook
+// DingtalkHooksEditPost response for editing dingtalk hook
func DingtalkHooksEditPost(ctx *context.Context, form auth.NewDingtalkHookForm) {
ctx.Data["Title"] = ctx.Tr("repo.settings")
ctx.Data["PageIsSettingsHooks"] = true
@@ -628,6 +680,46 @@ func DingtalkHooksEditPost(ctx *context.Context, form auth.NewDingtalkHookForm)
ctx.Redirect(fmt.Sprintf("%s/settings/hooks/%d", orCtx.Link, w.ID))
}
+// WorkwechatHooksEditPost response for editing work wechat hook
+func WorkwechatHooksEditPost(ctx *context.Context, form auth.NewWorkwechatHookForm) {
+ ctx.Data["Title"] = ctx.Tr("repo.settings")
+ ctx.Data["PageIsSettingsHooks"] = true
+ ctx.Data["PageIsSettingsHooksEdit"] = true
+
+ orCtx, w := checkWebhook(ctx)
+ if ctx.Written() {
+ return
+ }
+ ctx.Data["Webhook"] = w
+
+ if ctx.HasError() {
+ ctx.HTML(200, orCtx.NewTemplate)
+ return
+ }
+ meta, err := json.Marshal(&models.WorkwechatMeta{
+ ChatID: form.ChatID,
+ })
+ if err != nil {
+ ctx.ServerError("Marshal", err)
+ return
+ }
+
+ w.URL = form.PayloadURL
+ w.Meta = string(meta)
+ w.HookEvent = ParseHookEvent(form.WebhookForm)
+ w.IsActive = form.Active
+ if err := w.UpdateEvent(); err != nil {
+ ctx.ServerError("UpdateEvent", err)
+ return
+ } else if err := models.UpdateWebhook(w); err != nil {
+ ctx.ServerError("UpdateWebhook", err)
+ return
+ }
+
+ ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success"))
+ ctx.Redirect(fmt.Sprintf("%s/settings/hooks/%d", orCtx.Link, w.ID))
+}
+
// TestWebhook test if web hook is work fine
func TestWebhook(ctx *context.Context) {
hookID := ctx.ParamsInt64(":id")
diff --git a/routers/routes/routes.go b/routers/routes/routes.go
index b73b030a51e09..91753f0bbe6d5 100644
--- a/routers/routes/routes.go
+++ b/routers/routes/routes.go
@@ -484,12 +484,14 @@ 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("/workwechat/new", bindIgnErr(auth.NewWorkwechatHookForm{}), repo.WorkwechatHooksNewPost)
m.Get("/:id", repo.WebHooksEdit)
m.Post("/gitea/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost)
m.Post("/gogs/:id", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksEditPost)
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("/workwechat/:id", bindIgnErr(auth.NewWorkwechatHookForm{}), repo.WorkwechatHooksEditPost)
})
m.Route("/delete", "GET,POST", org.SettingsDelete)
@@ -537,6 +539,7 @@ 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("/workwechat/new", bindIgnErr(auth.NewWorkwechatHookForm{}), repo.WorkwechatHooksNewPost)
m.Get("/:id", repo.WebHooksEdit)
m.Post("/:id/test", repo.TestWebhook)
m.Post("/gitea/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost)
@@ -544,6 +547,7 @@ 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("/workwechat/:id", bindIgnErr(auth.NewWorkwechatHookForm{}), repo.WorkwechatHooksEditPost)
m.Group("/git", func() {
m.Get("", repo.GitHooks)
diff --git a/templates/org/settings/hook_new.tmpl b/templates/org/settings/hook_new.tmpl
index 809009b66b7b4..c3cdf1b24a97a 100644
--- a/templates/org/settings/hook_new.tmpl
+++ b/templates/org/settings/hook_new.tmpl
@@ -18,7 +18,9 @@
{{else if eq .HookType "discord"}}
{{else if eq .HookType "dingtalk"}}
-
+
+ {{else if eq .HookType "workwechat"}}
+
{{end}}
@@ -28,6 +30,7 @@
{{template "repo/settings/webhook/slack" .}}
{{template "repo/settings/webhook/discord" .}}
{{template "repo/settings/webhook/dingtalk" .}}
+ {{template "repo/settings/webhook/workwechat" .}}
{{template "repo/settings/webhook/history" .}}
diff --git a/templates/repo/settings/webhook/list.tmpl b/templates/repo/settings/webhook/list.tmpl
index d98976cf5b400..cdef0d4829677 100644
--- a/templates/repo/settings/webhook/list.tmpl
+++ b/templates/repo/settings/webhook/list.tmpl
@@ -20,6 +20,9 @@
Dingtalk
+
+
Work Wechat
+
diff --git a/templates/repo/settings/webhook/new.tmpl b/templates/repo/settings/webhook/new.tmpl
index 1b3d114577a4e..b4ad5cfb7d423 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 "workwechat"}}
+
{{end}}
@@ -26,6 +28,7 @@
{{template "repo/settings/webhook/slack" .}}
{{template "repo/settings/webhook/discord" .}}
{{template "repo/settings/webhook/dingtalk" .}}
+ {{template "repo/settings/webhook/workwechat" .}}
{{template "repo/settings/webhook/history" .}}
diff --git a/templates/repo/settings/webhook/workwechat.tmpl b/templates/repo/settings/webhook/workwechat.tmpl
new file mode 100644
index 0000000000000..fa1012efc29e6
--- /dev/null
+++ b/templates/repo/settings/webhook/workwechat.tmpl
@@ -0,0 +1,15 @@
+{{if eq .HookType "workwechat"}}
+
{{.i18n.Tr "repo.settings.add_workwechat_hook_desc" "https://work.weixin.qq.com" | Str2html}}
+ +{{end}}