package services import ( "fmt" "log" "github.com/sujit-baniya/fiber-boilerplate/pkg/models" ) // ─── DispatchTicketNuevo ────────────────────────────────────────────────────── // Llamar cuando el portal user crea un nuevo ticket. // Notifica al ADMIN según su configuración de canales. func DispatchTicketNuevo(ticket *models.ProyectoTicket, portalUser *models.PortalUser, proyectoNombre string) { cfg := models.GetNotifConfig("ticket_nuevo", "admin") if cfg == nil { return } ticketURL := "/app/tickets" titulo := fmt.Sprintf("Nuevo ticket: %s", ticket.Titulo) cuerpo := fmt.Sprintf("Cliente %s abrió: %s", ticket.AutorNombre, ticket.Titulo) if cfg.CanalSistema { _ = models.CreateSistemaNotif(&models.SistemaNotificacion{ TipoUsuario: "admin", UsuarioID: 0, Titulo: titulo, Cuerpo: cuerpo, Url: ticketURL, Icono: "🎫", }) } if cfg.CanalEmail { if adminEmail := getAdminEmail(); adminEmail != "" { SendTicketNuevoAdmin(adminEmail, proyectoNombre, ticket.AutorNombre, ticket.Titulo, ticket.Descripcion, ticketURL) } } if cfg.CanalTelegram { msg := fmt.Sprintf("🎫 Nuevo ticket\nProyecto: %s\nCliente: %s\nTítulo: %s\n\n%s\n\n🔗 %s", proyectoNombre, ticket.AutorNombre, ticket.Titulo, ticket.Descripcion, ticketURL) sendTelegramAdmin(msg) } } // ─── DispatchTicketRespuestaCliente ────────────────────────────────────────── // Llamar cuando el portal user responde un ticket. // Notifica al ADMIN según su configuración de canales. func DispatchTicketRespuestaCliente(ticket *models.ProyectoTicket, contenido string, proyectoNombre string) { cfg := models.GetNotifConfig("ticket_respuesta_cliente", "admin") if cfg == nil { return } ticketURL := "/app/tickets" titulo := fmt.Sprintf("Respuesta de cliente: %s", ticket.Titulo) cuerpo := fmt.Sprintf("%s respondió: %s", ticket.AutorNombre, contenido) if cfg.CanalSistema { _ = models.CreateSistemaNotif(&models.SistemaNotificacion{ TipoUsuario: "admin", UsuarioID: 0, Titulo: titulo, Cuerpo: cuerpo, Url: ticketURL, Icono: "💬", }) } if cfg.CanalEmail { if adminEmail := getAdminEmail(); adminEmail != "" { SendTicketRespuestaAdmin(adminEmail, proyectoNombre, ticket.AutorNombre, ticket.Titulo, contenido, ticketURL) } } if cfg.CanalTelegram { msg := fmt.Sprintf("💬 Respuesta de cliente\nProyecto: %s\nCliente: %s\n\n%s\n\n🔗 %s", proyectoNombre, ticket.AutorNombre, contenido, ticketURL) sendTelegramAdmin(msg) } } // ─── DispatchTicketRespuestaAdmin ───────────────────────────────────────────── // Llamar cuando el admin responde un ticket. // Notifica al PORTAL USER según su configuración de canales. func DispatchTicketRespuestaAdmin(ticket *models.ProyectoTicket, contenido string, proyectoNombre string) { cfg := models.GetNotifConfig("ticket_respuesta_admin", "portal_user") if cfg == nil { return } // Obtener portal user para saber email y telegram portalUser, err := models.GetPortalUserByID(ticket.PortalUserID) if err != nil || portalUser == nil { log.Printf("[Notif] PortalUser %d no encontrado: %v", ticket.PortalUserID, err) return } portalURL := fmt.Sprintf("/portal/proyecto/%s", ticket.Proyecto.Slug) titulo := fmt.Sprintf("Respuesta en tu ticket: %s", ticket.Titulo) cuerpo := fmt.Sprintf("El equipo respondió: %s", contenido) if cfg.CanalSistema { _ = models.CreateSistemaNotif(&models.SistemaNotificacion{ TipoUsuario: "portal_user", UsuarioID: portalUser.ID, Titulo: titulo, Cuerpo: cuerpo, Url: portalURL, Icono: "💬", }) } if cfg.CanalEmail && portalUser.Email != "" { SendTicketRespuestaPortalUser(portalUser.Email, portalUser.Nombre, proyectoNombre, ticket.Titulo, contenido, portalURL) } if cfg.CanalTelegram && portalUser.TelegramChatID != "" { ts := NewTelegramService() msg := fmt.Sprintf("💬 El equipo respondió tu ticket\nProyecto: %s\nTicket: %s\n\n%s\n\n🔗 %s", proyectoNombre, ticket.Titulo, contenido, portalURL) if err := ts.SendMessageWithToken(portalUser.TelegramChatID, msg, getAdminBotToken()); err != nil { log.Printf("[Notif] Error telegram portal_user %d: %v", portalUser.ID, err) } } } // ─── helpers internos ───────────────────────────────────────────────────────── // getAdminEmail devuelve el from_address del SMTP activo como email del admin. func getAdminEmail() string { cfg, err := models.GetSmtpConfig() if err != nil || cfg == nil { return "" } return cfg.FromAddress } // getAdminBotToken devuelve el token del primer TelegramConfig activo. func getAdminBotToken() string { configs, err := models.GetAllTelegramConfigs() if err != nil { return "" } for _, c := range configs { if c.Activo { return c.BotToken } } return "" } // sendTelegramAdmin envía un mensaje usando el primer TelegramConfig activo. func sendTelegramAdmin(mensaje string) { configs, err := models.GetAllTelegramConfigs() if err != nil { log.Printf("[Notif] Error obteniendo configs telegram: %v", err) return } for _, cfg := range configs { if !cfg.Activo { continue } ts := &TelegramService{BotToken: cfg.BotToken} if err := ts.SendMessage(cfg.ChatID, mensaje); err != nil { log.Printf("[Notif] Error enviando telegram admin (cfg %d): %v", cfg.ID, err) } } } // ─── DispatchFacturaSubida ──────────────────────────────────────────────────── // Llamar cuando el admin sube el PDF de una factura. // Notifica a todos los portal_users activos del cliente. func DispatchFacturaSubida(factura *models.Factura) { cfg := models.GetNotifConfig("factura_subida", "portal_user") if cfg == nil { return } if factura.ClienteID == 0 { return } portalUsers, err := models.GetPortalUsersByClienteID(factura.ClienteID) if err != nil || len(portalUsers) == 0 { return } clienteNombre := "" if factura.Cliente.Nombre != "" { clienteNombre = factura.Cliente.Nombre } else if factura.Cliente.Empresa != "" { clienteNombre = factura.Cliente.Empresa } for _, u := range portalUsers { u := u // capture portalURL := "/portal/dashboard" titulo := fmt.Sprintf("Nueva factura disponible: %s", factura.Numero) cuerpo := fmt.Sprintf("Factura %s por %s %s", factura.Numero, factura.Moneda, fmt.Sprintf("%.2f", factura.Monto)) if cfg.CanalSistema { _ = models.CreateSistemaNotif(&models.SistemaNotificacion{ TipoUsuario: "portal_user", UsuarioID: u.ID, Titulo: titulo, Cuerpo: cuerpo, Url: portalURL, Icono: "🧾", }) } if cfg.CanalEmail && u.Email != "" { go SendFacturaSubidaPortalUser(u.Email, u.Nombre, clienteNombre, factura.Numero, factura.Monto, factura.Moneda, portalURL) } if cfg.CanalTelegram && u.TelegramChatID != "" { ts := NewTelegramService() msg := fmt.Sprintf("🧾 Nueva factura disponible\nNúmero: %s\nMonto: %s %.2f\n\n🔗 %s", factura.Numero, factura.Moneda, factura.Monto, portalURL) if err := ts.SendMessageWithToken(u.TelegramChatID, msg, getAdminBotToken()); err != nil { log.Printf("[Notif] Error telegram portal_user %d: %v", u.ID, err) } } } log.Printf("[Notif] DispatchFacturaSubida factura=%d clientes notificados=%d", factura.ID, len(portalUsers)) }