2025-10-29 10:36:36 -04:00

156 lines
6.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package email
import (
"bytes"
"fmt"
"github.com/tuusuario/go-sync-service/internal/domain/ports"
"html/template"
"strings"
"time"
)
// TaskTplData contiene los datos que se inyectarán en la plantilla HTML de la notificación de tarea.
// Se usan como {{.Campo}} dentro del template.
type TaskTplData struct {
AppName string
Nombre string
TareaNombre string
Descripcion string
FechaVencimiento string
ErrorDescripcion string
FechaError string
LinkTarea string
LogoURL string
Direccion string
Telefono string
EmailContacto string
Year int
ColorHeaderBG string
ColorAccent string
ColorFooterText string
ColorFooterMuted string
ColorBodyBG string
}
type Branding struct {
AppName string
LogoURL string
ColorHeaderBG string
ColorAccent string
ColorFooterText string
ColorFooterMuted string
ColorBodyBG string
Direccion string
Telefono string
EmailContacto string
Year int
}
// Código del parámetro en tu tabla `parametros` que guarda la PLANTILLA HTML para la tarea.
// Ej: SELECT valor FROM parametros WHERE codigo = 'EMAIL_TEMPLATE_TASK';
const ParamEmailTaskTemplate = "EMAIL_TEMPLATE_TASK"
// BuildTaskSubject arma el asunto con el nombre de la app.
func BuildTaskSubject(appName string) string {
appName = strings.TrimSpace(appName)
if appName == "" {
return "Tarea asignada"
}
return fmt.Sprintf("[%s] Tarea asignada", appName)
}
// RenderTaskEmailHTML recibe la plantilla HTML (tplStr) y los datos (data) para la notificación de tarea.
// Si tplStr viene vacío, usa DefaultTaskTemplate como fallback.
func RenderTaskEmailHTML(tplStr string, data TaskTplData) (string, error) {
if strings.TrimSpace(tplStr) == "" {
tplStr = DefaultErrorSyncTemplate
}
tpl, err := template.New("email_task").Parse(tplStr)
if err != nil {
return "", fmt.Errorf("parse template: %w", err)
}
var buf bytes.Buffer
if err := tpl.Execute(&buf, data); err != nil {
return "", fmt.Errorf("execute template: %w", err)
}
return buf.String(), nil
}
func LoadBrandingAsignation(cfg ports.RedisConfigProvider, appName string) Branding {
get := func(key, def string) string {
if cfg == nil {
return def
}
v, _ := cfg.GetString("parametros:" + key)
v = strings.TrimSpace(v)
if v == "" {
return def
}
return v
}
if strings.TrimSpace(appName) == "" {
appName = get("EMAIL_APP_NAME", appName)
}
return Branding{
AppName: appName,
LogoURL: get("EMAIL_LOGO_URL", ""),
ColorHeaderBG: get("EMAIL_COLOR_HEADER_BG", "#0e1a2b"),
ColorAccent: get("EMAIL_COLOR_ACCENT", "#CBA135"),
ColorFooterText: get("EMAIL_COLOR_FOOTER_TEXT", "#ffffff"),
ColorFooterMuted: get("EMAIL_COLOR_FOOTER_MUTED", "#bfc6d1"),
ColorBodyBG: get("EMAIL_COLOR_BODY_BG", "#f4f6f8"),
Direccion: get("EMAIL_FOOTER_ADDRESS", ""),
Telefono: get("EMAIL_FOOTER_PHONE", ""),
EmailContacto: get("EMAIL_FOOTER_EMAIL", ""),
Year: time.Now().Year(),
}
}
// --- Plantilla por defecto para la notificación de tarea (Go template con {{.Campo}}) ---
const DefaultErrorSyncTemplate = `<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>{{.AppName}} Error de Sincronización</title>
<style>@media (max-width:620px){.container{width:100% !important}.p-24{padding:20px !important}.h1{font-size:22px !important;line-height:28px !important}}</style>
</head>
<body style="margin:0;padding:0;background:#f4f6f8;color:#1c1c1c;">
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="background:#f4f6f8;">
<tr><td align="center" style="padding:24px;">
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="600" class="container" style="width:600px;max-width:600px;background:#ffffff;border-radius:12px;overflow:hidden;box-shadow:0 4px 18px rgba(0,0,0,.06);">
<tr><td style="background:{{if .ColorHeaderBG}}{{.ColorHeaderBG}}{{else}}#0e1a2b{{end}};padding:20px 24px;" align="left">
{{if .LogoURL}}<img src="{{.LogoURL}}" width="140" alt="{{.AppName}}" style="display:block;border:0;max-width:100%">{{else}}<div style="font-family:Arial,Helvetica,sans-serif;font-size:16px;font-weight:bold;color:#fff;">{{.AppName}}</div>{{end}}
</td></tr>
<tr><td class="p-24" style="padding:28px 32px 8px 32px;">
<h1 class="h1" style="margin:0 0 8px 0;font-family:Arial,Helvetica,sans-serif;font-size:24px;line-height:32px;color:#0e1a2b;">
Error de sincronización en {{.AppName}}
</h1>
<p style="margin:0;font-family:Arial,Helvetica,sans-serif;font-size:14px;line-height:22px;color:#4a4a4a;">
Hola <strong>{{.Nombre}}</strong>, hemos detectado un problema al intentar sincronizar los datos. Aquí están los detalles:
</p>
</td></tr>
<tr><td class="p-24" style="padding:8px 32px 0 32px;">
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="background:#f9fafb;border:1px solid #e6e8eb;border-radius:8px;">
<tr><td style="padding:16px 20px;">
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%">
<tr><td style="font-family:Arial,Helvetica,sans-serif;font-size:13px;color:#6b7280;padding:4px 0;width:160px;">Descripción del Error</td>
<td style="font-family:Arial,Helvetica,sans-serif;font-size:14px;color:#111827;padding:4px 0;"><strong>{{.ErrorDescripcion}}</strong></td></tr>
<tr><td style="font-family:Arial,Helvetica,sans-serif;font-size:13px;color:#6b7280;padding:4px 0;width:160px;">Hora del Error</td>
<td style="font-family:Arial,Helvetica,sans-serif;font-size:14px;color:#111827;padding:4px 0;"><strong>{{.FechaError}}</strong></td></tr>
</table>
</td></tr>
</table>
</td></tr>
<br/><br/><br/><br/>
<tr><td style="background:{{if .ColorHeaderBG}}{{.ColorHeaderBG}}{{else}}#0e1a2b{{end}};padding:18px 24px;" align="left">
<p style="margin:0 0 6px 0;font-family:Arial,Helvetica,sans-serif;font-size:12px;line-height:18px;color:#ffffff;">{{.AppName}}</p>
<p style="margin:0;font-family:Arial,Helvetica,sans-serif;font-size:11px;line-height:18px;color:#bfc6d1;">
{{.Direccion}}{{if .Telefono}} · Tel. {{.Telefono}}{{end}}{{if .EmailContacto}} · {{.EmailContacto}}{{end}} · © {{.Year}} {{.AppName}}
</p>
</td></tr>
</table>
</td></tr>
</table>
</body></html>`