drone/app/services/notification/mail_client.go
2024-03-15 20:54:25 +00:00

222 lines
5.6 KiB
Go

// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package notification
import (
"bytes"
"context"
"fmt"
pullreqevents "github.com/harness/gitness/app/events/pullreq"
"github.com/harness/gitness/app/services/notification/mailer"
"github.com/harness/gitness/types"
)
const (
TemplateReviewerAdded = "reviewer_added.html"
TemplateCommentPRAuthor = "comment_pr_author.html"
TemplateCommentMentions = "comment_mentions.html"
TemplateCommentParticipants = "comment_participants.html"
TemplatePullReqBranchUpdated = "pullreq_branch_updated.html"
TemplateNameReviewSubmitted = "review_submitted.html"
TemplatePullReqStateChanged = "pullreq_state_changed.html"
)
type MailClient struct {
mailer.Mailer
}
func NewMailClient(mailer mailer.Mailer) MailClient {
return MailClient{
Mailer: mailer,
}
}
func (m MailClient) SendCommentPRAuthor(
ctx context.Context,
recipients []*types.PrincipalInfo,
payload *CommentPayload,
) error {
email, err := GenerateEmailFromPayload(
TemplateCommentPRAuthor,
recipients,
payload.Base,
payload,
)
if err != nil {
return fmt.Errorf("failed to generate mail requests after processing %s event: %w",
pullreqevents.CommentCreatedEvent, err)
}
return m.Mailer.Send(ctx, *email)
}
func (m MailClient) SendCommentMentions(
ctx context.Context,
recipients []*types.PrincipalInfo,
payload *CommentPayload,
) error {
email, err := GenerateEmailFromPayload(
TemplateCommentMentions,
recipients,
payload.Base,
payload,
)
if err != nil {
return fmt.Errorf("failed to generate mail requests after processing %s event: %w",
pullreqevents.CommentCreatedEvent, err)
}
return m.Mailer.Send(ctx, *email)
}
func (m MailClient) SendCommentParticipants(
ctx context.Context,
recipients []*types.PrincipalInfo,
payload *CommentPayload,
) error {
email, err := GenerateEmailFromPayload(
TemplateCommentParticipants,
recipients,
payload.Base,
payload,
)
if err != nil {
return fmt.Errorf("failed to generate mail requests after processing %s event: %w",
pullreqevents.CommentCreatedEvent, err)
}
return m.Mailer.Send(ctx, *email)
}
func (m MailClient) SendReviewerAdded(
ctx context.Context,
recipients []*types.PrincipalInfo,
payload *ReviewerAddedPayload,
) error {
email, err := GenerateEmailFromPayload(
TemplateReviewerAdded,
recipients,
payload.Base,
payload,
)
if err != nil {
return fmt.Errorf("failed to generate mail requests after processing %s event: %w",
pullreqevents.ReviewerAddedEvent, err)
}
return m.Mailer.Send(ctx, *email)
}
func (m MailClient) SendPullReqBranchUpdated(
ctx context.Context,
recipients []*types.PrincipalInfo,
payload *PullReqBranchUpdatedPayload,
) error {
email, err := GenerateEmailFromPayload(
TemplatePullReqBranchUpdated,
recipients,
payload.Base,
payload,
)
if err != nil {
return fmt.Errorf("failed to generate mail requests after processing %s event: %w",
pullreqevents.BranchUpdatedEvent, err)
}
return m.Mailer.Send(ctx, *email)
}
func (m MailClient) SendReviewSubmitted(
ctx context.Context,
recipients []*types.PrincipalInfo,
payload *ReviewSubmittedPayload,
) error {
email, err := GenerateEmailFromPayload(TemplateNameReviewSubmitted, recipients, payload.Base, payload)
if err != nil {
return fmt.Errorf(
"failed to generate mail requests after processing %s event: %w",
pullreqevents.ReviewSubmittedEvent,
err,
)
}
return m.Mailer.Send(ctx, *email)
}
func (m MailClient) SendPullReqStateChanged(
ctx context.Context,
recipients []*types.PrincipalInfo,
payload *PullReqStateChangedPayload,
) error {
email, err := GenerateEmailFromPayload(TemplatePullReqStateChanged, recipients, payload.Base, payload)
if err != nil {
return fmt.Errorf(
"failed to generate mail requests after processing pullReqState change event: %w",
err,
)
}
return m.Mailer.Send(ctx, *email)
}
func GetSubjectPullRequest(
repoIdentifier string,
prNum int64,
prTitle string,
) string {
return fmt.Sprintf(subjectPullReqEvent, repoIdentifier, prTitle, prNum)
}
func GetHTMLBody(templateName string, data interface{}) ([]byte, error) {
tmpl := htmlTemplates[templateName]
tmplOutput := bytes.Buffer{}
err := tmpl.Execute(&tmplOutput, data)
if err != nil {
return nil, fmt.Errorf("failed to execute template %s", templateName)
}
return tmplOutput.Bytes(), nil
}
func GenerateEmailFromPayload(
templateName string,
recipients []*types.PrincipalInfo,
base *BasePullReqPayload,
payload interface{},
) (*mailer.Payload, error) {
subject := GetSubjectPullRequest(base.Repo.Identifier, base.PullReq.Number,
base.PullReq.Title)
body, err := GetHTMLBody(templateName, payload)
if err != nil {
return nil, err
}
var email mailer.Payload
email.Body = string(body)
email.Subject = subject
email.RepoRef = base.Repo.Path
recipientEmails := RetrieveEmailsFromPrincipals(recipients)
email.ToRecipients = recipientEmails
return &email, nil
}
func RetrieveEmailsFromPrincipals(principals []*types.PrincipalInfo) []string {
emails := make([]string, len(principals))
for i, principal := range principals {
emails[i] = principal.Email
}
return emails
}