Appearance
Manual del Servicio de Correo Electrónico de Kuenta
Este documento explica cómo utilizar el servicio de correo electrónico en Kuenta, detallando la estructura de datos, las variables disponibles y las funciones que se pueden utilizar para personalizar los mensajes.
Descripción General
El servicio de correo electrónico de Kuenta permite enviar comunicaciones personalizadas a usuarios y entidades. Utiliza un sistema de plantillas para personalizar tanto el asunto como el cuerpo de los correos, permitiendo incluir datos dinámicos según el contexto del mensaje.
Estructura de Datos
EmailRequest
go
type EmailRequest struct {
EmailContent // Asunto y cuerpo del correo
FromEmail string // Correo del remitente
FromName string // Nombre del remitente
To string // Correo del destinatario
Name string // Nombre del destinatario
Files []*File // Archivos adjuntos
prepared bool // Si ya se procesó la plantilla
Reason string // Motivo del correo
}EmailContent
go
type EmailContent struct {
Subject string // Asunto del correo
Body string // Cuerpo del correo (plantilla HTML)
}EmailTemplateVars
go
type EmailTemplateVars struct {
Entity *Entity // Entidad relacionada con el correo
Profile *Profile // Perfil de la entidad
Organization *Entity // Organización emisora
Credit *Credit // Datos del crédito (si aplica)
Invitation *Invitation // Datos de invitación (si aplica)
Title template.HTML // Título como HTML
Body template.HTML // Cuerpo como HTML
Code string // Código de verificación o similar
URL string // URL para acción del usuario
Activity *UserActivityLog // Registro de actividad
}Variables Disponibles en Plantillas
Las plantillas de correo electrónico tienen acceso a las siguientes variables:
.Entity - La entidad relacionada con el correo
.Profile - El perfil de la entidad
.Organization - La organización (generalmente la entidad emisora del correo)
.Credit - El objeto de crédito (cuando el correo está relacionado con un crédito)
.Invitation - Objeto de invitación (cuando el correo es una invitación)
.Title - Título del correo como HTML
.Body - Cuerpo del correo como HTML
.Code - Código de verificación o similar
.URL - URL a la que se debe dirigir el usuario
.Activity - Registro de actividad del usuarioDatos de Crédito
Cuando el correo está relacionado con un crédito, tienes acceso al objeto Credit que contiene toda la información relacionada:
.Credit.ID - ID del crédito
.Credit.Status - Estado del crédito (ApprovedCredit, RejectedCredit, PendingCredit, etc.)
.Credit.Amount - Monto del crédito
.Credit.Principal - Monto principal del crédito
.Credit.Rate - Tasa de interés
.Credit.Term - Plazo del crédito
.Credit.Time - Duración del crédito en días
.Credit.Frequency - Frecuencia de pago
.Credit.CreatedAt - Fecha de creación
.Credit.UpdatedAt - Fecha de actualización
.Credit.StartDate - Fecha de inicio
.Credit.ApprovedAt - Fecha de aprobación
.Credit.CancelledAt - Fecha de cancelación
.Credit.Debtor - Objeto del deudor
.Credit.Creditor - Objeto del acreedor
.Credit.UserLastAction - Usuario que realizó la última acción
.Credit.Installments - Cuotas del créditoDatos de Organización y Entidad
Las variables .Entity, .Organization, .Credit.Debtor y .Credit.Creditor contienen información sobre las entidades involucradas:
.ID - ID de la organización
.Phone - Número de teléfono
.Email - Correo electrónico
.Nickname - Apodo o alias
.Verified - Si está verificado
.Type - Tipo de entidad (natural o legal)
.IDType - Tipo de identificación
.IDNumber - Número de identificación
.Profile - Perfil con datos personalesFunciones de Plantillas
Funciones Nativas de Go Templates
Las plantillas de correo admiten todas las funciones estándar de Go Templates:
{ { if }}...{ { else }}...{ { end }} - Condiciones
{ { range .Items }}...{ { end }} - Ciclos
{ { with .Object }}...{ { end }} - Establecer contexto
{ { index .Array 1 }} - Acceso a índice de array
{ { .Field }} - Acceso a campoFunciones Específicas de Kuenta
Según el análisis del código fuente en email_service.go, el servicio de email utiliza las funciones de domain.Funcs() junto con algunas funciones específicas para correos:
go
// Parseo de la plantilla
generalFunctions := domain.Funcs()
t, err := template.New("email").Funcs(fs).Funcs(generalFunctions).Parse(text)Las funciones disponibles incluyen:
{ { currency .Credit.Amount }} - Formatea un valor como moneda (Ej: $1,000,000)
{ { percentage .Credit.Rate }} - Formatea un valor como porcentaje (Ej: 12.5%)
{ { date .Credit.CreatedAt }} - Formatea una fecha
{ { commonData .Profile "Name" }} - Accede a datos comunes de un perfil
{ { pin }} - Obtiene el PIN de verificación (en algunos contextos)
{ { summary }} - Genera un resumen HTML del crédito
{ { amortization }} - Genera una tabla HTML de amortización del crédito
{ { creditLimit "max" }} - Muestra el límite máximo de crédito
{ { creditLimit "min" }} - Muestra el límite mínimo de créditoAcceso a Datos de Perfil
Para acceder a los datos comunes a través de commonData, solo estos campos están disponibles:
Name - Nombre (persona completo o empresa)
Email - Correo electrónico
Address - Dirección
AddressCity - Ciudad de la dirección
IDNumber - Número de identificación
Initials - InicialesEjemplos de Uso de Plantillas
Ejemplo para Correo de Bienvenida
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Bienvenido a Kuenta</title>
</head>
<body>
<h1>¡Bienvenido, { { commonData .Entity.Profile "Name" }}!</h1>
<p>Gracias por registrarte en nuestra plataforma.</p>
<p>Para confirmar tu cuenta, haz clic en el siguiente enlace:</p>
<a href="{ { .URL }}">Confirmar mi cuenta</a>
<p>O utiliza este código de verificación: <strong>{ { .Code }}</strong></p>
<p>Saludos,<br />El equipo de Kuenta</p>
</body>
</html>Ejemplo para Notificación de Crédito Aprobado
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Tu Crédito ha sido Aprobado</title>
<style>
body {
font-family: Arial, sans-serif;
line-height: 1.6;
color: #333;
max-width: 600px;
margin: 0 auto;
}
.header {
background-color: #4caf50;
color: white;
padding: 20px;
text-align: center;
}
.content {
padding: 20px;
}
.footer {
background-color: #f1f1f1;
padding: 10px;
text-align: center;
font-size: 12px;
}
.button {
display: inline-block;
background-color: #4caf50;
color: white;
padding: 10px 20px;
text-decoration: none;
border-radius: 5px;
margin: 20px 0;
}
table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
}
th,
td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
</style>
</head>
<body>
<div class="header">
<h1>¡Tu Crédito ha sido Aprobado!</h1>
</div>
<div class="content">
<p>Estimado(a) { { commonData .Credit.Debtor.Profile "Name" }}:</p>
<p>
Nos complace informarte que tu solicitud de crédito ha sido
<strong>APROBADA</strong>.
</p>
<h2>Detalles del Crédito:</h2>
<table>
<tr>
<th>Concepto</th>
<th>Valor</th>
</tr>
<tr>
<td>Monto Aprobado</td>
<td>{ { currency .Credit.Amount }}</td>
</tr>
<tr>
<td>Tasa de Interés</td>
<td>{ { percentage .Credit.Rate }}</td>
</tr>
<tr>
<td>Plazo</td>
<td>{ { .Credit.Term }} días</td>
</tr>
<tr>
<td>Fecha de Aprobación</td>
<td>{ { date .Credit.ApprovedAt }}</td>
</tr>
</table>
<h3>Resumen del Crédito</h3>
{ { summary }}
<h3>Tabla de Amortización</h3>
{ { amortization }}
<p>
Para continuar con el proceso de desembolso, por favor haz clic en el
siguiente botón:
</p>
<p style="text-align: center;">
<a href="{ { .URL }}" class="button">Continuar al Desembolso</a>
</p>
<p><strong>Tu código de verificación es:</strong> { { pin }}</p>
<p>Si tienes alguna pregunta, no dudes en contactarnos.</p>
<p>
Atentamente,<br />El equipo de { { commonData .Organization.Profile
"Name" }}
</p>
</div>
<div class="footer">
<p>
Este correo es informativo y fue enviado a { { commonData
.Credit.Debtor.Profile "Email" }}
</p>
<p>
© { { .Credit.CreatedAt.Year }} { { commonData .Organization.Profile
"Name" }}. Todos los derechos reservados.
</p>
</div>
</body>
</html>Ejemplo para Recordatorio de Pago
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Recordatorio de Pago</title>
<style>
body {
font-family: Arial, sans-serif;
line-height: 1.6;
color: #333;
max-width: 600px;
margin: 0 auto;
}
.header {
background-color: #3498db;
color: white;
padding: 20px;
text-align: center;
}
.content {
padding: 20px;
}
.footer {
background-color: #f1f1f1;
padding: 10px;
text-align: center;
font-size: 12px;
}
.button {
display: inline-block;
background-color: #3498db;
color: white;
padding: 10px 20px;
text-decoration: none;
border-radius: 5px;
margin: 20px 0;
}
.important {
background-color: #fcf8e3;
border-left: 4px solid #faebcc;
padding: 10px;
margin: 20px 0;
}
</style>
</head>
<body>
<div class="header">
<h1>Recordatorio de Pago</h1>
</div>
<div class="content">
<p>Estimado(a) { { commonData .Credit.Debtor.Profile "Name" }}:</p>
<p>
Te escribimos para recordarte que tienes una cuota próxima a vencer.
</p>
<div class="important">
<p><strong>Información importante de tu cuota:</strong></p>
<p>Vencimiento: { { date .Credit.Installments.0.Date }}</p>
<p>Valor a pagar: { { currency .Credit.Installments.0.Payment }}</p>
</div>
<p>
Para realizar el pago de manera sencilla, haz clic en el siguiente
botón:
</p>
<p style="text-align: center;">
<a href="{ { .URL }}" class="button">Realizar Pago</a>
</p>
<p>
Si ya realizaste el pago, agradecemos tu puntualidad y puedes ignorar
este mensaje.
</p>
<p>
Atentamente,<br />El equipo de { { commonData .Organization.Profile
"Name" }}
</p>
</div>
<div class="footer">
<p>
Este correo es informativo y fue enviado a { { commonData
.Credit.Debtor.Profile "Email" }}
</p>
</div>
</body>
</html>Mejores Prácticas para Correos Electrónicos
Diseño y Estructura
Respeta el ancho máximo: Mantén el contenido principal en un ancho máximo de 600px para mejor visualización en todos los dispositivos.
Utiliza tablas para compatibilidad: Aunque el código de ejemplo usa
<div>, en correos electrónicos reales es mejor usar tablas para garantizar la compatibilidad con clientes de correo antiguos.Incluye estilos en línea: Define todos los estilos en línea (
style="...") o en la sección<head>. No uses hojas de estilo externas.Estructura clara:
- Encabezado con logo y título
- Saludo personalizado
- Cuerpo con mensaje principal
- Llamada a la acción clara
- Firma y pie de página con información legal
Botones accesibles: Para los botones de llamada a acción, usa etiquetas
<a>con suficiente padding para facilitar el clic en dispositivos móviles.
Contenido y Redacción
Asunto conciso y relevante: El asunto debe ser breve (4-7 palabras) y describir claramente el propósito del correo.
Personalización: Usa el nombre del destinatario y otros datos personales relevantes.
Mensajes claros y concisos: Ve directo al punto. Los destinatarios tienen poco tiempo y atención.
Una sola llamada a la acción principal: Cada correo debe tener un objetivo claro y una acción principal que deseas que el usuario realice.
Accesibilidad:
- Usa texto alternativo para imágenes
- Asegúrate de tener suficiente contraste entre texto y fondo
- Proporciona alternativas de texto plano
Consideraciones Técnicas
Prueba en múltiples clientes de correo: Los correos pueden verse diferentes en Gmail, Outlook, clientes móviles, etc.
Evita JavaScript: Los clientes de correo bloquean JavaScript, así que no lo incluyas.
Imágenes optimizadas: Incluye dimensiones en las etiquetas de imagen y optimiza el tamaño de archivo.
Verificación de variables: Siempre verifica que las variables existan antes de usarlas:
html
{ { if .Credit }} { { if .Credit.Installments }} Vencimiento: { { date
.Credit.Installments.0.Date }} { { end }} { { end }}- Versión de texto plano: Aunque no se maneja directamente en estas plantillas, es recomendable tener una versión de texto plano de cada correo.
Solución de Problemas Comunes
Errores Comunes
Variable no encontrada: Si recibe un error indicando que una variable no existe, verifique que esté accediendo correctamente a la estructura:
error: can't evaluate field Amount in type *domain.EntitySolución: Verificar que está accediendo al objeto correcto, por ejemplo
.Credit.Amounten lugar de.Entity.Amount.Función no reconocida: Si una función de plantilla no es reconocida:
function "formatDate" not definedSolución: Utilizar las funciones correctas como
{ { date .Value }}en lugar de{ { formatDate .Value }}.Error de sintaxis:
unexpected "}" in operandSolución: Verificar que las llaves
{ {y}}estén balanceadas y que la sintaxis sea correcta.
Problemas con Entrega de Correos
Si los correos no llegan a su destino:
- Verificar que las direcciones de correo sean válidas
- Revisar las configuraciones del servidor SMTP
- Comprobar que los correos no sean marcados como spam
- Verificar que el tamaño total del correo (con adjuntos) no exceda los límites
Depuración de Plantillas
Para debuggear problemas en plantillas complejas, puede agregar esto temporalmente para ver los datos disponibles:
html
<pre>
Datos disponibles:
Entity: { { if .Entity }}Presente{ { else }}No disponible{ { end }}
Credit: { { if .Credit }}Presente{ { else }}No disponible{ { end }}
URL: { { if .URL }}{ { .URL }}{ { else }}No disponible{ { end }}
</pre>