1// Copyright 2020 The Gitea Authors. All rights reserved. 2// Use of this source code is governed by a MIT-style 3// license that can be found in the LICENSE file. 4 5package webhook 6 7import ( 8 "fmt" 9 "strings" 10 11 webhook_model "code.gitea.io/gitea/models/webhook" 12 "code.gitea.io/gitea/modules/git" 13 "code.gitea.io/gitea/modules/json" 14 api "code.gitea.io/gitea/modules/structs" 15) 16 17type ( 18 // FeishuPayload represents 19 FeishuPayload struct { 20 MsgType string `json:"msg_type"` // text / post / image / share_chat / interactive 21 Content struct { 22 Text string `json:"text"` 23 } `json:"content"` 24 } 25) 26 27func newFeishuTextPayload(text string) *FeishuPayload { 28 return &FeishuPayload{ 29 MsgType: "text", 30 Content: struct { 31 Text string `json:"text"` 32 }{ 33 Text: strings.TrimSpace(text), 34 }, 35 } 36} 37 38// JSONPayload Marshals the FeishuPayload to json 39func (f *FeishuPayload) JSONPayload() ([]byte, error) { 40 data, err := json.MarshalIndent(f, "", " ") 41 if err != nil { 42 return []byte{}, err 43 } 44 return data, nil 45} 46 47var ( 48 _ PayloadConvertor = &FeishuPayload{} 49) 50 51// Create implements PayloadConvertor Create method 52func (f *FeishuPayload) Create(p *api.CreatePayload) (api.Payloader, error) { 53 // created tag/branch 54 refName := git.RefEndName(p.Ref) 55 text := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName) 56 57 return newFeishuTextPayload(text), nil 58} 59 60// Delete implements PayloadConvertor Delete method 61func (f *FeishuPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { 62 // created tag/branch 63 refName := git.RefEndName(p.Ref) 64 text := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName) 65 66 return newFeishuTextPayload(text), nil 67} 68 69// Fork implements PayloadConvertor Fork method 70func (f *FeishuPayload) Fork(p *api.ForkPayload) (api.Payloader, error) { 71 text := fmt.Sprintf("%s is forked to %s", p.Forkee.FullName, p.Repo.FullName) 72 73 return newFeishuTextPayload(text), nil 74} 75 76// Push implements PayloadConvertor Push method 77func (f *FeishuPayload) Push(p *api.PushPayload) (api.Payloader, error) { 78 var ( 79 branchName = git.RefEndName(p.Ref) 80 commitDesc string 81 ) 82 83 var text = fmt.Sprintf("[%s:%s] %s\r\n", p.Repo.FullName, branchName, commitDesc) 84 // for each commit, generate attachment text 85 for i, commit := range p.Commits { 86 var authorName string 87 if commit.Author != nil { 88 authorName = " - " + commit.Author.Name 89 } 90 text += fmt.Sprintf("[%s](%s) %s", commit.ID[:7], commit.URL, 91 strings.TrimRight(commit.Message, "\r\n")) + authorName 92 // add linebreak to each commit but the last 93 if i < len(p.Commits)-1 { 94 text += "\r\n" 95 } 96 } 97 98 return newFeishuTextPayload(text), nil 99} 100 101// Issue implements PayloadConvertor Issue method 102func (f *FeishuPayload) Issue(p *api.IssuePayload) (api.Payloader, error) { 103 text, issueTitle, attachmentText, _ := getIssuesPayloadInfo(p, noneLinkFormatter, true) 104 105 return newFeishuTextPayload(issueTitle + "\r\n" + text + "\r\n\r\n" + attachmentText), nil 106} 107 108// IssueComment implements PayloadConvertor IssueComment method 109func (f *FeishuPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloader, error) { 110 text, issueTitle, _ := getIssueCommentPayloadInfo(p, noneLinkFormatter, true) 111 112 return newFeishuTextPayload(issueTitle + "\r\n" + text + "\r\n\r\n" + p.Comment.Body), nil 113} 114 115// PullRequest implements PayloadConvertor PullRequest method 116func (f *FeishuPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader, error) { 117 text, issueTitle, attachmentText, _ := getPullRequestPayloadInfo(p, noneLinkFormatter, true) 118 119 return newFeishuTextPayload(issueTitle + "\r\n" + text + "\r\n\r\n" + attachmentText), nil 120} 121 122// Review implements PayloadConvertor Review method 123func (f *FeishuPayload) Review(p *api.PullRequestPayload, event webhook_model.HookEventType) (api.Payloader, error) { 124 action, err := parseHookPullRequestEventType(event) 125 if err != nil { 126 return nil, err 127 } 128 129 title := fmt.Sprintf("[%s] Pull request review %s : #%d %s", p.Repository.FullName, action, p.Index, p.PullRequest.Title) 130 text := p.Review.Content 131 132 return newFeishuTextPayload(title + "\r\n\r\n" + text), nil 133} 134 135// Repository implements PayloadConvertor Repository method 136func (f *FeishuPayload) Repository(p *api.RepositoryPayload) (api.Payloader, error) { 137 var text string 138 switch p.Action { 139 case api.HookRepoCreated: 140 text = fmt.Sprintf("[%s] Repository created", p.Repository.FullName) 141 return newFeishuTextPayload(text), nil 142 case api.HookRepoDeleted: 143 text = fmt.Sprintf("[%s] Repository deleted", p.Repository.FullName) 144 return newFeishuTextPayload(text), nil 145 } 146 147 return nil, nil 148} 149 150// Release implements PayloadConvertor Release method 151func (f *FeishuPayload) Release(p *api.ReleasePayload) (api.Payloader, error) { 152 text, _ := getReleasePayloadInfo(p, noneLinkFormatter, true) 153 154 return newFeishuTextPayload(text), nil 155} 156 157// GetFeishuPayload converts a ding talk webhook into a FeishuPayload 158func GetFeishuPayload(p api.Payloader, event webhook_model.HookEventType, meta string) (api.Payloader, error) { 159 return convertPayloader(new(FeishuPayload), p, event) 160} 161