package notifications import ( "bytes" "encoding/json" "fmt" "log" "net/http" "net/smtp" "time" ) // NotificationSender es la interfaz que deben cumplir los sistemas de notificación. type NotificationSender interface { SendNotification(subject, message string) error } // WebhookNotifier implementa la notificación vía webhook. type WebhookNotifier struct { WebhookURL string } // SendNotification envía notificación a través de webhook. func (w *WebhookNotifier) SendNotification(subject, message string) error { if w.WebhookURL == "" { return nil } payload, err := json.Marshal(map[string]string{ "subject": subject, "message": message, "time": time.Now().Format(time.RFC3339), }) if err != nil { return err } resp, err := http.Post(w.WebhookURL, "application/json", bytes.NewBuffer(payload)) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode >= 400 { return fmt.Errorf("webhook error: %s", resp.Status) } return nil } // EmailNotifier simula el envío de notificaciones por correo electrónico. type EmailNotifier struct { SMTPServer string SMTPPort string Username string Password string FromEmail string ToEmail string } // SendNotification envía un email a través de un servidor SMTP. func (e *EmailNotifier) SendNotification(subject, message string) error { // Construir los encabezados del mensaje header := make(map[string]string) header["From"] = e.FromEmail header["To"] = e.ToEmail header["Subject"] = subject header["MIME-Version"] = "1.0" header["Content-Type"] = "text/plain; charset=\"utf-8\"" var msg string for k, v := range header { msg += fmt.Sprintf("%s: %s\r\n", k, v) } msg += "\r\n" + message // Configurar autenticación SMTP auth := smtp.PlainAuth("", e.Username, e.Password, e.SMTPServer) addr := fmt.Sprintf("%s:%s", e.SMTPServer, e.SMTPPort) // Enviar el email err := smtp.SendMail(addr, auth, e.FromEmail, []string{e.ToEmail}, []byte(msg)) if err != nil { return err } log.Printf("Email enviado correctamente a %s", e.ToEmail) return nil } // SlackNotifier implementa las notificaciones vía Slack. type SlackNotifier struct { WebhookURL string } // SendNotification envía un mensaje a Slack. func (s *SlackNotifier) SendNotification(subject, message string) error { if s.WebhookURL == "" { return nil } payload, err := json.Marshal(map[string]interface{}{ "text": fmt.Sprintf("*%s*\n%s", subject, message), }) if err != nil { return err } resp, err := http.Post(s.WebhookURL, "application/json", bytes.NewBuffer(payload)) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode >= 400 { return fmt.Errorf("slack webhook error: %s", resp.Status) } return nil } // CreateNotificationSender crea el notificador según la configuración. func CreateNotificationSender(enabled bool, method string, cfg map[string]string) NotificationSender { if !enabled { return nil } switch method { case "webhook": return &WebhookNotifier{ WebhookURL: cfg["url"], } case "email": return &EmailNotifier{ SMTPServer: cfg["smtp_server"], SMTPPort: cfg["smtp_port"], Username: cfg["username"], Password: cfg["password"], FromEmail: cfg["from_email"], ToEmail: cfg["to_email"], } case "slack": return &SlackNotifier{ WebhookURL: cfg["webhook_url"], } default: log.Printf("Método de notificación desconocido: %s", method) return nil } } // package notifications // import ( // "bytes" // "encoding/json" // "fmt" // "log" // "net/http" // "time" // ) // // NotificationSender define la interfaz para enviar notificaciones. // type NotificationSender interface { // SendNotification(subject, message string) error // } // // WebhookNotifier envía notificaciones mediante webhook. // type WebhookNotifier struct { // WebhookURL string // } // func (w *WebhookNotifier) SendNotification(subject, message string) error { // if w.WebhookURL == "" { // return nil // } // payload, err := json.Marshal(map[string]string{ // "subject": subject, // "message": message, // "time": time.Now().Format(time.RFC3339), // }) // if err != nil { // return err // } // resp, err := http.Post(w.WebhookURL, "application/json", bytes.NewBuffer(payload)) // if err != nil { // return err // } // defer resp.Body.Close() // if resp.StatusCode >= 400 { // return fmt.Errorf("webhook error: %s", resp.Status) // } // return nil // } // // EmailNotifier simula el envío de notificaciones por email. // type EmailNotifier struct { // SMTPServer string // SMTPPort string // Username string // Password string // FromEmail string // ToEmail string // } // func (e *EmailNotifier) SendNotification(subject, message string) error { // log.Printf("Simulando envío de email: Asunto: %s, Mensaje: %s", subject, message) // log.Printf("Destinatario: %s, Remitente: %s", e.ToEmail, e.FromEmail) // // Aquí se integraría el cliente SMTP real si fuera necesario // return nil // } // // SlackNotifier envía notificaciones a Slack. // type SlackNotifier struct { // WebhookURL string // } // func (s *SlackNotifier) SendNotification(subject, message string) error { // if s.WebhookURL == "" { // return nil // } // payload, err := json.Marshal(map[string]interface{}{ // "text": fmt.Sprintf("*%s*\n%s", subject, message), // }) // if err != nil { // return err // } // resp, err := http.Post(s.WebhookURL, "application/json", bytes.NewBuffer(payload)) // if err != nil { // return err // } // defer resp.Body.Close() // if resp.StatusCode >= 400 { // return fmt.Errorf("slack webhook error: %s", resp.Status) // } // return nil // } // // NewNotificationSender crea la instancia del notificador según la configuración. // func NewNotificationSender(enabled bool, method string, cfg map[string]string) NotificationSender { // if !enabled { // return nil // } // switch method { // case "webhook": // return &WebhookNotifier{WebhookURL: cfg["url"]} // case "email": // return &EmailNotifier{ // SMTPServer: cfg["smtp_server"], // SMTPPort: cfg["smtp_port"], // Username: cfg["username"], // Password: cfg["password"], // FromEmail: cfg["from_email"], // ToEmail: cfg["to_email"], // } // case "slack": // return &SlackNotifier{WebhookURL: cfg["webhook_url"]} // default: // log.Printf("Método de notificación desconocido: %s", method) // return nil // } // }