2020-02-12 11:48:28 +03:00
// Copyright 2020 The Gitea Authors. All rights reserved.
2022-11-27 21:20:29 +03:00
// SPDX-License-Identifier: MIT
2020-02-12 11:48:28 +03:00
package webhook
import (
2024-03-08 01:18:38 +03:00
"context"
2020-02-12 11:48:28 +03:00
"fmt"
2024-03-22 18:02:48 +03:00
"html/template"
2024-03-08 01:18:38 +03:00
"net/http"
2020-02-12 11:48:28 +03:00
"strings"
2024-03-08 01:18:38 +03:00
webhook_model "code.gitea.io/gitea/models/webhook"
2020-02-12 11:48:28 +03:00
"code.gitea.io/gitea/modules/git"
api "code.gitea.io/gitea/modules/structs"
2023-01-01 18:23:15 +03:00
webhook_module "code.gitea.io/gitea/modules/webhook"
2024-03-21 16:02:14 +03:00
"code.gitea.io/gitea/services/forms"
2024-04-03 15:22:36 +03:00
"code.gitea.io/gitea/services/webhook/shared"
2020-02-12 11:48:28 +03:00
)
2024-03-20 17:44:01 +03:00
type feishuHandler struct { }
2024-03-21 15:23:27 +03:00
func ( feishuHandler ) Type ( ) webhook_module . HookType { return webhook_module . FEISHU }
2024-04-03 15:22:36 +03:00
func ( feishuHandler ) Icon ( size int ) template . HTML { return shared . ImgIcon ( "feishu.png" , size ) }
2024-03-21 15:23:27 +03:00
2024-04-03 15:22:36 +03:00
func ( feishuHandler ) UnmarshalForm ( bind func ( any ) ) forms . WebhookForm {
2024-03-21 16:02:14 +03:00
var form struct {
2024-04-03 15:22:36 +03:00
forms . WebhookCoreForm
2024-03-21 16:02:14 +03:00
PayloadURL string ` binding:"Required;ValidUrl" `
}
bind ( & form )
2024-04-03 15:22:36 +03:00
return forms . WebhookForm {
WebhookCoreForm : form . WebhookCoreForm ,
URL : form . PayloadURL ,
ContentType : webhook_model . ContentTypeJSON ,
Secret : "" ,
HTTPMethod : http . MethodPost ,
Metadata : nil ,
2024-03-21 16:02:14 +03:00
}
2024-03-21 15:23:27 +03:00
}
2024-03-20 17:44:01 +03:00
func ( feishuHandler ) Metadata ( * webhook_model . Webhook ) any { return nil }
2020-02-12 11:48:28 +03:00
type (
// FeishuPayload represents
FeishuPayload struct {
2023-10-31 07:43:38 +03:00
MsgType string ` json:"msg_type" ` // text / post / image / share_chat / interactive / file /audio / media
2020-12-11 19:04:04 +03:00
Content struct {
Text string ` json:"text" `
} ` json:"content" `
2020-02-12 11:48:28 +03:00
}
)
2024-03-08 01:18:38 +03:00
func newFeishuTextPayload ( text string ) FeishuPayload {
return FeishuPayload {
2020-12-11 19:04:04 +03:00
MsgType : "text" ,
Content : struct {
Text string ` json:"text" `
} {
2021-06-21 05:12:19 +03:00
Text : strings . TrimSpace ( text ) ,
2020-12-11 19:04:04 +03:00
} ,
}
}
2020-09-05 05:57:13 +03:00
// Create implements PayloadConvertor Create method
2024-03-08 01:18:38 +03:00
func ( fc feishuConvertor ) Create ( p * api . CreatePayload ) ( FeishuPayload , error ) {
2020-02-12 11:48:28 +03:00
// created tag/branch
2023-05-26 04:04:48 +03:00
refName := git . RefName ( p . Ref ) . ShortName ( )
2020-12-11 19:04:04 +03:00
text := fmt . Sprintf ( "[%s] %s %s created" , p . Repo . FullName , p . RefType , refName )
2020-02-12 11:48:28 +03:00
2020-12-11 19:04:04 +03:00
return newFeishuTextPayload ( text ) , nil
2020-02-12 11:48:28 +03:00
}
2020-09-05 05:57:13 +03:00
// Delete implements PayloadConvertor Delete method
2024-03-08 01:18:38 +03:00
func ( fc feishuConvertor ) Delete ( p * api . DeletePayload ) ( FeishuPayload , error ) {
2020-02-12 11:48:28 +03:00
// created tag/branch
2023-05-26 04:04:48 +03:00
refName := git . RefName ( p . Ref ) . ShortName ( )
2020-12-11 19:04:04 +03:00
text := fmt . Sprintf ( "[%s] %s %s deleted" , p . Repo . FullName , p . RefType , refName )
2020-02-12 11:48:28 +03:00
2020-12-11 19:04:04 +03:00
return newFeishuTextPayload ( text ) , nil
2020-02-12 11:48:28 +03:00
}
2020-09-05 05:57:13 +03:00
// Fork implements PayloadConvertor Fork method
2024-03-08 01:18:38 +03:00
func ( fc feishuConvertor ) Fork ( p * api . ForkPayload ) ( FeishuPayload , error ) {
2020-12-11 19:04:04 +03:00
text := fmt . Sprintf ( "%s is forked to %s" , p . Forkee . FullName , p . Repo . FullName )
2020-02-12 11:48:28 +03:00
2020-12-11 19:04:04 +03:00
return newFeishuTextPayload ( text ) , nil
2020-02-12 11:48:28 +03:00
}
2020-09-05 05:57:13 +03:00
// Push implements PayloadConvertor Push method
2024-03-08 01:18:38 +03:00
func ( fc feishuConvertor ) Push ( p * api . PushPayload ) ( FeishuPayload , error ) {
2020-02-12 11:48:28 +03:00
var (
2023-05-26 04:04:48 +03:00
branchName = git . RefName ( p . Ref ) . ShortName ( )
2020-02-12 11:48:28 +03:00
commitDesc string
)
2022-01-20 20:46:10 +03:00
text := fmt . Sprintf ( "[%s:%s] %s\r\n" , p . Repo . FullName , branchName , commitDesc )
2020-02-12 11:48:28 +03:00
// 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 {
2021-06-21 05:12:19 +03:00
text += "\r\n"
2020-02-12 11:48:28 +03:00
}
}
2020-12-11 19:04:04 +03:00
return newFeishuTextPayload ( text ) , nil
2020-02-12 11:48:28 +03:00
}
2020-09-05 05:57:13 +03:00
// Issue implements PayloadConvertor Issue method
2024-03-08 01:18:38 +03:00
func ( fc feishuConvertor ) Issue ( p * api . IssuePayload ) ( FeishuPayload , error ) {
2023-08-24 04:00:11 +03:00
title , link , by , operator , result , assignees := getIssuesInfo ( p )
if assignees != "" {
if p . Action == api . HookIssueAssigned || p . Action == api . HookIssueUnassigned || p . Action == api . HookIssueMilestoned {
2024-03-08 01:18:38 +03:00
return newFeishuTextPayload ( fmt . Sprintf ( "%s\n%s\n%s\n%s\n%s\n%s\n\n%s" , title , link , by , operator , result , assignees , p . Issue . Body ) ) , nil
2023-08-24 04:00:11 +03:00
}
2024-03-08 01:18:38 +03:00
return newFeishuTextPayload ( fmt . Sprintf ( "%s\n%s\n%s\n%s\n%s\n\n%s" , title , link , by , operator , assignees , p . Issue . Body ) ) , nil
2023-08-24 04:00:11 +03:00
}
2024-03-08 01:18:38 +03:00
return newFeishuTextPayload ( fmt . Sprintf ( "%s\n%s\n%s\n%s\n\n%s" , title , link , by , operator , p . Issue . Body ) ) , nil
2020-02-12 11:48:28 +03:00
}
2020-09-05 05:57:13 +03:00
// IssueComment implements PayloadConvertor IssueComment method
2024-03-08 01:18:38 +03:00
func ( fc feishuConvertor ) IssueComment ( p * api . IssueCommentPayload ) ( FeishuPayload , error ) {
2023-08-24 04:00:11 +03:00
title , link , by , operator := getIssuesCommentInfo ( p )
return newFeishuTextPayload ( fmt . Sprintf ( "%s\n%s\n%s\n%s\n\n%s" , title , link , by , operator , p . Comment . Body ) ) , nil
2020-02-12 11:48:28 +03:00
}
2020-09-05 05:57:13 +03:00
// PullRequest implements PayloadConvertor PullRequest method
2024-03-08 01:18:38 +03:00
func ( fc feishuConvertor ) PullRequest ( p * api . PullRequestPayload ) ( FeishuPayload , error ) {
2023-08-24 04:00:11 +03:00
title , link , by , operator , result , assignees := getPullRequestInfo ( p )
if assignees != "" {
if p . Action == api . HookIssueAssigned || p . Action == api . HookIssueUnassigned || p . Action == api . HookIssueMilestoned {
2024-03-08 01:18:38 +03:00
return newFeishuTextPayload ( fmt . Sprintf ( "%s\n%s\n%s\n%s\n%s\n%s\n\n%s" , title , link , by , operator , result , assignees , p . PullRequest . Body ) ) , nil
2023-08-24 04:00:11 +03:00
}
2024-03-08 01:18:38 +03:00
return newFeishuTextPayload ( fmt . Sprintf ( "%s\n%s\n%s\n%s\n%s\n\n%s" , title , link , by , operator , assignees , p . PullRequest . Body ) ) , nil
2023-08-24 04:00:11 +03:00
}
2024-03-08 01:18:38 +03:00
return newFeishuTextPayload ( fmt . Sprintf ( "%s\n%s\n%s\n%s\n\n%s" , title , link , by , operator , p . PullRequest . Body ) ) , nil
2020-02-12 11:48:28 +03:00
}
2020-09-05 05:57:13 +03:00
// Review implements PayloadConvertor Review method
2024-03-08 01:18:38 +03:00
func ( fc feishuConvertor ) Review ( p * api . PullRequestPayload , event webhook_module . HookEventType ) ( FeishuPayload , error ) {
2021-06-21 05:12:19 +03:00
action , err := parseHookPullRequestEventType ( event )
if err != nil {
2024-03-08 01:18:38 +03:00
return FeishuPayload { } , err
2020-02-12 11:48:28 +03:00
}
2021-06-21 05:12:19 +03:00
title := fmt . Sprintf ( "[%s] Pull request review %s : #%d %s" , p . Repository . FullName , action , p . Index , p . PullRequest . Title )
text := p . Review . Content
2020-12-11 19:04:04 +03:00
return newFeishuTextPayload ( title + "\r\n\r\n" + text ) , nil
2020-02-12 11:48:28 +03:00
}
2020-09-05 05:57:13 +03:00
// Repository implements PayloadConvertor Repository method
2024-03-08 01:18:38 +03:00
func ( fc feishuConvertor ) Repository ( p * api . RepositoryPayload ) ( FeishuPayload , error ) {
2020-12-11 19:04:04 +03:00
var text string
2020-02-12 11:48:28 +03:00
switch p . Action {
case api . HookRepoCreated :
2020-12-11 19:04:04 +03:00
text = fmt . Sprintf ( "[%s] Repository created" , p . Repository . FullName )
return newFeishuTextPayload ( text ) , nil
2020-02-12 11:48:28 +03:00
case api . HookRepoDeleted :
2020-12-11 19:04:04 +03:00
text = fmt . Sprintf ( "[%s] Repository deleted" , p . Repository . FullName )
return newFeishuTextPayload ( text ) , nil
2020-02-12 11:48:28 +03:00
}
2024-03-08 01:18:38 +03:00
return FeishuPayload { } , nil
2020-02-12 11:48:28 +03:00
}
2022-09-04 22:54:23 +03:00
// Wiki implements PayloadConvertor Wiki method
2024-03-08 01:18:38 +03:00
func ( fc feishuConvertor ) Wiki ( p * api . WikiPayload ) ( FeishuPayload , error ) {
2022-09-04 22:54:23 +03:00
text , _ , _ := getWikiPayloadInfo ( p , noneLinkFormatter , true )
return newFeishuTextPayload ( text ) , nil
}
2020-09-05 05:57:13 +03:00
// Release implements PayloadConvertor Release method
2024-03-08 01:18:38 +03:00
func ( fc feishuConvertor ) Release ( p * api . ReleasePayload ) ( FeishuPayload , error ) {
2020-02-12 11:48:28 +03:00
text , _ := getReleasePayloadInfo ( p , noneLinkFormatter , true )
2020-12-11 19:04:04 +03:00
return newFeishuTextPayload ( text ) , nil
2020-02-12 11:48:28 +03:00
}
2024-03-08 01:18:38 +03:00
func ( fc feishuConvertor ) Package ( p * api . PackagePayload ) ( FeishuPayload , error ) {
2023-10-31 07:43:38 +03:00
text , _ := getPackagePayloadInfo ( p , noneLinkFormatter , true )
return newFeishuTextPayload ( text ) , nil
}
2024-03-08 01:18:38 +03:00
type feishuConvertor struct { }
2024-04-03 15:22:36 +03:00
var _ shared . PayloadConvertor [ FeishuPayload ] = feishuConvertor { }
2024-03-08 01:18:38 +03:00
2024-03-20 17:44:01 +03:00
func ( feishuHandler ) NewRequest ( ctx context . Context , w * webhook_model . Webhook , t * webhook_model . HookTask ) ( * http . Request , [ ] byte , error ) {
2024-04-03 15:22:36 +03:00
return shared . NewJSONRequest ( feishuConvertor { } , w , t , true )
2020-02-12 11:48:28 +03:00
}