You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

205 lines
5.5 KiB

  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. package webhook
  5. import (
  6. "encoding/json"
  7. "fmt"
  8. "strings"
  9. "code.gitea.io/gitea/models"
  10. "code.gitea.io/gitea/modules/git"
  11. api "code.gitea.io/gitea/modules/structs"
  12. )
  13. type (
  14. // FeishuPayload represents
  15. FeishuPayload struct {
  16. Title string `json:"title"`
  17. Text string `json:"text"`
  18. }
  19. )
  20. // SetSecret sets the Feishu secret
  21. func (p *FeishuPayload) SetSecret(_ string) {}
  22. // JSONPayload Marshals the FeishuPayload to json
  23. func (p *FeishuPayload) JSONPayload() ([]byte, error) {
  24. data, err := json.MarshalIndent(p, "", " ")
  25. if err != nil {
  26. return []byte{}, err
  27. }
  28. return data, nil
  29. }
  30. func getFeishuCreatePayload(p *api.CreatePayload) (*FeishuPayload, error) {
  31. // created tag/branch
  32. refName := git.RefEndName(p.Ref)
  33. title := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName)
  34. return &FeishuPayload{
  35. Text: title,
  36. Title: title,
  37. }, nil
  38. }
  39. func getFeishuDeletePayload(p *api.DeletePayload) (*FeishuPayload, error) {
  40. // created tag/branch
  41. refName := git.RefEndName(p.Ref)
  42. title := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName)
  43. return &FeishuPayload{
  44. Text: title,
  45. Title: title,
  46. }, nil
  47. }
  48. func getFeishuForkPayload(p *api.ForkPayload) (*FeishuPayload, error) {
  49. title := fmt.Sprintf("%s is forked to %s", p.Forkee.FullName, p.Repo.FullName)
  50. return &FeishuPayload{
  51. Text: title,
  52. Title: title,
  53. }, nil
  54. }
  55. func getFeishuPushPayload(p *api.PushPayload) (*FeishuPayload, error) {
  56. var (
  57. branchName = git.RefEndName(p.Ref)
  58. commitDesc string
  59. )
  60. title := fmt.Sprintf("[%s:%s] %s", p.Repo.FullName, branchName, commitDesc)
  61. var text string
  62. // for each commit, generate attachment text
  63. for i, commit := range p.Commits {
  64. var authorName string
  65. if commit.Author != nil {
  66. authorName = " - " + commit.Author.Name
  67. }
  68. text += fmt.Sprintf("[%s](%s) %s", commit.ID[:7], commit.URL,
  69. strings.TrimRight(commit.Message, "\r\n")) + authorName
  70. // add linebreak to each commit but the last
  71. if i < len(p.Commits)-1 {
  72. text += "\n"
  73. }
  74. }
  75. return &FeishuPayload{
  76. Text: text,
  77. Title: title,
  78. }, nil
  79. }
  80. func getFeishuIssuesPayload(p *api.IssuePayload) (*FeishuPayload, error) {
  81. text, issueTitle, attachmentText, _ := getIssuesPayloadInfo(p, noneLinkFormatter, true)
  82. return &FeishuPayload{
  83. Text: text + "\r\n\r\n" + attachmentText,
  84. Title: issueTitle,
  85. }, nil
  86. }
  87. func getFeishuIssueCommentPayload(p *api.IssueCommentPayload) (*FeishuPayload, error) {
  88. text, issueTitle, _ := getIssueCommentPayloadInfo(p, noneLinkFormatter, true)
  89. return &FeishuPayload{
  90. Text: text + "\r\n\r\n" + p.Comment.Body,
  91. Title: issueTitle,
  92. }, nil
  93. }
  94. func getFeishuPullRequestPayload(p *api.PullRequestPayload) (*FeishuPayload, error) {
  95. text, issueTitle, attachmentText, _ := getPullRequestPayloadInfo(p, noneLinkFormatter, true)
  96. return &FeishuPayload{
  97. Text: text + "\r\n\r\n" + attachmentText,
  98. Title: issueTitle,
  99. }, nil
  100. }
  101. func getFeishuPullRequestApprovalPayload(p *api.PullRequestPayload, event models.HookEventType) (*FeishuPayload, error) {
  102. var text, title string
  103. switch p.Action {
  104. case api.HookIssueSynchronized:
  105. action, err := parseHookPullRequestEventType(event)
  106. if err != nil {
  107. return nil, err
  108. }
  109. title = fmt.Sprintf("[%s] Pull request review %s : #%d %s", p.Repository.FullName, action, p.Index, p.PullRequest.Title)
  110. text = p.Review.Content
  111. }
  112. return &FeishuPayload{
  113. Text: title + "\r\n\r\n" + text,
  114. Title: title,
  115. }, nil
  116. }
  117. func getFeishuRepositoryPayload(p *api.RepositoryPayload) (*FeishuPayload, error) {
  118. var title string
  119. switch p.Action {
  120. case api.HookRepoCreated:
  121. title = fmt.Sprintf("[%s] Repository created", p.Repository.FullName)
  122. return &FeishuPayload{
  123. Text: title,
  124. Title: title,
  125. }, nil
  126. case api.HookRepoDeleted:
  127. title = fmt.Sprintf("[%s] Repository deleted", p.Repository.FullName)
  128. return &FeishuPayload{
  129. Title: title,
  130. Text: title,
  131. }, nil
  132. }
  133. return nil, nil
  134. }
  135. func getFeishuReleasePayload(p *api.ReleasePayload) (*FeishuPayload, error) {
  136. text, _ := getReleasePayloadInfo(p, noneLinkFormatter, true)
  137. return &FeishuPayload{
  138. Text: text,
  139. Title: text,
  140. }, nil
  141. }
  142. // GetFeishuPayload converts a ding talk webhook into a FeishuPayload
  143. func GetFeishuPayload(p api.Payloader, event models.HookEventType, meta string) (*FeishuPayload, error) {
  144. s := new(FeishuPayload)
  145. switch event {
  146. case models.HookEventCreate:
  147. return getFeishuCreatePayload(p.(*api.CreatePayload))
  148. case models.HookEventDelete:
  149. return getFeishuDeletePayload(p.(*api.DeletePayload))
  150. case models.HookEventFork:
  151. return getFeishuForkPayload(p.(*api.ForkPayload))
  152. case models.HookEventIssues:
  153. return getFeishuIssuesPayload(p.(*api.IssuePayload))
  154. case models.HookEventIssueComment, models.HookEventPullRequestComment:
  155. pl, ok := p.(*api.IssueCommentPayload)
  156. if ok {
  157. return getFeishuIssueCommentPayload(pl)
  158. }
  159. return getFeishuPullRequestPayload(p.(*api.PullRequestPayload))
  160. case models.HookEventPush:
  161. return getFeishuPushPayload(p.(*api.PushPayload))
  162. case models.HookEventPullRequest:
  163. return getFeishuPullRequestPayload(p.(*api.PullRequestPayload))
  164. case models.HookEventPullRequestReviewApproved, models.HookEventPullRequestReviewRejected:
  165. return getFeishuPullRequestApprovalPayload(p.(*api.PullRequestPayload), event)
  166. case models.HookEventRepository:
  167. return getFeishuRepositoryPayload(p.(*api.RepositoryPayload))
  168. case models.HookEventRelease:
  169. return getFeishuReleasePayload(p.(*api.ReleasePayload))
  170. }
  171. return s, nil
  172. }