Skip to content

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 usuario

Datos 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édito

Datos 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 personales

Funciones 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 campo

Funciones 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édito

Acceso 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    - Iniciales

Ejemplos 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

  1. 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.

  2. 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.

  3. 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.

  4. 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
  5. 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

  1. Asunto conciso y relevante: El asunto debe ser breve (4-7 palabras) y describir claramente el propósito del correo.

  2. Personalización: Usa el nombre del destinatario y otros datos personales relevantes.

  3. Mensajes claros y concisos: Ve directo al punto. Los destinatarios tienen poco tiempo y atención.

  4. 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.

  5. 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

  1. Prueba en múltiples clientes de correo: Los correos pueden verse diferentes en Gmail, Outlook, clientes móviles, etc.

  2. Evita JavaScript: Los clientes de correo bloquean JavaScript, así que no lo incluyas.

  3. Imágenes optimizadas: Incluye dimensiones en las etiquetas de imagen y optimiza el tamaño de archivo.

  4. 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 }}
  1. 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

  1. 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.Entity

    Solución: Verificar que está accediendo al objeto correcto, por ejemplo .Credit.Amount en lugar de .Entity.Amount.

  2. Función no reconocida: Si una función de plantilla no es reconocida:

    function "formatDate" not defined

    Solución: Utilizar las funciones correctas como { { date .Value }} en lugar de { { formatDate .Value }}.

  3. Error de sintaxis:

    unexpected "}" in operand

    Solució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:

  1. Verificar que las direcciones de correo sean válidas
  2. Revisar las configuraciones del servidor SMTP
  3. Comprobar que los correos no sean marcados como spam
  4. 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>