code.gitea.io/gitea@v1.21.7/services/mailer/notify.go (about) 1 // Copyright 2019 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package mailer 5 6 import ( 7 "context" 8 "fmt" 9 10 activities_model "code.gitea.io/gitea/models/activities" 11 issues_model "code.gitea.io/gitea/models/issues" 12 repo_model "code.gitea.io/gitea/models/repo" 13 user_model "code.gitea.io/gitea/models/user" 14 "code.gitea.io/gitea/modules/log" 15 notify_service "code.gitea.io/gitea/services/notify" 16 ) 17 18 type mailNotifier struct { 19 notify_service.NullNotifier 20 } 21 22 var _ notify_service.Notifier = &mailNotifier{} 23 24 // NewNotifier create a new mailNotifier notifier 25 func NewNotifier() notify_service.Notifier { 26 return &mailNotifier{} 27 } 28 29 func (m *mailNotifier) CreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, 30 issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User, 31 ) { 32 var act activities_model.ActionType 33 if comment.Type == issues_model.CommentTypeClose { 34 act = activities_model.ActionCloseIssue 35 } else if comment.Type == issues_model.CommentTypeReopen { 36 act = activities_model.ActionReopenIssue 37 } else if comment.Type == issues_model.CommentTypeComment { 38 act = activities_model.ActionCommentIssue 39 } else if comment.Type == issues_model.CommentTypeCode { 40 act = activities_model.ActionCommentIssue 41 } else if comment.Type == issues_model.CommentTypePullRequestPush { 42 act = 0 43 } 44 45 if err := MailParticipantsComment(ctx, comment, act, issue, mentions); err != nil { 46 log.Error("MailParticipantsComment: %v", err) 47 } 48 } 49 50 func (m *mailNotifier) NewIssue(ctx context.Context, issue *issues_model.Issue, mentions []*user_model.User) { 51 if err := MailParticipants(ctx, issue, issue.Poster, activities_model.ActionCreateIssue, mentions); err != nil { 52 log.Error("MailParticipants: %v", err) 53 } 54 } 55 56 func (m *mailNotifier) IssueChangeStatus(ctx context.Context, doer *user_model.User, commitID string, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) { 57 var actionType activities_model.ActionType 58 if issue.IsPull { 59 if isClosed { 60 actionType = activities_model.ActionClosePullRequest 61 } else { 62 actionType = activities_model.ActionReopenPullRequest 63 } 64 } else { 65 if isClosed { 66 actionType = activities_model.ActionCloseIssue 67 } else { 68 actionType = activities_model.ActionReopenIssue 69 } 70 } 71 72 if err := MailParticipants(ctx, issue, doer, actionType, nil); err != nil { 73 log.Error("MailParticipants: %v", err) 74 } 75 } 76 77 func (m *mailNotifier) IssueChangeTitle(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldTitle string) { 78 if err := issue.LoadPullRequest(ctx); err != nil { 79 log.Error("issue.LoadPullRequest: %v", err) 80 return 81 } 82 if issue.IsPull && issues_model.HasWorkInProgressPrefix(oldTitle) && !issue.PullRequest.IsWorkInProgress() { 83 if err := MailParticipants(ctx, issue, doer, activities_model.ActionPullRequestReadyForReview, nil); err != nil { 84 log.Error("MailParticipants: %v", err) 85 } 86 } 87 } 88 89 func (m *mailNotifier) NewPullRequest(ctx context.Context, pr *issues_model.PullRequest, mentions []*user_model.User) { 90 if err := MailParticipants(ctx, pr.Issue, pr.Issue.Poster, activities_model.ActionCreatePullRequest, mentions); err != nil { 91 log.Error("MailParticipants: %v", err) 92 } 93 } 94 95 func (m *mailNotifier) PullRequestReview(ctx context.Context, pr *issues_model.PullRequest, r *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) { 96 var act activities_model.ActionType 97 if comment.Type == issues_model.CommentTypeClose { 98 act = activities_model.ActionCloseIssue 99 } else if comment.Type == issues_model.CommentTypeReopen { 100 act = activities_model.ActionReopenIssue 101 } else if comment.Type == issues_model.CommentTypeComment { 102 act = activities_model.ActionCommentPull 103 } 104 if err := MailParticipantsComment(ctx, comment, act, pr.Issue, mentions); err != nil { 105 log.Error("MailParticipantsComment: %v", err) 106 } 107 } 108 109 func (m *mailNotifier) PullRequestCodeComment(ctx context.Context, pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User) { 110 if err := MailMentionsComment(ctx, pr, comment, mentions); err != nil { 111 log.Error("MailMentionsComment: %v", err) 112 } 113 } 114 115 func (m *mailNotifier) IssueChangeAssignee(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) { 116 // mail only sent to added assignees and not self-assignee 117 if !removed && doer.ID != assignee.ID && assignee.EmailNotifications() != user_model.EmailNotificationsDisabled { 118 ct := fmt.Sprintf("Assigned #%d.", issue.Index) 119 if err := SendIssueAssignedMail(ctx, issue, doer, ct, comment, []*user_model.User{assignee}); err != nil { 120 log.Error("Error in SendIssueAssignedMail for issue[%d] to assignee[%d]: %v", issue.ID, assignee.ID, err) 121 } 122 } 123 } 124 125 func (m *mailNotifier) PullRequestReviewRequest(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) { 126 if isRequest && doer.ID != reviewer.ID && reviewer.EmailNotifications() != user_model.EmailNotificationsDisabled { 127 ct := fmt.Sprintf("Requested to review %s.", issue.HTMLURL()) 128 if err := SendIssueAssignedMail(ctx, issue, doer, ct, comment, []*user_model.User{reviewer}); err != nil { 129 log.Error("Error in SendIssueAssignedMail for issue[%d] to reviewer[%d]: %v", issue.ID, reviewer.ID, err) 130 } 131 } 132 } 133 134 func (m *mailNotifier) MergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) { 135 if err := pr.LoadIssue(ctx); err != nil { 136 log.Error("LoadIssue: %v", err) 137 return 138 } 139 if err := MailParticipants(ctx, pr.Issue, doer, activities_model.ActionMergePullRequest, nil); err != nil { 140 log.Error("MailParticipants: %v", err) 141 } 142 } 143 144 func (m *mailNotifier) AutoMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) { 145 if err := pr.LoadIssue(ctx); err != nil { 146 log.Error("pr.LoadIssue: %v", err) 147 return 148 } 149 if err := MailParticipants(ctx, pr.Issue, doer, activities_model.ActionAutoMergePullRequest, nil); err != nil { 150 log.Error("MailParticipants: %v", err) 151 } 152 } 153 154 func (m *mailNotifier) PullRequestPushCommits(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) { 155 var err error 156 if err = comment.LoadIssue(ctx); err != nil { 157 log.Error("comment.LoadIssue: %v", err) 158 return 159 } 160 if err = comment.Issue.LoadRepo(ctx); err != nil { 161 log.Error("comment.Issue.LoadRepo: %v", err) 162 return 163 } 164 if err = comment.Issue.LoadPullRequest(ctx); err != nil { 165 log.Error("comment.Issue.LoadPullRequest: %v", err) 166 return 167 } 168 if err = comment.Issue.PullRequest.LoadBaseRepo(ctx); err != nil { 169 log.Error("comment.Issue.PullRequest.LoadBaseRepo: %v", err) 170 return 171 } 172 if err := comment.LoadPushCommits(ctx); err != nil { 173 log.Error("comment.LoadPushCommits: %v", err) 174 } 175 m.CreateIssueComment(ctx, doer, comment.Issue.Repo, comment.Issue, comment, nil) 176 } 177 178 func (m *mailNotifier) PullReviewDismiss(ctx context.Context, doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) { 179 if err := comment.Review.LoadReviewer(ctx); err != nil { 180 log.Error("Error in PullReviewDismiss while loading reviewer for issue[%d], review[%d] and reviewer[%d]: %v", review.Issue.ID, comment.Review.ID, comment.Review.ReviewerID, err) 181 } 182 if err := MailParticipantsComment(ctx, comment, activities_model.ActionPullReviewDismissed, review.Issue, nil); err != nil { 183 log.Error("MailParticipantsComment: %v", err) 184 } 185 } 186 187 func (m *mailNotifier) NewRelease(ctx context.Context, rel *repo_model.Release) { 188 if err := rel.LoadAttributes(ctx); err != nil { 189 log.Error("LoadAttributes: %v", err) 190 return 191 } 192 193 if rel.IsDraft || rel.IsPrerelease { 194 return 195 } 196 197 MailNewRelease(ctx, rel) 198 } 199 200 func (m *mailNotifier) RepoPendingTransfer(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository) { 201 if err := SendRepoTransferNotifyMail(ctx, doer, newOwner, repo); err != nil { 202 log.Error("SendRepoTransferNotifyMail: %v", err) 203 } 204 }