2025-10-29 10:36:36 -04:00

140 lines
4.3 KiB
Go

package email
import (
"fmt"
"github.com/tuusuario/go-sync-service/internal/config"
"github.com/tuusuario/go-sync-service/internal/domain/ports"
"log"
"time"
"github.com/go-playground/validator/v10"
"gopkg.in/gomail.v2"
)
// EmailService define la interfaz para el envío de correos
type EmailService interface {
SendEmail(email EmailRequest) error
}
// SMTPEmailService implementa EmailService con SMTP
type SMTPEmailService struct {
Config *config.Config
Validator *validator.Validate
}
// NewSMTPEmailService retorna una nueva instancia del servicio de email con validación
func NewSMTPEmailService(cfg *config.Config) *SMTPEmailService {
return &SMTPEmailService{
Config: cfg,
Validator: validator.New(), // Inicializa el validador
}
}
// EmailRequest estructura para la validación del email
type EmailRequest struct {
To string `json:"correoElectronico" validate:"required,email"`
Subject string `json:"asunto" validate:"required,min=3,max=100"`
Body string `json:"cuerpo" validate:"required"`
}
// SendEmail valida y envía un correo electrónico usando SMTP
func (s *SMTPEmailService) SendEmail(email EmailRequest) error {
// Validar la estructura antes de enviarla
/*
err := s.Validator.Struct(email)
if err != nil {
for _, err := range err.(validator.ValidationErrors) {
log.Printf("❌ Error de validación en %s: %s", err.Field(), err.Tag())
}
return fmt.Errorf("❌ Error en la validación del email: %v", err)
}
*/
smtpHost := s.Config.EmailHost
smtpPort := s.Config.EmailPort
smtpUser := s.Config.EmailUser
smtpPass := s.Config.EmailPassword
emailFrom := s.Config.EmailFrom
if smtpHost == "" || smtpUser == "" || smtpPass == "" || emailFrom == "" || smtpPort == 0 {
log.Println("❌ ERROR: Faltan variables de entorno para SMTP")
return fmt.Errorf("faltan variables de entorno para el envío de correos")
}
log.Printf("📧 Enviando correo desde: %s", emailFrom)
mail := gomail.NewMessage()
mail.SetHeader("From", emailFrom)
mail.SetHeader("To", email.To)
mail.SetHeader("Subject", email.Subject)
mail.SetBody("text/html", email.Body)
dialer := gomail.NewDialer(smtpHost, smtpPort, smtpUser, smtpPass)
err := dialer.DialAndSend(mail)
if err != nil {
log.Printf("❌ Error enviando correo a %s: %s", email.To, err)
return err
}
log.Printf("✅ Correo enviado con éxito a %s", email.To)
return nil
}
func (s *SMTPEmailService) PrepareEmail(asunto string, mensaje string, cfg ports.RedisConfigProvider) error {
// Validar la estructura antes de enviarla
branding := LoadBrandingAsignation(cfg, s.Config.AppName)
// Cargar destinatarios del entorno
destinos := s.LoadDestinosCorreo(cfg)
// Cargar datos para la plantilla
data := TaskTplData{
AppName: branding.AppName,
Nombre: "Administrador",
TareaNombre: asunto, // Ejemplo
Descripcion: mensaje, // Ejemplo
FechaError: time.Now().Format("02/01/2006 15:04"), // Ejemplo
ErrorDescripcion: mensaje,
LinkTarea: "",
LogoURL: branding.LogoURL,
Direccion: branding.Direccion,
Telefono: branding.Telefono,
EmailContacto: branding.EmailContacto,
Year: branding.Year,
ColorHeaderBG: branding.ColorHeaderBG,
ColorAccent: branding.ColorAccent,
ColorFooterText: branding.ColorFooterText,
ColorFooterMuted: branding.ColorFooterMuted,
ColorBodyBG: branding.ColorBodyBG,
}
// Renderizar el correo
body, err := RenderTaskEmailHTML("", data)
if err != nil {
return fmt.Errorf("error al renderizar la plantilla de tarea: %v", err)
}
// Crear el correo
subject := BuildTaskSubject(branding.AppName)
reqMail := EmailRequest{
To: *destinos, // Usamos la lista de destinos cargada
Subject: subject,
Body: body,
}
// Enviar el correo
if err := s.SendEmail(reqMail); err != nil {
return fmt.Errorf("error al enviar el correo de notificación de tarea: %v", err)
}
return nil
}
// Cargar los correos electrónicos desde la configuración
func (s *SMTPEmailService) LoadDestinosCorreo(cfg ports.RedisConfigProvider) *string {
destinos, err := cfg.GetString("SYNCRONIZADOR_EMAIL_DESTINOS") // Asumiendo que usas RedisConfigProvider
if err != nil {
log.Printf(" ERROR no se pudo cargar la lista de destinatarios: %v", err)
destinos = s.Config.EmailAdmin
}
return &destinos
}