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