140 lines
4.3 KiB
Go
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
|
|
}
|