veza/veza-backend-api/internal/email/sender.go

119 lines
3 KiB
Go

package email
import (
"fmt"
"net/smtp"
"os"
"go.uber.org/zap"
)
// EmailSender interface pour l'envoi d'emails
type EmailSender interface {
Send(to, subject, body string) error
SendTemplate(to, template string, data map[string]interface{}) error
}
// SMTPConfig contient la configuration SMTP
type SMTPConfig struct {
Host string
Port string
Username string
Password string
From string
FromName string
}
// SMTPEmailSender implémente EmailSender avec SMTP réel
type SMTPEmailSender struct {
config SMTPConfig
logger *zap.Logger
}
// NewSMTPEmailSender crée un nouveau sender SMTP
func NewSMTPEmailSender(config SMTPConfig, logger *zap.Logger) *SMTPEmailSender {
return &SMTPEmailSender{
config: config,
logger: logger,
}
}
// Send envoie un email via SMTP
func (s *SMTPEmailSender) Send(to, subject, body string) error {
// Si pas de config SMTP, log seulement (dev mode)
if s.config.Host == "" {
s.logger.Info("SMTP not configured, email would be sent",
zap.String("to", to),
zap.String("subject", subject),
)
return nil
}
// SMTP auth
auth := smtp.PlainAuth("", s.config.Username, s.config.Password, s.config.Host)
// Email headers avec format correct
fromHeader := s.config.From
if s.config.FromName != "" {
fromHeader = fmt.Sprintf("%s <%s>", s.config.FromName, s.config.From)
}
msg := []byte(fmt.Sprintf("From: %s\r\n"+
"To: %s\r\n"+
"Subject: %s\r\n"+
"MIME-Version: 1.0\r\n"+
"Content-Type: text/html; charset=UTF-8\r\n"+
"\r\n"+
"%s", fromHeader, to, subject, body))
// Send email
addr := fmt.Sprintf("%s:%s", s.config.Host, s.config.Port)
err := smtp.SendMail(addr, auth, s.config.From, []string{to}, msg)
if err != nil {
return fmt.Errorf("failed to send email via SMTP: %w", err)
}
s.logger.Info("Email sent successfully",
zap.String("to", to),
zap.String("subject", subject),
)
return nil
}
// SendTemplate envoie un email avec un template
// Pour l'instant, cette méthode appelle Send avec le body généré
// L'implémentation complète avec template engine sera dans email_job.go
func (s *SMTPEmailSender) SendTemplate(to, template string, data map[string]interface{}) error {
// Cette méthode sera utilisée par EmailJob qui gère le rendu des templates
// Pour l'instant, on délègue au template renderer
return fmt.Errorf("SendTemplate not implemented directly, use EmailJob instead")
}
// LoadSMTPConfigFromEnv charge la config SMTP depuis les variables d'environnement
func LoadSMTPConfigFromEnv() SMTPConfig {
// En dev, fallback sur MailHog si pas de config
host := os.Getenv("SMTP_HOST")
port := os.Getenv("SMTP_PORT")
if host == "" {
host = os.Getenv("MAILHOG_HOST")
if host == "" {
host = "localhost"
}
}
if port == "" {
port = os.Getenv("MAILHOG_PORT")
if port == "" {
port = "1025" // MailHog default
}
}
return SMTPConfig{
Host: host,
Port: port,
Username: os.Getenv("SMTP_USERNAME"),
Password: os.Getenv("SMTP_PASSWORD"),
From: os.Getenv("SMTP_FROM"),
FromName: os.Getenv("SMTP_FROM_NAME"),
}
}