2024-03-31 18:23:50 +00:00
|
|
|
package clients
|
2024-03-31 20:04:15 +00:00
|
|
|
|
|
|
|
import (
|
2024-04-01 14:41:53 +00:00
|
|
|
"bytes"
|
|
|
|
"fmt"
|
2024-03-31 20:04:15 +00:00
|
|
|
"github.com/gofiber/fiber/v2"
|
|
|
|
"go.uber.org/zap"
|
2024-04-01 14:41:53 +00:00
|
|
|
"html/template"
|
|
|
|
"mime/multipart"
|
|
|
|
"os"
|
2024-03-31 20:04:15 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type Deps struct {
|
|
|
|
SmtpApiUrl string
|
|
|
|
SmtpHost string
|
|
|
|
SmtpPort string
|
|
|
|
SmtpSender string
|
|
|
|
Username string
|
|
|
|
Password string
|
|
|
|
ApiKey string
|
|
|
|
FiberClient *fiber.Client
|
|
|
|
Logger *zap.Logger
|
|
|
|
}
|
|
|
|
|
|
|
|
type MailClient struct {
|
|
|
|
deps Deps
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewMailClient(deps Deps) *MailClient {
|
|
|
|
if deps.FiberClient == nil {
|
|
|
|
deps.FiberClient = fiber.AcquireClient()
|
|
|
|
}
|
|
|
|
return &MailClient{
|
|
|
|
deps: deps,
|
|
|
|
}
|
|
|
|
}
|
2024-04-01 14:41:53 +00:00
|
|
|
|
|
|
|
type SenderDeps struct {
|
|
|
|
Subject string
|
|
|
|
Email string
|
|
|
|
TmplPath string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *MailClient) MailSender(data SenderDeps) error {
|
|
|
|
tmplContent, err := os.ReadFile(data.TmplPath)
|
|
|
|
if err != nil {
|
|
|
|
m.deps.Logger.Error("Error reading template file", zap.Error(err))
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
tmpl, err := template.New("email").Parse(string(tmplContent))
|
|
|
|
if err != nil {
|
|
|
|
m.deps.Logger.Error("Error parsing HTML template", zap.Error(err))
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
var buf bytes.Buffer
|
|
|
|
if err := tmpl.Execute(&buf, nil); err != nil {
|
|
|
|
m.deps.Logger.Error("Error executing template", zap.Error(err))
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
htmlBody := buf.String()
|
|
|
|
|
|
|
|
form := new(bytes.Buffer)
|
|
|
|
writer := multipart.NewWriter(form)
|
|
|
|
defer writer.Close()
|
|
|
|
|
|
|
|
fields := map[string]string{
|
|
|
|
"from": m.deps.SmtpSender,
|
|
|
|
"to": data.Email,
|
|
|
|
"subject": data.Subject,
|
|
|
|
"html": htmlBody,
|
|
|
|
}
|
|
|
|
|
|
|
|
for key, value := range fields {
|
|
|
|
if err := writer.WriteField(key, value); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := writer.Close(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
req := m.deps.FiberClient.Post(m.deps.SmtpApiUrl).Body(form.Bytes()).ContentType(writer.FormDataContentType())
|
|
|
|
if m.deps.ApiKey != "" {
|
|
|
|
req.Set("Authorization", m.deps.ApiKey)
|
|
|
|
}
|
|
|
|
|
|
|
|
statusCode, body, errs := req.Bytes()
|
|
|
|
if errs != nil {
|
|
|
|
m.deps.Logger.Error("Error sending request", zap.Error(errs[0]))
|
|
|
|
return errs[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
if statusCode != fiber.StatusOK {
|
|
|
|
err := fmt.Errorf("the SMTP service returned an error: %s Response body: %s", statusCode, body)
|
|
|
|
m.deps.Logger.Error("Error sending email", zap.Error(err))
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|