feat(notif): integrar notificaciones de tareas con NotifEventoConfig

- SeedNotifDefaults: poblar 10 eventos por defecto (tickets, servidores, tareas)
- notif_dispatch: NotificarTareaAsignada/Estado/Comentario ahora respetan
  canal_email, canal_telegram y canal_sistema de la config de notificaciones
- mail_service: añadir SendTareaAsignadaEmail y SendTareaNotifAdmin
- notif_config.html: agregar eventos tarea_asignada, tarea_estado, tarea_comentario
  al panel de configuración para que el admin pueda activar/desactivar canales

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-07-06 22:06:40 -05:00
co-authored by Claude Sonnet 4.6
parent 107178aa97
commit 37648724f8
4 changed files with 170 additions and 21 deletions
+95 -16
View File
@@ -260,22 +260,54 @@ func NotificarTareaAsignada(t *models.Tarea) {
if t == nil || t.AsignadoID == nil {
return
}
cfg := models.GetNotifConfig("tarea_asignada", "admin")
if cfg == nil {
return
}
asignado := ""
if t.Asignado != nil {
asignado = t.Asignado.Name
}
msg := fmt.Sprintf("📋 <b>Nueva tarea asignada</b>\n<b>%s</b>\nAsignado a: %s\nPrioridad: %s\n\n%s",
escapeTelegramHTML(t.Titulo),
escapeTelegramHTML(asignado),
escapeTelegramHTML(t.Prioridad),
escapeTelegramHTML(t.Descripcion))
sendTelegramAdmin(msg)
titulo := fmt.Sprintf("📋 Nueva tarea asignada: %s", t.Titulo)
cuerpo := fmt.Sprintf("Asignado a: %s | Prioridad: %s\n%s", asignado, t.Prioridad, t.Descripcion)
tareaPath := "/app/tareas"
if cfg.CanalSistema {
_ = models.CreateSistemaNotif(&models.SistemaNotificacion{
TipoUsuario: "admin",
UsuarioID: 0,
Titulo: titulo,
Cuerpo: cuerpo,
Url: tareaPath,
Icono: "📋",
})
}
if cfg.CanalEmail {
tareaURL := absAppURL(tareaPath)
if t.Asignado != nil && t.Asignado.Email != "" {
go SendTareaAsignadaEmail(t.Asignado.Email, t.Asignado.Name, t.Titulo, t.Prioridad, t.Descripcion, tareaURL)
} else if adminEmail := getAdminEmail(); adminEmail != "" {
go SendTareaNotifAdmin(adminEmail, titulo, cuerpo, tareaURL)
}
}
if cfg.CanalTelegram {
msg := fmt.Sprintf("📋 <b>Nueva tarea asignada</b>\n<b>%s</b>\nAsignado a: %s\nPrioridad: %s\n\n%s",
escapeTelegramHTML(t.Titulo),
escapeTelegramHTML(asignado),
escapeTelegramHTML(t.Prioridad),
escapeTelegramHTML(t.Descripcion))
sendTelegramAdmin(msg)
}
}
func NotificarTareaEstado(t *models.Tarea) {
if t == nil {
return
}
cfg := models.GetNotifConfig("tarea_estado", "admin")
if cfg == nil {
return
}
etiquetas := map[string]string{
"por_hacer": "📥 Por hacer",
"en_progreso": "🔄 En progreso",
@@ -287,24 +319,71 @@ func NotificarTareaEstado(t *models.Tarea) {
label = t.Estado
}
asignado := ""
asignadoSuffix := ""
if t.Asignado != nil {
asignado = "\nAsignado: " + escapeTelegramHTML(t.Asignado.Name)
asignado = t.Asignado.Name
asignadoSuffix = "\nAsignado: " + asignado
}
titulo := fmt.Sprintf("🔀 Tarea → %s: %s", label, t.Titulo)
cuerpo := fmt.Sprintf("Estado: %s%s", label, asignadoSuffix)
tareaPath := "/app/tareas"
if cfg.CanalSistema {
_ = models.CreateSistemaNotif(&models.SistemaNotificacion{
TipoUsuario: "admin",
UsuarioID: 0,
Titulo: titulo,
Cuerpo: cuerpo,
Url: tareaPath,
Icono: "🔀",
})
}
if cfg.CanalEmail {
if adminEmail := getAdminEmail(); adminEmail != "" {
go SendTareaNotifAdmin(adminEmail, titulo, cuerpo, absAppURL(tareaPath))
}
}
if cfg.CanalTelegram {
msg := fmt.Sprintf("🔀 <b>Tarea movida → %s</b>\n<b>%s</b>%s",
label,
escapeTelegramHTML(t.Titulo),
escapeTelegramHTML(asignadoSuffix))
sendTelegramAdmin(msg)
}
msg := fmt.Sprintf("🔀 <b>Tarea movida → %s</b>\n<b>%s</b>%s",
label,
escapeTelegramHTML(t.Titulo),
asignado)
sendTelegramAdmin(msg)
}
func NotificarTareaComentario(t *models.Tarea, contenido string) {
if t == nil {
return
}
msg := fmt.Sprintf("💬 <b>Nuevo comentario en tarea</b>\n<b>%s</b>\n\n%s",
escapeTelegramHTML(t.Titulo),
escapeTelegramHTML(contenido))
sendTelegramAdmin(msg)
cfg := models.GetNotifConfig("tarea_comentario", "admin")
if cfg == nil {
return
}
titulo := fmt.Sprintf("💬 Nuevo comentario en tarea: %s", t.Titulo)
tareaPath := "/app/tareas"
if cfg.CanalSistema {
_ = models.CreateSistemaNotif(&models.SistemaNotificacion{
TipoUsuario: "admin",
UsuarioID: 0,
Titulo: titulo,
Cuerpo: contenido,
Url: tareaPath,
Icono: "💬",
})
}
if cfg.CanalEmail {
if adminEmail := getAdminEmail(); adminEmail != "" {
go SendTareaNotifAdmin(adminEmail, titulo, contenido, absAppURL(tareaPath))
}
}
if cfg.CanalTelegram {
msg := fmt.Sprintf("💬 <b>Nuevo comentario en tarea</b>\n<b>%s</b>\n\n%s",
escapeTelegramHTML(t.Titulo),
escapeTelegramHTML(contenido))
sendTelegramAdmin(msg)
}
}
func sendTelegramAdmin(mensaje string) {