package mailer import ( "bytes" "fmt" "net/smtp" "text/template" "github.com/jordan-wright/email" ) const ( smtpAuthAddress = "smtp.gmail.com" smtpServerAddress = "smtp.gmail.com:587" ) type GmailSender struct { name string fromEmailAddress string fromEmailPassword string } func NewGmailSender(name, fromEmailAddress, fromEmailPassword string) MailSender { return &GmailSender{ name: name, fromEmailAddress: fromEmailAddress, fromEmailPassword: fromEmailPassword, } } func (s *GmailSender) Send( mailTemplate string, vars any, to []string, cc []string, bcc []string, attachFiles []string, ) error { e := email.NewEmail() e.From = fmt.Sprintf("%s <%s>", s.name, s.fromEmailAddress) e.To = to e.Cc = cc e.Bcc = bcc tmpl, err := template.ParseFS(FS, "templates/"+mailTemplate) if err != nil { return fmt.Errorf("failed to parse email template: %w", err) } subject := new(bytes.Buffer) if err := tmpl.ExecuteTemplate(subject, "subject", vars); err != nil { return fmt.Errorf("failed to execute subject template: %w", err) } body := new(bytes.Buffer) if err := tmpl.ExecuteTemplate(body, "body", vars); err != nil { return fmt.Errorf("failed to execute body template: %w", err) } e.Subject = subject.String() e.HTML = body.Bytes() for _, file := range attachFiles { _, err := e.AttachFile(file) if err != nil { return fmt.Errorf("failed to attach file %s: %w", file, err) } } smtpAuth := smtp.PlainAuth("", s.fromEmailAddress, s.fromEmailPassword, smtpAuthAddress) return e.Send(smtpServerAddress, smtpAuth) }