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"), } }