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.

feishu.go 6.0KB

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