119 lines
3 KiB
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"),
|
|
}
|
|
}
|