Files
correos_api/src/mail/mail.service.ts
T

198 lines
5.6 KiB
TypeScript
Raw Normal View History

2025-02-27 12:41:56 -06:00
import { Injectable } from '@nestjs/common';
import * as nodemailer from 'nodemailer';
import * as dotenv from 'dotenv';
2025-03-07 14:14:37 -06:00
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Correo, Status } from 'src/typeorm/votacionesPrueba.entity';
2025-02-27 12:41:56 -06:00
dotenv.config();
@Injectable()
export class MailService {
private transporter;
2025-03-07 14:14:37 -06:00
constructor(
@InjectRepository(Correo) private readonly correoRepository: Repository<Correo>,
@InjectRepository(Status) private readonly statusRepository: Repository<Status>,
) {
2025-02-27 12:41:56 -06:00
this.transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.USER_GMAIL, // tu dirección de correo de Gmail
pass: process.env.PASS_GMAIL, // contraseña de aplicación generada en Google
},
});
/*
this.transporter = nodemailer.createTransport({
host: 'localhost',
port: 1025,
ignoreTLS: true,
});
*/
}
// Función para generar el reporte de correos enviados y fallidos
private generateReport(
sentEmails: string[],
failedEmails: { email: string; error: any }[],
totalTime: number,
) {
console.log('--- Reporte de envío de correos ---');
console.log(`Tiempo total de envío: ${totalTime} segundos`);
console.log('\nCorreos enviados con éxito:');
sentEmails.forEach((email) => console.log(email));
console.log('\nCorreos fallidos:');
failedEmails.forEach((failed) =>
console.log(`Correo: ${failed.email} - Error: ${failed.error.message}`),
);
console.log(`\nTotal de correos enviados: ${sentEmails.length}`);
console.log(`Total de correos fallidos: ${failedEmails.length}`);
if (failedEmails.length > 0) {
console.log(
'\nAlgunos correos fallaron. Inténtalos de nuevo de manera manual.',
);
}
}
2025-03-07 14:14:37 -06:00
async sendMail(to: string, subject: string, text: string, fecha_recibido: Date) {
2025-02-27 12:41:56 -06:00
const mailOptions = {
from: process.env.USER_GMAIL,
to,
subject,
text,
};
2025-03-07 14:14:37 -06:00
let resMail = await this.transporter.sendMail(mailOptions);
const statusTexto = resMail.accepted.length > 0 ? "Enviado" : "Fallido";
let status = await this.statusRepository.findOne({ where: { status: statusTexto } });
if (!status) {
status = this.statusRepository.create({ status: statusTexto });
await this.statusRepository.save(status);
}
const info= this.correoRepository.create({
id_status: status,
fecha_recibido: fecha_recibido,
fecha_enviado: new Date(),
destinatario: to,
remitente: process.env.USER_GMAIL,
});
if(!resMail){
throw new Error("fallo")
}
this.correoRepository.save(info);
return
2025-02-27 12:41:56 -06:00
}
async sendBulkMailsOld(emails: string[], subject: string, text: string) {
const batchSize = 100; // Número de correos por lote
for (let i = 0; i < emails.length; i += batchSize) {
const batch = emails.slice(i, i + batchSize);
const promises = batch.map((email) =>
this.transporter.sendMail({
from: process.env.USER_GMAIL,
to: email,
subject,
text,
}),
);
// Esperar que se envíen todos los correos del lote
await Promise.all(promises);
// Delay entre lotes para no sobrecargar el servidor de Gmail
await new Promise((resolve) => setTimeout(resolve, 2000)); // 2 segundos de pausa
}
}
async sendBulkMails(emails: string[], subject: string, text: string) {
const batchSize = 100;
const sentEmails: string[] = [];
const failedEmails: { email: string; error: any }[] = [];
const startTime = Date.now(); // Inicia el temporizador
for (let i = 0; i < emails.length; i += batchSize) {
const batch = emails.slice(i, i + batchSize);
const promises = batch.map(async (email) => {
try {
await this.transporter.sendMail({
from: process.env.USER_GMAIL,
to: email,
subject,
text,
});
sentEmails.push(email); // Agregar a lista de enviados exitosamente
} catch (error) {
failedEmails.push({ email, error }); // Agregar a lista de fallos
}
});
// Espera a que todos los correos del lote se envíen
await Promise.all(promises);
// Delay para evitar saturar el servidor de correo
await new Promise((resolve) => setTimeout(resolve, 2000));
}
const totalTime = (Date.now() - startTime) / 1000; // Tiempo total en segundos
// Generar el reporte final
this.generateReport(sentEmails, failedEmails, totalTime);
}
async retryFailedEmails(
failedEmails: { email: string; error: any }[],
subject: string,
text: string,
) {
const retrySuccess: string[] = [];
const retryFailed: { email: string; error: any }[] = [];
for (const failed of failedEmails) {
try {
await this.transporter.sendMail({
from: process.env.USER_GMAIL,
to: failed.email,
subject,
text,
});
retrySuccess.push(failed.email); // Reintento exitoso
} catch (error) {
retryFailed.push({ email: failed.email, error }); // Reintento fallido
}
}
console.log('--- Reintento de correos fallidos ---');
console.log('\nCorreos reenviados con éxito:');
retrySuccess.forEach((email) => console.log(email));
console.log('\nCorreos que fallaron nuevamente:');
retryFailed.forEach((failed) =>
console.log(`Correo: ${failed.email} - Error: ${failed.error.message}`),
);
}
}