code.gitea.io/gitea@v1.21.7/services/webhook/telegram.go (about) 1 // Copyright 2019 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package webhook 5 6 import ( 7 "fmt" 8 "strings" 9 10 webhook_model "code.gitea.io/gitea/models/webhook" 11 "code.gitea.io/gitea/modules/git" 12 "code.gitea.io/gitea/modules/json" 13 "code.gitea.io/gitea/modules/log" 14 "code.gitea.io/gitea/modules/markup" 15 api "code.gitea.io/gitea/modules/structs" 16 webhook_module "code.gitea.io/gitea/modules/webhook" 17 ) 18 19 type ( 20 // TelegramPayload represents 21 TelegramPayload struct { 22 Message string `json:"text"` 23 ParseMode string `json:"parse_mode"` 24 DisableWebPreview bool `json:"disable_web_page_preview"` 25 } 26 27 // TelegramMeta contains the telegram metadata 28 TelegramMeta struct { 29 BotToken string `json:"bot_token"` 30 ChatID string `json:"chat_id"` 31 ThreadID string `json:"thread_id"` 32 } 33 ) 34 35 // GetTelegramHook returns telegram metadata 36 func GetTelegramHook(w *webhook_model.Webhook) *TelegramMeta { 37 s := &TelegramMeta{} 38 if err := json.Unmarshal([]byte(w.Meta), s); err != nil { 39 log.Error("webhook.GetTelegramHook(%d): %v", w.ID, err) 40 } 41 return s 42 } 43 44 var _ PayloadConvertor = &TelegramPayload{} 45 46 // JSONPayload Marshals the TelegramPayload to json 47 func (t *TelegramPayload) JSONPayload() ([]byte, error) { 48 t.ParseMode = "HTML" 49 t.DisableWebPreview = true 50 t.Message = markup.Sanitize(t.Message) 51 data, err := json.MarshalIndent(t, "", " ") 52 if err != nil { 53 return []byte{}, err 54 } 55 return data, nil 56 } 57 58 // Create implements PayloadConvertor Create method 59 func (t *TelegramPayload) Create(p *api.CreatePayload) (api.Payloader, error) { 60 // created tag/branch 61 refName := git.RefName(p.Ref).ShortName() 62 title := fmt.Sprintf(`[<a href="%s">%s</a>] %s <a href="%s">%s</a> created`, p.Repo.HTMLURL, p.Repo.FullName, p.RefType, 63 p.Repo.HTMLURL+"/src/"+refName, refName) 64 65 return createTelegramPayload(title), nil 66 } 67 68 // Delete implements PayloadConvertor Delete method 69 func (t *TelegramPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { 70 // created tag/branch 71 refName := git.RefName(p.Ref).ShortName() 72 title := fmt.Sprintf(`[<a href="%s">%s</a>] %s <a href="%s">%s</a> deleted`, p.Repo.HTMLURL, p.Repo.FullName, p.RefType, 73 p.Repo.HTMLURL+"/src/"+refName, refName) 74 75 return createTelegramPayload(title), nil 76 } 77 78 // Fork implements PayloadConvertor Fork method 79 func (t *TelegramPayload) Fork(p *api.ForkPayload) (api.Payloader, error) { 80 title := fmt.Sprintf(`%s is forked to <a href="%s">%s</a>`, p.Forkee.FullName, p.Repo.HTMLURL, p.Repo.FullName) 81 82 return createTelegramPayload(title), nil 83 } 84 85 // Push implements PayloadConvertor Push method 86 func (t *TelegramPayload) Push(p *api.PushPayload) (api.Payloader, error) { 87 var ( 88 branchName = git.RefName(p.Ref).ShortName() 89 commitDesc string 90 ) 91 92 var titleLink string 93 if p.TotalCommits == 1 { 94 commitDesc = "1 new commit" 95 titleLink = p.Commits[0].URL 96 } else { 97 commitDesc = fmt.Sprintf("%d new commits", p.TotalCommits) 98 titleLink = p.CompareURL 99 } 100 if titleLink == "" { 101 titleLink = p.Repo.HTMLURL + "/src/" + branchName 102 } 103 title := fmt.Sprintf(`[<a href="%s">%s</a>:<a href="%s">%s</a>] %s`, p.Repo.HTMLURL, p.Repo.FullName, titleLink, branchName, commitDesc) 104 105 var text string 106 // for each commit, generate attachment text 107 for i, commit := range p.Commits { 108 var authorName string 109 if commit.Author != nil { 110 authorName = " - " + commit.Author.Name 111 } 112 text += fmt.Sprintf(`[<a href="%s">%s</a>] %s`, commit.URL, commit.ID[:7], 113 strings.TrimRight(commit.Message, "\r\n")) + authorName 114 // add linebreak to each commit but the last 115 if i < len(p.Commits)-1 { 116 text += "\n" 117 } 118 } 119 120 return createTelegramPayload(title + "\n" + text), nil 121 } 122 123 // Issue implements PayloadConvertor Issue method 124 func (t *TelegramPayload) Issue(p *api.IssuePayload) (api.Payloader, error) { 125 text, _, attachmentText, _ := getIssuesPayloadInfo(p, htmlLinkFormatter, true) 126 127 return createTelegramPayload(text + "\n\n" + attachmentText), nil 128 } 129 130 // IssueComment implements PayloadConvertor IssueComment method 131 func (t *TelegramPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloader, error) { 132 text, _, _ := getIssueCommentPayloadInfo(p, htmlLinkFormatter, true) 133 134 return createTelegramPayload(text + "\n" + p.Comment.Body), nil 135 } 136 137 // PullRequest implements PayloadConvertor PullRequest method 138 func (t *TelegramPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader, error) { 139 text, _, attachmentText, _ := getPullRequestPayloadInfo(p, htmlLinkFormatter, true) 140 141 return createTelegramPayload(text + "\n" + attachmentText), nil 142 } 143 144 // Review implements PayloadConvertor Review method 145 func (t *TelegramPayload) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (api.Payloader, error) { 146 var text, attachmentText string 147 switch p.Action { 148 case api.HookIssueReviewed: 149 action, err := parseHookPullRequestEventType(event) 150 if err != nil { 151 return nil, err 152 } 153 154 text = fmt.Sprintf("[%s] Pull request review %s: #%d %s", p.Repository.FullName, action, p.Index, p.PullRequest.Title) 155 attachmentText = p.Review.Content 156 } 157 158 return createTelegramPayload(text + "\n" + attachmentText), nil 159 } 160 161 // Repository implements PayloadConvertor Repository method 162 func (t *TelegramPayload) Repository(p *api.RepositoryPayload) (api.Payloader, error) { 163 var title string 164 switch p.Action { 165 case api.HookRepoCreated: 166 title = fmt.Sprintf(`[<a href="%s">%s</a>] Repository created`, p.Repository.HTMLURL, p.Repository.FullName) 167 return createTelegramPayload(title), nil 168 case api.HookRepoDeleted: 169 title = fmt.Sprintf("[%s] Repository deleted", p.Repository.FullName) 170 return createTelegramPayload(title), nil 171 } 172 return nil, nil 173 } 174 175 // Wiki implements PayloadConvertor Wiki method 176 func (t *TelegramPayload) Wiki(p *api.WikiPayload) (api.Payloader, error) { 177 text, _, _ := getWikiPayloadInfo(p, htmlLinkFormatter, true) 178 179 return createTelegramPayload(text), nil 180 } 181 182 // Release implements PayloadConvertor Release method 183 func (t *TelegramPayload) Release(p *api.ReleasePayload) (api.Payloader, error) { 184 text, _ := getReleasePayloadInfo(p, htmlLinkFormatter, true) 185 186 return createTelegramPayload(text), nil 187 } 188 189 func (t *TelegramPayload) Package(p *api.PackagePayload) (api.Payloader, error) { 190 text, _ := getPackagePayloadInfo(p, htmlLinkFormatter, true) 191 192 return createTelegramPayload(text), nil 193 } 194 195 // GetTelegramPayload converts a telegram webhook into a TelegramPayload 196 func GetTelegramPayload(p api.Payloader, event webhook_module.HookEventType, _ string) (api.Payloader, error) { 197 return convertPayloader(new(TelegramPayload), p, event) 198 } 199 200 func createTelegramPayload(message string) *TelegramPayload { 201 return &TelegramPayload{ 202 Message: strings.TrimSpace(message), 203 } 204 }