2025-05-17 11:36:26 -04:00

272 lines
6.4 KiB
Go

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
// }
// }