Files

68 lines
1.5 KiB
Go

package mailer
import (
"bytes"
"fmt"
"text/template"
"time"
"github.com/sendgrid/sendgrid-go"
"github.com/sendgrid/sendgrid-go/helpers/mail"
)
type SendGridMailer struct {
fromEmail string
apiKey string
client *sendgrid.Client
}
func NewSendGrid(apiKey, fromEmail string) *SendGridMailer {
client := sendgrid.NewSendClient(apiKey)
return &SendGridMailer{
fromEmail: fromEmail,
apiKey: apiKey,
client: client,
}
}
func (s *SendGridMailer) Send(templateFile, username, email string, data any, isDevEnv bool) (int, error) {
from := mail.NewEmail(FromName, s.fromEmail)
to := mail.NewEmail(username, email)
tmpl, err := template.ParseFS(FS, "templates/"+templateFile)
if err != nil {
return -1, err
}
// Template Parsing and sending
subject := new(bytes.Buffer)
if err := tmpl.ExecuteTemplate(subject, "subject", data); err != nil {
return -1, err
}
body := new(bytes.Buffer)
if err := tmpl.ExecuteTemplate(body, "body", data); err != nil {
return -1, err
}
message := mail.NewSingleEmail(from, subject.String(), to, "", body.String())
message.SetMailSettings(&mail.MailSettings{
SandboxMode: &mail.Setting{
Enable: &isDevEnv,
},
})
var retryErr error
for i := 0; i < maxRetries; i++ {
resp, retryErr := s.client.Send(message)
if retryErr != nil {
//* Exponential backoff
time.Sleep(time.Duration(i+1) * time.Second)
continue
}
return resp.StatusCode, nil
}
return -1, fmt.Errorf("failed to send the email after %d attempts, error: %v", maxRetries, retryErr)
}