code.gitea.io/gitea@v1.21.7/services/webhook/feishu.go (about)

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