import nodemailer, { Transporter } from "nodemailer"; import { MailBuilder, MailOptions, MailUseCases, Response } from "../build"; /** * Clase para el proveedor de correo Gmail. * Extiende `MailBuilder` para integrar la funcionalidad de envío de correos a través de Gmail, * utilizando Nodemailer internamente con una configuración de servicio 'Gmail'. * * @template Config - El tipo de configuración específica para el transportador de Gmail (ej. credenciales OAuth2). * Debe ser compatible con las opciones de configuración de Nodemailer para Gmail. */ export class Gmail extends MailBuilder implements MailUseCases { /** * Crea una instancia del proveedor de correo Gmail. * Configura el transportador de Nodemailer con el servicio 'Gmail' automáticamente. * * @param {Config} smtpConfig - El objeto de configuración SMTP o OAuth2 para Gmail. * Debe contener las credenciales necesarias (ej., user, clientId, clientSecret, refreshToken). */ constructor(smtpConfig: Config) { // Llama al constructor de la clase base (MailBuilder). // Añade automáticamente 'service: "Gmail"' a la configuración proporcionada. super({ ...smtpConfig, service: 'Gmail' }, nodemailer.createTransport); } /** * Envía un correo electrónico utilizando el transportador de Gmail configurado. * * @template T - El tipo de respuesta esperada, que debe extender la interfaz `Response`. * @param {MailOptions} options - Las opciones del correo electrónico a enviar (destinatario, asunto, etc.). * @param {string} templateMain - El contenido HTML del cuerpo del correo, ya renderizado a partir de una plantilla. * @returns {Promise} Una promesa que se resuelve con un objeto de respuesta que contiene el `messageId` * y potencialmente `getTestMessageUrl`. * @throws {Error} Si ocurre un error durante el proceso de envío del correo. */ async sendMail(options: MailOptions, templateMain: string): Promise { try { // Envía el correo usando el transportador interno (Nodemailer). // La propiedad 'html' se establece con el contenido de la plantilla ya renderizado. const result = await this.transporter.sendMail({ ...options, html: templateMain }); // TODO: Asegurarse de que el 'result' de Nodemailer se mapee correctamente a la interfaz 'Response'. // Nodemailer devuelve un objeto con 'messageId', 'response', 'envelope', 'accepted', 'rejected', etc. // Es posible que necesites un paso de mapeo explícito aquí para asegurar que 'getTestMessageUrl' // y otras propiedades de 'Response' estén presentes o sean 'undefined'. return result as T; } catch (error: any) { console.error("Error al enviar correo:", error?.message || error); throw error; } } }