package services import ( "fmt" "log" "time" "github.com/gofiber/fiber/v2" "github.com/sujit-baniya/fiber-boilerplate/app" "github.com/sujit-baniya/fiber-boilerplate/utils" ) func SendPasswordResetEmail(email string, baseURL string) { // Generar un identificador único para el correo de restablecimiento resetEmail := fmt.Sprintf("%s-reset-%d", email, time.Now().Unix()) // Generar la URL de restablecimiento resetLink := GeneratePasswordResetURL(resetEmail, baseURL) // Preparar el cuerpo HTML del correo utilizando la plantilla htmlBody := app.Http.Mail.PrepareHtml("emails/password-reset", fiber.Map{ "reset_link": resetLink, }) // Canal para recibir errores de la goroutine errChan := make(chan error) // Ejecutar la goroutine para enviar el correo de manera asíncrona go func() { err := app.Http.Mail.Send(email, "Solicitud de restablecimiento de contraseña - U-site", htmlBody, "") errChan <- err // Enviar el error (o nil si no hay error) al canal }() // Esperar el resultado de la goroutine err := <-errChan if err != nil { log.Printf("Error enviando el correo de restablecimiento: %s", err) } else { log.Println("Correo de restablecimiento enviado con éxito") } } func SendConfirmationEmail(email string, baseURL string, nombreUsuario string) { // Generar el enlace de confirmación confirmLink := GenerateConfirmURL(nombreUsuario, baseURL) // Preparar el cuerpo HTML del correo utilizando la plantilla htmlBody := app.Http.Mail.PrepareHtml("emails/confirm", fiber.Map{ "confirm_link": confirmLink, }) // Canal para recibir errores de la goroutine errChan := make(chan error) // Ejecutar la goroutine para enviar el correo de manera asíncrona go func() { err := app.Http.Mail.Send(email, "✅ ¡Confirma tu registro en la Oficina Virtual de U-site!", htmlBody, "") errChan <- err // Enviar el error (o nil si no hay error) al canal }() // Esperar el resultado de la goroutine err := <-errChan if err != nil { // Manejar el error si ocurrió log.Printf("Error enviando el correo de confirmación: %s", err) } else { // Imprimir en consola si el correo se envió con éxito log.Println("Correo electrónico de confirmación enviado a:", email) } } func GenerateConfirmURL(nombreUsuario string, baseURL string) string { token := utils.Encrypt(nombreUsuario, app.Http.Server.Key) uri := fmt.Sprintf("%s/do/verify-email?t=%s", baseURL, token) return uri } func GeneratePasswordResetURL(email string, baseURL string) string { token := utils.Encrypt(email, app.Http.Server.Key) uri := fmt.Sprintf("%s/reset-password?t=%s", baseURL, token) return uri } // SendPortalPasswordResetEmail envía al usuario del portal un enlace para restablecer su contraseña. func SendPortalPasswordResetEmail(email, nombre, resetLink string) { htmlBody := fmt.Sprintf(`
U

Restablecer contraseña

Portal de Clientes · U-site

Hola %s,

Recibimos una solicitud para restablecer la contraseña de tu cuenta. Haz clic en el siguiente botón para continuar:

Restablecer contraseña

Este enlace es válido por 1 hora. Si no solicitaste este cambio, puedes ignorar este mensaje.

© 2025 U-site — Todos los derechos reservados

`, nombre, resetLink) go func() { if err := app.Http.Mail.Send(email, "Restablece tu contraseña - Portal U-site", htmlBody, ""); err != nil { log.Printf("[Portal] Error enviando correo de reseteo a %s: %v", email, err) } }() } // SendPortalCredentialsEmail envía al usuario del portal su URL de acceso y contraseña inicial. func SendPortalCredentialsEmail(email, nombre, password string) { loginURL := absAppURL("/portal/login") htmlBody := fmt.Sprintf(`
U

Portal de Clientes

Acceso a tu espacio de trabajo

Hola %s,

Tu cuenta en el Portal de Clientes ha sido creada. Usa los siguientes datos para ingresar:

Email: %s

Contraseña: %s

Enlace de acceso: %s

Ingresar al Portal

Si no esperabas este correo, puedes ignorarlo.

`, nombre, email, password, loginURL, loginURL, loginURL) go func() { if err := app.Http.Mail.Send(email, "Acceso a tu Portal de Clientes - U-site", htmlBody, ""); err != nil { log.Printf("[Portal] Error enviando credenciales a %s: %v", email, err) } }() } // ─── Notificaciones de Tickets ──────────────────────────────────────────────── // SendTicketNuevoAdmin notifica al admin que el cliente abrió un ticket. func SendTicketNuevoAdmin(adminEmail, proyectoNombre, autorNombre, titulo, descripcion, ticketURL string) { subject := fmt.Sprintf("🎫 Nuevo ticket: %s", titulo) htmlBody := fmt.Sprintf(`
🎫

Nuevo ticket de soporte

Proyecto: %s

Cliente: %s

Título: %s

Descripción: %s

Ver ticket
`, proyectoNombre, autorNombre, titulo, descripcion, ticketURL) go func() { if err := app.Http.Mail.Send(adminEmail, subject, htmlBody, ""); err != nil { log.Printf("[Notif] Error enviando ticket nuevo a admin: %v", err) } }() } // SendTicketRespuestaPortalUser notifica al portal user que el admin respondió. func SendTicketRespuestaPortalUser(userEmail, userName, proyectoNombre, titulo, respuesta, ticketURL string) { subject := fmt.Sprintf("💬 Respuesta en tu ticket: %s", titulo) htmlBody := fmt.Sprintf(`
💬

Hay una respuesta en tu ticket

Proyecto: %s

Hola %s,

El equipo respondió tu ticket "%s":

%s
Ver mi ticket
`, proyectoNombre, userName, titulo, respuesta, ticketURL) go func() { if err := app.Http.Mail.Send(userEmail, subject, htmlBody, ""); err != nil { log.Printf("[Notif] Error enviando respuesta ticket a %s: %v", userEmail, err) } }() } // SendTicketRespuestaAdmin notifica al admin que el portal user respondió. func SendTicketRespuestaAdmin(adminEmail, proyectoNombre, autorNombre, titulo, respuesta, ticketURL string) { subject := fmt.Sprintf("💬 Respuesta de cliente en ticket: %s", titulo) htmlBody := fmt.Sprintf(`

💬 Respuesta de cliente

Proyecto: %s | Cliente: %s

En el ticket "%s":

%s
Ver ticket
`, proyectoNombre, autorNombre, titulo, respuesta, ticketURL) go func() { if err := app.Http.Mail.Send(adminEmail, subject, htmlBody, ""); err != nil { log.Printf("[Notif] Error enviando respuesta cliente a admin: %v", err) } }() } // SendFacturaSubidaPortalUser notifica a un portal user que tiene una nueva factura disponible. func SendFacturaSubidaPortalUser(toEmail, userName, clienteNombre, numero string, monto float64, moneda, portalURL string) { go func() { subject := fmt.Sprintf("Nueva factura disponible: %s", numero) htmlBody := fmt.Sprintf(`

🧾 Nueva factura disponible

Hola %s,

Tienes una nueva factura disponible para descargar:

Número%s
Monto%s %.2f
Ver en el portal

Este es un mensaje automático.

`, userName, numero, moneda, monto, portalURL) if err := app.Http.Mail.Send(toEmail, subject, htmlBody, ""); err != nil { log.Printf("[Notif] Error enviando factura_subida a %s: %v", toEmail, err) } }() }