mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2026-02-03 20:51:07 -05:00
Committer names in Slack/Mattermost messages trigger notifications to the corresponding users if they have configured notifications for messages containing their names. These notifications are intended to alert users when someone else mentions them. However, for Git-related messages, users may receive notifications triggered by their own actions. To prevent this, BitBucket, for example, places names in inline code blocks. This pull request adds a similar feature for the Forgejo Slack webhook. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10147 Reviewed-by: Lucas <sclu1034@noreply.codeberg.org> Reviewed-by: oliverpool <oliverpool@noreply.codeberg.org> Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: Erki Aring <erki@example.ee> Co-committed-by: Erki Aring <erki@example.ee>
216 lines
7.4 KiB
Go
216 lines
7.4 KiB
Go
// Copyright 2021 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package webhook
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"html/template"
|
|
"net/http"
|
|
"strings"
|
|
|
|
webhook_model "forgejo.org/models/webhook"
|
|
"forgejo.org/modules/git"
|
|
api "forgejo.org/modules/structs"
|
|
webhook_module "forgejo.org/modules/webhook"
|
|
"forgejo.org/services/forms"
|
|
"forgejo.org/services/webhook/shared"
|
|
)
|
|
|
|
type wechatworkHandler struct{}
|
|
|
|
func (wechatworkHandler) Type() webhook_module.HookType { return webhook_module.WECHATWORK }
|
|
func (wechatworkHandler) Metadata(*webhook_model.Webhook) any { return nil }
|
|
|
|
func (wechatworkHandler) Icon(size int) template.HTML {
|
|
return shared.ImgIcon("wechatwork.png", size)
|
|
}
|
|
|
|
func (wechatworkHandler) UnmarshalForm(bind func(any)) forms.WebhookForm {
|
|
var form struct {
|
|
forms.WebhookCoreForm
|
|
PayloadURL string `binding:"Required;ValidUrl"`
|
|
}
|
|
bind(&form)
|
|
|
|
return forms.WebhookForm{
|
|
WebhookCoreForm: form.WebhookCoreForm,
|
|
URL: form.PayloadURL,
|
|
ContentType: webhook_model.ContentTypeJSON,
|
|
Secret: "",
|
|
HTTPMethod: http.MethodPost,
|
|
Metadata: nil,
|
|
}
|
|
}
|
|
|
|
type (
|
|
// WechatworkPayload represents
|
|
WechatworkPayload struct {
|
|
Msgtype string `json:"msgtype"`
|
|
Text struct {
|
|
Content string `json:"content"`
|
|
MentionedList []string `json:"mentioned_list"`
|
|
MentionedMobileList []string `json:"mentioned_mobile_list"`
|
|
} `json:"text"`
|
|
Markdown struct {
|
|
Content string `json:"content"`
|
|
} `json:"markdown"`
|
|
}
|
|
)
|
|
|
|
func newWechatworkMarkdownPayload(title string) WechatworkPayload {
|
|
return WechatworkPayload{
|
|
Msgtype: "markdown",
|
|
Markdown: struct {
|
|
Content string `json:"content"`
|
|
}{
|
|
Content: title,
|
|
},
|
|
}
|
|
}
|
|
|
|
// Create implements PayloadConvertor Create method
|
|
func (wc wechatworkConvertor) Create(p *api.CreatePayload) (WechatworkPayload, error) {
|
|
// created tag/branch
|
|
refName := git.RefName(p.Ref).ShortName()
|
|
title := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName)
|
|
|
|
return newWechatworkMarkdownPayload(title), nil
|
|
}
|
|
|
|
// Delete implements PayloadConvertor Delete method
|
|
func (wc wechatworkConvertor) Delete(p *api.DeletePayload) (WechatworkPayload, error) {
|
|
// created tag/branch
|
|
refName := git.RefName(p.Ref).ShortName()
|
|
title := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName)
|
|
|
|
return newWechatworkMarkdownPayload(title), nil
|
|
}
|
|
|
|
// Fork implements PayloadConvertor Fork method
|
|
func (wc wechatworkConvertor) Fork(p *api.ForkPayload) (WechatworkPayload, error) {
|
|
title := fmt.Sprintf("%s is forked to %s", p.Forkee.FullName, p.Repo.FullName)
|
|
|
|
return newWechatworkMarkdownPayload(title), nil
|
|
}
|
|
|
|
// Push implements PayloadConvertor Push method
|
|
func (wc wechatworkConvertor) Push(p *api.PushPayload) (WechatworkPayload, error) {
|
|
var (
|
|
branchName = git.RefName(p.Ref).ShortName()
|
|
commitDesc string
|
|
)
|
|
|
|
title := fmt.Sprintf("# %s:%s <font color=\"warning\"> %s </font>", 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 = "Author: " + commit.Author.Name
|
|
}
|
|
|
|
message := strings.ReplaceAll(commit.Message, "\n\n", "\r\n")
|
|
text += fmt.Sprintf(" > [%s](%s) \r\n ><font color=\"info\">%s</font> \n ><font color=\"warning\">%s</font>", commit.ID[:7], commit.URL,
|
|
message, authorName)
|
|
|
|
// add linebreak to each commit but the last
|
|
if i < len(p.Commits)-1 {
|
|
text += "\n"
|
|
}
|
|
}
|
|
return newWechatworkMarkdownPayload(title + "\r\n\r\n" + text), nil
|
|
}
|
|
|
|
// Issue implements PayloadConvertor Issue method
|
|
func (wc wechatworkConvertor) Issue(p *api.IssuePayload) (WechatworkPayload, error) {
|
|
text, issueTitle, attachmentText, _ := getIssuesPayloadInfo(p, noneLinkFormatter, noneNameFormatter, true)
|
|
var content string
|
|
content += fmt.Sprintf(" ><font color=\"info\">%s</font>\n >%s \n ><font color=\"warning\"> %s</font> \n [%s](%s)", text, attachmentText, issueTitle, p.Issue.HTMLURL, p.Issue.HTMLURL)
|
|
|
|
return newWechatworkMarkdownPayload(content), nil
|
|
}
|
|
|
|
// IssueComment implements PayloadConvertor IssueComment method
|
|
func (wc wechatworkConvertor) IssueComment(p *api.IssueCommentPayload) (WechatworkPayload, error) {
|
|
text, issueTitle, _ := getIssueCommentPayloadInfo(p, noneLinkFormatter, noneNameFormatter, true)
|
|
var content string
|
|
content += fmt.Sprintf(" ><font color=\"info\">%s</font>\n >%s \n ><font color=\"warning\">%s</font> \n [%s](%s)", text, p.Comment.Body, issueTitle, p.Comment.HTMLURL, p.Comment.HTMLURL)
|
|
|
|
return newWechatworkMarkdownPayload(content), nil
|
|
}
|
|
|
|
// PullRequest implements PayloadConvertor PullRequest method
|
|
func (wc wechatworkConvertor) PullRequest(p *api.PullRequestPayload) (WechatworkPayload, error) {
|
|
text, issueTitle, attachmentText, _ := getPullRequestPayloadInfo(p, noneLinkFormatter, noneNameFormatter, true)
|
|
pr := fmt.Sprintf("> <font color=\"info\"> %s </font> \r\n > <font color=\"comment\">%s </font> \r\n > <font color=\"comment\">%s </font> \r\n",
|
|
text, issueTitle, attachmentText)
|
|
|
|
return newWechatworkMarkdownPayload(pr), nil
|
|
}
|
|
|
|
// Review implements PayloadConvertor Review method
|
|
func (wc wechatworkConvertor) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (WechatworkPayload, error) {
|
|
var text, title string
|
|
if p.Action == api.HookIssueReviewed {
|
|
action, err := parseHookPullRequestEventType(event)
|
|
if err != nil {
|
|
return WechatworkPayload{}, err
|
|
}
|
|
title = fmt.Sprintf("[%s] Pull request review %s : #%d %s", p.Repository.FullName, action, p.Index, p.PullRequest.Title)
|
|
text = p.Review.Content
|
|
}
|
|
|
|
return newWechatworkMarkdownPayload("# " + title + "\r\n\r\n >" + text), nil
|
|
}
|
|
|
|
// Repository implements PayloadConvertor Repository method
|
|
func (wc wechatworkConvertor) Repository(p *api.RepositoryPayload) (WechatworkPayload, error) {
|
|
var title string
|
|
switch p.Action {
|
|
case api.HookRepoCreated:
|
|
title = fmt.Sprintf("[%s] Repository created", p.Repository.FullName)
|
|
return newWechatworkMarkdownPayload(title), nil
|
|
case api.HookRepoDeleted:
|
|
title = fmt.Sprintf("[%s] Repository deleted", p.Repository.FullName)
|
|
return newWechatworkMarkdownPayload(title), nil
|
|
}
|
|
|
|
return WechatworkPayload{}, nil
|
|
}
|
|
|
|
// Wiki implements PayloadConvertor Wiki method
|
|
func (wc wechatworkConvertor) Wiki(p *api.WikiPayload) (WechatworkPayload, error) {
|
|
text, _, _ := getWikiPayloadInfo(p, noneLinkFormatter, noneNameFormatter, true)
|
|
|
|
return newWechatworkMarkdownPayload(text), nil
|
|
}
|
|
|
|
// Release implements PayloadConvertor Release method
|
|
func (wc wechatworkConvertor) Release(p *api.ReleasePayload) (WechatworkPayload, error) {
|
|
text, _ := getReleasePayloadInfo(p, noneLinkFormatter, noneNameFormatter, true)
|
|
|
|
return newWechatworkMarkdownPayload(text), nil
|
|
}
|
|
|
|
func (wc wechatworkConvertor) Package(p *api.PackagePayload) (WechatworkPayload, error) {
|
|
text, _ := getPackagePayloadInfo(p, noneLinkFormatter, noneNameFormatter, true)
|
|
|
|
return newWechatworkMarkdownPayload(text), nil
|
|
}
|
|
|
|
func (wc wechatworkConvertor) Action(p *api.ActionPayload) (WechatworkPayload, error) {
|
|
text, _ := getActionPayloadInfo(p, noneLinkFormatter)
|
|
|
|
return newWechatworkMarkdownPayload(text), nil
|
|
}
|
|
|
|
type wechatworkConvertor struct{}
|
|
|
|
var _ shared.PayloadConvertor[WechatworkPayload] = wechatworkConvertor{}
|
|
|
|
func (wechatworkHandler) NewRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (*http.Request, []byte, error) {
|
|
return shared.NewJSONRequest(wechatworkConvertor{}, w, t, true)
|
|
}
|