package workers import ( "bytes" "context" "fmt" "html/template" "os" "path/filepath" "veza-backend-api/internal/email" "go.uber.org/zap" ) // EmailJob représente un job d'envoi d'email type EmailJob struct { To string Subject string Body string Template string // Nom du template (ex: "password_reset") Data map[string]interface{} // Données pour le template } // NewEmailJob crée un nouveau job d'email func NewEmailJob(to, subject, body string) *EmailJob { return &EmailJob{ To: to, Subject: subject, Body: body, Data: make(map[string]interface{}), } } // NewEmailJobWithTemplate crée un job d'email avec template func NewEmailJobWithTemplate(to, subject, templateName string, data map[string]interface{}) *EmailJob { return &EmailJob{ To: to, Subject: subject, Template: templateName, Data: data, } } // Execute exécute le job d'email func (j *EmailJob) Execute(ctx context.Context, sender email.EmailSender, logger *zap.Logger) error { // Si un template est spécifié, le rendre body := j.Body if j.Template != "" { rendered, err := j.renderTemplate(j.Template, j.Data) if err != nil { logger.Error("Failed to render email template", zap.String("template", j.Template), zap.Error(err), ) return fmt.Errorf("failed to render template: %w", err) } body = rendered } // Envoyer l'email if err := sender.Send(j.To, j.Subject, body); err != nil { logger.Error("Failed to send email", zap.String("to", j.To), zap.String("subject", j.Subject), zap.Error(err), ) return fmt.Errorf("failed to send email: %w", err) } logger.Info("Email job executed successfully", zap.String("to", j.To), zap.String("subject", j.Subject), zap.String("template", j.Template), ) return nil } // renderTemplate rend un template email func (j *EmailJob) renderTemplate(templateName string, data map[string]interface{}) (string, error) { // Chercher le template dans templates/email/ templateDir := os.Getenv("EMAIL_TEMPLATE_DIR") if templateDir == "" { templateDir = "templates/email" } templatePath := filepath.Join(templateDir, templateName+".html") // Lire le fichier template tmplContent, err := os.ReadFile(templatePath) if err != nil { return "", fmt.Errorf("failed to read template file %s: %w", templatePath, err) } // Parser le template tmpl, err := template.New(templateName).Parse(string(tmplContent)) if err != nil { return "", fmt.Errorf("failed to parse template: %w", err) } // Rendre le template avec les données var buf bytes.Buffer if err := tmpl.Execute(&buf, data); err != nil { return "", fmt.Errorf("failed to execute template: %w", err) } return buf.String(), nil }