Skip to content

Commit

Permalink
Add support for corporate WeChat webhooks (go-gitea#15910)
Browse files Browse the repository at this point in the history
* 企业微信webhook

* 企业微信webhook

* 企业微信webhook

* Update templates/admin/hook_new.tmpl

Co-authored-by: a1012112796 <1012112796@qq.com>

* Update services/webhook/wechatwork.go

Co-authored-by: a1012112796 <1012112796@qq.com>

* 修善wechatwork

* 修善wechatwork

* fix

* Update locale_cs-CZ.ini

fix

* fix build

* fix

* fix build

* make webhooks.zh-cn.md

* delet unnecessary blank line

* delet unnecessary blank line

* 企业微信webhook

* 企业微信webhook

* 企业微信webhook

* Update templates/admin/hook_new.tmpl

Co-authored-by: a1012112796 <1012112796@qq.com>

* Update services/webhook/wechatwork.go

Co-authored-by: a1012112796 <1012112796@qq.com>

* 修善wechatwork

* 修善wechatwork

* fix

* fix build

* fix

* fix build

* make webhooks.zh-cn.md

* delet unnecessary blank line

* delet unnecessary blank line

* 企业微信webhook

* 企业微信webhook

* 企业微信webhook

* 企业微信webhook

* 企业微信webhook

* fix

* fix

* 企业微信webhook

* 企业微信webhook

* 企业微信webhook

* fix wechat

* fix wechat

* fix wechat

* fix wechat

* Fix invalid params and typo of email templates (go-gitea#16394)

Signed-off-by: Meano <meanocat@gmail.com>

* Add LRU mem cache implementation (go-gitea#16226)

The current default memory cache implementation is unbounded in size and number of
objects cached. This is hardly ideal.

This PR proposes creating a TwoQueue LRU cache as the underlying cache for Gitea.
The cache is limited by the number of objects stored in the cache (rather than size)
for simplicity. The default number of objects is 50000 - which is perhaps too small
as most of our objects cached are going to be much less than 1kB.

It may be worth considering using a different LRU implementation that actively limits
sizes or avoids GC - however, this is just a beginning implementation.

Signed-off-by: Andrew Thornton <art27@cantab.net>

* [skip ci] Updated translations via Crowdin

* Replace `plugins/docker` with `techknowlogick/drone-docker`in ci (go-gitea#16407)

* plugins/docker -> techknowlogick/drone-docker

* It is multi-arch

* docs: rewrite email setup (go-gitea#16404)

* Add intro for both the docs page and mailer methods
  * Fix numbering level in SMTP section
  * Recommends implicit TLS

Signed-off-by: Bagas Sanjaya <bagasdotme@gmail.com>

* Validate Issue Index before querying DB (go-gitea#16406)

* Fix external renderer (go-gitea#16401)

* fix external renderer

* use GBackground context as fallback

* no fallback, return error

Co-authored-by: Lauris BH <lauris@nix.lv>

* Add checkbox to delete pull branch after successful merge (go-gitea#16049)

* Add checkbox to delete pull branch after successful merge

* Omit DeleteBranchAfterMerge field in json

* Log a warning instead of error when PR head branch deleted

* Add DefaultDeleteBranchAfterMerge to PullRequestConfig

* Add support for delete_branch_after_merge via API

* Fix for API: the branch should be deleted from the HEAD repo

If head and base repo are the same, reuse the already opened ctx.Repo.GitRepo

* Don't delegate to CleanupBranch, only reuse branch deletion code

CleanupBranch contains too much logic that has already been performed by the Merge

* Reuse gitrepo in MergePullRequest

Co-authored-by: Andrew Thornton <art27@cantab.net>

* [skip ci] Updated translations via Crowdin

* Detect encoding changes while parsing diff (go-gitea#16330)

* Detect encoding changes while parsing diff

* Let branch/tag name be a valid ref to get CI status (go-gitea#16400)

* fix go-gitea#16384#

* refactor: move shared helper func to utils package

* extend Tests

* use ctx.Repo.GitRepo if not nil

* fix

* fix

* 企业微信webhook

* 企业微信webhook

* 企业微信webhook

* fix build

* fix build

* Apply suggestions from code review

Co-authored-by: a1012112796 <1012112796@qq.com>
Co-authored-by: myheavily <myheavily>
Co-authored-by: zhaoxin <gitea@fake.local>
Co-authored-by: Meano <Meano@foxmail.com>
Co-authored-by: zeripath <art27@cantab.net>
Co-authored-by: GiteaBot <teabot@gitea.io>
Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: Bagas Sanjaya <bagasdotme@gmail.com>
Co-authored-by: Norwin <noerw@users.noreply.github.com>
Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: Jimmy Praet <jimmy.praet@telenet.be>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
  • Loading branch information
12 people authored and AbdulrhmnGhanem committed Aug 10, 2021
1 parent ad5e6cf commit 61c9191
Show file tree
Hide file tree
Showing 24 changed files with 364 additions and 30 deletions.
1 change: 1 addition & 0 deletions docs/content/doc/features/webhooks.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ All event pushes are POST requests. The methods currently supported are:
- Telegram
- Microsoft Teams
- Feishu
- Wechatwork

### Event information

Expand Down
13 changes: 13 additions & 0 deletions docs/content/doc/features/webhooks.zh-cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,17 @@ menu:

# Webhooks

Gitea 的存储 webhook。这可以有存储库管路设定页 `/:username/:reponame/settings/hooks` 中的。Webhook 也可以按照组织调整或全系统调整,所有时间的推送都是POST请求
。此方法目前被下列服务支援:

- Gitea (也可以是 GET 請求)
- Gogs
- Slack
- Discord
- Dingtalk
- Telegram
- Microsoft Teams
- Feishu
- Wechatwork

## TBD
1 change: 1 addition & 0 deletions docs/content/doc/features/webhooks.zh-tw.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Gitea 的儲存庫事件支援 web hook。這可以有儲存庫管理員在設
- Telegram
- Microsoft Teams
- Feishu
- Wechatwork

### 事件資訊

Expand Down
20 changes: 11 additions & 9 deletions models/migrations/v161.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,20 @@ func convertTaskTypeToString(x *xorm.Engine) error {
MSTEAMS
FEISHU
MATRIX
WECHATWORK
)

hookTaskTypes := map[int]string{
GITEA: "gitea",
GOGS: "gogs",
SLACK: "slack",
DISCORD: "discord",
DINGTALK: "dingtalk",
TELEGRAM: "telegram",
MSTEAMS: "msteams",
FEISHU: "feishu",
MATRIX: "matrix",
GITEA: "gitea",
GOGS: "gogs",
SLACK: "slack",
DISCORD: "discord",
DINGTALK: "dingtalk",
TELEGRAM: "telegram",
MSTEAMS: "msteams",
FEISHU: "feishu",
MATRIX: "matrix",
WECHATWORK: "wechatwork",
}

type HookTask struct {
Expand Down
20 changes: 11 additions & 9 deletions models/migrations/v162.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,20 @@ func convertWebhookTaskTypeToString(x *xorm.Engine) error {
MSTEAMS
FEISHU
MATRIX
WECHATWORK
)

hookTaskTypes := map[int]string{
GITEA: "gitea",
GOGS: "gogs",
SLACK: "slack",
DISCORD: "discord",
DINGTALK: "dingtalk",
TELEGRAM: "telegram",
MSTEAMS: "msteams",
FEISHU: "feishu",
MATRIX: "matrix",
GITEA: "gitea",
GOGS: "gogs",
SLACK: "slack",
DISCORD: "discord",
DINGTALK: "dingtalk",
TELEGRAM: "telegram",
MSTEAMS: "msteams",
FEISHU: "feishu",
MATRIX: "matrix",
WECHATWORK: "wechatwork",
}

type Webhook struct {
Expand Down
19 changes: 10 additions & 9 deletions models/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,16 @@ type HookType = string

// Types of webhooks
const (
GITEA HookType = "gitea"
GOGS HookType = "gogs"
SLACK HookType = "slack"
DISCORD HookType = "discord"
DINGTALK HookType = "dingtalk"
TELEGRAM HookType = "telegram"
MSTEAMS HookType = "msteams"
FEISHU HookType = "feishu"
MATRIX HookType = "matrix"
GITEA HookType = "gitea"
GOGS HookType = "gogs"
SLACK HookType = "slack"
DISCORD HookType = "discord"
DINGTALK HookType = "dingtalk"
TELEGRAM HookType = "telegram"
MSTEAMS HookType = "msteams"
FEISHU HookType = "feishu"
MATRIX HookType = "matrix"
WECHATWORK HookType = "wechatwork"
)

// HookStatus is the status of a web hook
Expand Down
2 changes: 1 addition & 1 deletion modules/setting/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ 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", "telegram", "msteams", "feishu", "matrix"}
Webhook.Types = []string{"gitea", "gogs", "slack", "discord", "dingtalk", "telegram", "msteams", "feishu", "matrix", "wechatwork"}
Webhook.PagingNum = sec.Key("PAGING_NUM").MustInt(10)
Webhook.ProxyURL = sec.Key("PROXY_URL").MustString("")
if Webhook.ProxyURL != "" {
Expand Down
2 changes: 1 addition & 1 deletion modules/structs/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type CreateHookOptionConfig map[string]string
// CreateHookOption options when create a hook
type CreateHookOption struct {
// required: true
// enum: dingtalk,discord,gitea,gogs,msteams,slack,telegram,feishu
// enum: dingtalk,discord,gitea,gogs,msteams,slack,telegram,feishu,wechatwork
Type string `json:"type" binding:"Required"`
// required: true
Config CreateHookOptionConfig `json:"config" binding:"Required"`
Expand Down
1 change: 1 addition & 0 deletions options/locale/locale_cs-CZ.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1758,6 +1758,7 @@ settings.add_telegram_hook_desc=Integrovat <a href="%s">Telegram</a> do vašeho
settings.add_matrix_hook_desc=Integrovat <a href="%s">Matrix</a> do vašeho repozitáře.
settings.add_msteams_hook_desc=Integrovat <a href="%s">Microsoft Teams</a> do vašeho repozitáře.
settings.add_feishu_hook_desc=Integrovat <a href="%s">Feishu</a> do vašeho repozitáře.
settings.add_wechatwork_hook_desc=Integrovat <a href="%s">Wechatwork</a> do vašeho repozitáře.
settings.deploy_keys=Klíče pro nasazení
settings.add_deploy_key=Přidat klíč pro nasazení
settings.deploy_key_desc=Klíče pro nasazení mají k tomuto repozitáři přístup pouze pro čtení.
Expand Down
1 change: 1 addition & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1848,6 +1848,7 @@ settings.add_telegram_hook_desc = Integrate <a href="%s">Telegram</a> into your
settings.add_matrix_hook_desc = Integrate <a href="%s">Matrix</a> into your repository.
settings.add_msteams_hook_desc = Integrate <a href="%s">Microsoft Teams</a> into your repository.
settings.add_feishu_hook_desc = Integrate <a href="%s">Feishu</a> into your repository.
settings.add_Wechat_hook_desc = Integrate <a href="%s">Wechatwork</a> 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.
Expand Down
1 change: 1 addition & 0 deletions options/locale/locale_zh-CN.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1848,6 +1848,7 @@ settings.add_telegram_hook_desc=将 <a href="%s">Telegram</a> 集成到您的仓
settings.add_matrix_hook_desc=将 <a href="%s">Matrix</a> 集成到您的仓库中。
settings.add_msteams_hook_desc=将 <a href="%s">Microsoft Teams</a> 集成到您的仓库中。
settings.add_feishu_hook_desc=将 <a href="%s">Feishu</a> 集成到您的仓库中。
settings.add_wechatwork_hook_desc=将 <a href="%s">Wechatwork</a> 集成到您的仓库中。
settings.deploy_keys=部署密钥
settings.add_deploy_key=添加部署密钥
settings.deploy_key_desc=部署密钥具有对仓库的只读拉取权限。
Expand Down
1 change: 1 addition & 0 deletions options/locale/locale_zh-TW.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1833,6 +1833,7 @@ settings.add_telegram_hook_desc=將 <a href="%s">Telegram</a> 整合到您的儲
settings.add_matrix_hook_desc=將 <a href="%s">Matrix</a> 整合到您的儲存庫。
settings.add_msteams_hook_desc=將 <a href="%s">Microsoft Teams</a> 整合到您的儲存庫。
settings.add_feishu_hook_desc=將 <a href="%s">Feishu</a> 整合到您的儲存庫。
settings.add_wechatwork_hook_desc=将 <a href="%s">Wechatwork</a> 整合到您的儲存庫。
settings.deploy_keys=部署金鑰
settings.add_deploy_key=新增部署金鑰
settings.deploy_key_desc=部署金鑰具有唯讀權限,可拉取此儲存庫。
Expand Down
Binary file added public/img/wechatwork.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
77 changes: 77 additions & 0 deletions routers/web/repo/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,50 @@ func FeishuHooksNewPost(ctx *context.Context) {
ctx.Redirect(orCtx.Link)
}

// WechatworkHooksNewPost response for creating wechatwork hook
func WechatworkHooksNewPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.NewWechatWorkHookForm)

ctx.Data["Title"] = ctx.Tr("repo.settings")
ctx.Data["PageIsSettingsHooks"] = true
ctx.Data["PageIsSettingsHooksNew"] = true
ctx.Data["Webhook"] = models.Webhook{HookEvent: &models.HookEvent{}}
ctx.Data["HookType"] = models.WECHATWORK

orCtx, err := getOrgRepoCtx(ctx)
if err != nil {
ctx.ServerError("getOrgRepoCtx", err)
return
}

if ctx.HasError() {
ctx.HTML(http.StatusOK, orCtx.NewTemplate)
return
}

w := &models.Webhook{
RepoID: orCtx.RepoID,
URL: form.PayloadURL,
ContentType: models.ContentTypeJSON,
HookEvent: ParseHookEvent(form.WebhookForm),
IsActive: form.Active,
Type: models.WECHATWORK,
Meta: "",
OrgID: orCtx.OrgID,
IsSystemWebhook: orCtx.IsSystemWebhook,
}
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)
}

func checkWebhook(ctx *context.Context) (*orgRepoCtx, *models.Webhook) {
ctx.Data["RequireHighlightJS"] = true

Expand Down Expand Up @@ -1062,6 +1106,39 @@ func FeishuHooksEditPost(ctx *context.Context) {
ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID))
}

// WechatworkHooksEditPost response for editing wechatwork hook
func WechatworkHooksEditPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.NewWechatWorkHookForm)
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(http.StatusOK, orCtx.NewTemplate)
return
}

w.URL = form.PayloadURL
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/%d", orCtx.Link, w.ID))
}

// TestWebhook test if web hook is work fine
func TestWebhook(ctx *context.Context) {
hookID := ctx.ParamsInt64(":id")
Expand Down
5 changes: 5 additions & 0 deletions routers/web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ func RegisterRoutes(m *web.Route) {
m.Post("/matrix/{id}", bindIgnErr(forms.NewMatrixHookForm{}), repo.MatrixHooksEditPost)
m.Post("/msteams/{id}", bindIgnErr(forms.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost)
m.Post("/feishu/{id}", bindIgnErr(forms.NewFeishuHookForm{}), repo.FeishuHooksEditPost)
m.Post("/wechatwork/{id}", bindIgnErr(forms.NewWechatWorkHookForm{}), repo.WechatworkHooksEditPost)
}, webhooksEnabled)

m.Group("/{configType:default-hooks|system-hooks}", func() {
Expand All @@ -438,6 +439,8 @@ func RegisterRoutes(m *web.Route) {
m.Post("/matrix/new", bindIgnErr(forms.NewMatrixHookForm{}), repo.MatrixHooksNewPost)
m.Post("/msteams/new", bindIgnErr(forms.NewMSTeamsHookForm{}), repo.MSTeamsHooksNewPost)
m.Post("/feishu/new", bindIgnErr(forms.NewFeishuHookForm{}), repo.FeishuHooksNewPost)
m.Post("/wechatwork/new", bindIgnErr(forms.NewWechatWorkHookForm{}), repo.WechatworkHooksNewPost)

})

m.Group("/auths", func() {
Expand Down Expand Up @@ -628,6 +631,7 @@ func RegisterRoutes(m *web.Route) {
m.Post("/matrix/new", bindIgnErr(forms.NewMatrixHookForm{}), repo.MatrixHooksNewPost)
m.Post("/msteams/new", bindIgnErr(forms.NewMSTeamsHookForm{}), repo.MSTeamsHooksNewPost)
m.Post("/feishu/new", bindIgnErr(forms.NewFeishuHookForm{}), repo.FeishuHooksNewPost)
m.Post("/wechatwork/new", bindIgnErr(forms.NewWechatWorkHookForm{}), repo.WechatworkHooksNewPost)
m.Get("/{id}", repo.WebHooksEdit)
m.Post("/{id}/test", repo.TestWebhook)
m.Post("/gitea/{id}", bindIgnErr(forms.NewWebhookForm{}), repo.WebHooksEditPost)
Expand All @@ -639,6 +643,7 @@ func RegisterRoutes(m *web.Route) {
m.Post("/matrix/{id}", bindIgnErr(forms.NewMatrixHookForm{}), repo.MatrixHooksEditPost)
m.Post("/msteams/{id}", bindIgnErr(forms.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost)
m.Post("/feishu/{id}", bindIgnErr(forms.NewFeishuHookForm{}), repo.FeishuHooksEditPost)
m.Post("/wechatwork/{id}", bindIgnErr(forms.NewWechatWorkHookForm{}), repo.WechatworkHooksEditPost)
}, webhooksEnabled)

m.Group("/keys", func() {
Expand Down
12 changes: 12 additions & 0 deletions services/forms/repo_form.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,18 @@ func (f *NewFeishuHookForm) Validate(req *http.Request, errs binding.Errors) bin
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
}

// NewWechatWorkHookForm form for creating wechatwork hook
type NewWechatWorkHookForm struct {
PayloadURL string `binding:"Required;ValidUrl"`
WebhookForm
}

// Validate validates the fields
func (f *NewWechatWorkHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
ctx := context.GetContext(req)
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
}

// .___
// | | ______ ________ __ ____
// | |/ ___// ___/ | \_/ __ \
Expand Down
4 changes: 4 additions & 0 deletions services/webhook/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ var (
name: models.MATRIX,
payloadCreator: GetMatrixPayload,
},
models.WECHATWORK: {
name: models.WECHATWORK,
payloadCreator: GetWechatworkPayload,
},
}
)

Expand Down
Loading

0 comments on commit 61c9191

Please sign in to comment.