# Implementación Técnica

### Integración con Mailjet

#### **Configuración Inicial**

* Configurar Mailjet con las credenciales de la cuenta.
* Implementar la API de Mailjet para gestionar el envío de correos electrónicos.

#### **Envío de Correos**

* Utilizar la API de Mailjet para enviar correos electrónicos basados en las plantillas configuradas.
* Pasar las variables dinámicas necesarias para personalizar cada correo.

### Desarrollo del Microservicio

#### **Backend**

* Desarrollar endpoints para gestionar las tareas de envío de correos.
* Implementar la lógica para el procesamiento en segundo plano y el registro de historiales.

#### **Base de Datos**

* Diseñar la estructura de la base de datos para almacenar las plantillas, historial de correos y variables dinámicas.
* Asegurar que los datos sean accesibles para el microservicio y la interfaz administrativa.

### Configuraciones de Seguridad

#### **Autenticación y Autorización**

* Asegurar que solo los usuarios autorizados puedan gestionar y enviar correos.
* Implementar autenticación de dos factores (2FA) para mayor seguridad en la administración de correos.

#### **Cifrado**

* Utilizar HTTPS/TLS para proteger la transmisión de datos entre el administrador y el servidor.
* Asegurar que los datos sensibles en los correos sean cifrados en tránsito y en reposo.

### Herramientas de Monitoreo

* **Mailjet Analytics:** Para monitoreo y logs de los correos enviados.
* **AWS CloudWatch:** Para monitoreo y logs de la infraestructura.
* **Sentry:** Para rastreo y reporte de errores.

### ¿Cómo usar microservicio de Task para enviar correos electrónicos?

#### Estructurar datos en la base de datos

Para hacer envío de correos electrónicos con la aplicación de Task se debe preconfigurar los siguientes campos en la base de datos administrativa de Inlaze.

* Tabla `email_templates`
  * isActive: define si la plantilla de correo está activa.
  * name: nombre descriptivo de la plantilla.
  * section: key por la cual se va a encontrar la plantilla.
  * subject: un json con el contenido de las traducciónes del subject.
  * template\_id: el id proporcionado por Mailjet cuando creamos una plantilla.
* Tabla `emal_translated_vars`
  * language: lenguaje en cca2.
  * vars: variables a usar en la plantilla traducidas al lenguaje especificado.
  * emailTemplateId: id de la plantilla a la que hace referencia.

#### Ejemplo de plantilla de correo

```json
{
  "id": 19,
  "is_active": true,
  "name": "Registro Afiliado Notificacion a Comercial",
  "section": "affiliate-register-comercial-notify",
  "subject": { "es": "Nuevo usuario registrado" },
  "template_id": 6074026
}
```

```json
{
  "language": "es",
  "vars": {
    "footerRights": "©2024 Inlaze, Todos los derechos reservados.",
    "footerThanks": "¡Gracias por elegir Inlaze!",
    "affiliateName": "name",
    "affiliateEmail": "email",
    "footerNeedHelp": "¿Necesita ayuda?",
    "footerWeAreHere": "Nosotros estamos aquí listos para ayudarle",
    "footerTeamInlaze": "Equipo Inlaze",
    "footerKeepInTouch": "¡Manténgase conectado!"
  },
  "email_template_id": 19
}
```

En el caso mostrado tenemos que la plantilla tiene sólo traducciones para el lenguaje en español, por lo que es el lenguaje que tenemos soportado.

#### Configurar plantilla en mailjet

* Crear o editar plantilla desde el panel.
* Generar maquetado con lenguaje [MJML](https://mjml.io/).
* Posicionar variables estáticas y dinámicas de la siguiente manera: `{{var:fullName}}` .
* Copiar template id y usarlo en la configuración.

{% file src="/files/lZV3YxEbJ9Q6AdwGxGJz" %}

#### Enviar correo electrónico mediante API de Task

Para hacer esto, previamente es necesario tener todo configurado en la base de datos y la cuenta de Mailjet enlazada al proyecto.

```bash
curl --location 'https://bktask.inlaze.com/queue/apply-async' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "send",
    "data": {
        "to": "a@gmail.com",
        "section": "affiliate-register-comercial-notify",
        "context": {
            "fullName": "Abuelo"
        },
        "language": "es"
    },
    "queue": "email-queue"
}'
```

En el caso usamos el endpoint para crear tareas asíncronas

Las propiedades usadas son las siguientes:

* To: especificar el correo electrónico al que se va a enviar.
* Section: clave para poder encontrar la template en la base de datos. La misma propiedad section de `email_template`.
* Context: son las variables dinámicas que se reemplazarán en la plantilla.
* Language: el lenguaje en el que se va a enviar el mensaje.

#### Enviar correo mediante servicios de la librería inlaze-common

* Instalar librería

```bash
pnpm i @inlaze_techlead/inlaze-common
```

* Crear un módulo importable en la app, ej: `TaskModule`

```typescript
import type { DynamicModule } from "@nestjs/common";
import { Module } from "@nestjs/common";
import { BullModule } from "@nestjs/bull";
import { QUEUE_LIST, QueueService, TaskService } from "@inlaze_techlead/inlaze-common";

@Module({
  imports: [BullModule.registerQueue(...QUEUE_LIST)],
  providers: [TaskService, QueueService],
  exports: [TaskService, QueueService],
})
export class TaskModule {
  public static register({ isGlobal }: { isGlobal: boolean }): DynamicModule {
    return {
      module: TaskModule,
      global: isGlobal,
    };
  }
}
```

* Registrar bull y modulo TaskModule en la aplicación

```typescript
BullModule.forRootAsync({
  useFactory: (configService: ConfigService) => ({
    redis: {
      host: configService.get("redis.redisHost")!,
      port: configService.get("redis.redisPort")!,
      maxRetriesPerRequest: configService.get("redis.maxRetriesPerRequest"),
    },
  }),
  inject: [ConfigService],
}),
TaskModule.register({ isGlobal: true })
```

* Usar TaskService como inyectable

```typescript
await this.taskService.applyAsync<SendEmail>({
      name: "send",
      queue: "email-queue",
      data: {
        to: user.email,
        section,
        context: {
          ...context,
          name: fullName,
        },
        language: user.language,
      },
    });
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs-affiliates.inlaze.com/admin/envio-de-correos/implementacion-tecnica.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
