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';
|
2025-04-23 15:57:52 -06:00
|
|
|
|
import { Correo, Sistema, Status } from '../typeorm/votacionesPrueba.entity';
|
2025-02-28 14:44:40 -06:00
|
|
|
|
|
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(
|
2025-03-11 15:47:32 -06:00
|
|
|
|
@InjectRepository(Correo) private readonly correoRepository: Repository<Correo>,
|
2025-03-07 14:14:37 -06:00
|
|
|
|
@InjectRepository(Status) private readonly statusRepository: Repository<Status>,
|
|
|
|
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
2025-02-27 12:41:56 -06:00
|
|
|
|
|
|
|
|
|
|
|
2025-04-22 09:48:21 -06:00
|
|
|
|
/* this.transporter = nodemailer.createTransport({
|
2025-04-21 12:59:59 -06:00
|
|
|
|
host: 'smtp-relay.gmail.com',
|
|
|
|
|
|
port: 587,
|
|
|
|
|
|
secure: false,
|
|
|
|
|
|
requireTLS: true,
|
|
|
|
|
|
auth: {
|
|
|
|
|
|
user: process.env.USER_GMAIL,
|
|
|
|
|
|
pass: process.env.PASS_GMAIL,
|
|
|
|
|
|
},
|
2025-04-22 09:48:21 -06:00
|
|
|
|
}); */
|
|
|
|
|
|
|
|
|
|
|
|
this.transporter = nodemailer.createTransport({
|
|
|
|
|
|
host: 'smtp.gmail.com', // o smtp‑relay.gmail.com (ver punto 2)
|
|
|
|
|
|
port: 587,
|
2025-04-22 10:05:20 -06:00
|
|
|
|
secure: false,
|
|
|
|
|
|
requireTLS: true, // TLS STARTTLS
|
2025-04-22 10:09:22 -06:00
|
|
|
|
auth: { user: process.env.USER_GMAIL, pass: process.env.PASS_GMAIL },
|
2025-04-22 09:48:21 -06:00
|
|
|
|
pool: true, // <‑‑ activa reuse
|
|
|
|
|
|
maxConnections: 1, // una sola conexión viva
|
|
|
|
|
|
maxMessages: 100, // reabrir después de 100 envíos
|
|
|
|
|
|
rateDelta: 2000, // ventana 1 s
|
|
|
|
|
|
rateLimit: 1 // máx. 5 mensajes/seg
|
2025-04-21 12:59:59 -06:00
|
|
|
|
});
|
2025-02-27 12:41:56 -06:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
this.transporter = nodemailer.createTransport({
|
|
|
|
|
|
host: 'localhost',
|
|
|
|
|
|
port: 1025,
|
|
|
|
|
|
ignoreTLS: true,
|
|
|
|
|
|
});
|
|
|
|
|
|
*/
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Función para generar el reporte de correos enviados y fallidos
|
2025-04-23 15:57:52 -06:00
|
|
|
|
async findAll(){
|
|
|
|
|
|
const result= await this.correoRepository.find({relations:['id_sistema','id_status']})
|
|
|
|
|
|
return result
|
|
|
|
|
|
}
|
2025-02-27 12:41:56 -06:00
|
|
|
|
|
2025-04-03 11:17:00 -06:00
|
|
|
|
async sendMail(to: string, subject: string, text: string, html: string, fecha_recibido: Date, sistema, adjuntos?: any[] ) {
|
2025-04-23 15:57:52 -06:00
|
|
|
|
|
|
|
|
|
|
|
2025-04-03 11:17:00 -06:00
|
|
|
|
|
|
|
|
|
|
console.log("estos son los archivos adjuntos en el service",adjuntos);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-02-27 12:41:56 -06:00
|
|
|
|
const mailOptions = {
|
|
|
|
|
|
from: process.env.USER_GMAIL,
|
|
|
|
|
|
to,
|
|
|
|
|
|
subject,
|
|
|
|
|
|
text,
|
2025-04-03 11:17:00 -06:00
|
|
|
|
html,
|
|
|
|
|
|
|
|
|
|
|
|
// OJO: nodemailer usa 'attachments', no 'adjuntos'
|
|
|
|
|
|
attachments: (adjuntos || []).map((adj) => {
|
|
|
|
|
|
// Asegúrate de no incluir 'data:image/png;base64,' en 'content'
|
|
|
|
|
|
let base64Clean = adj.content;
|
|
|
|
|
|
// Si viene con prefijo "data:image...", lo quitamos
|
|
|
|
|
|
if (base64Clean.startsWith('data:image/')) {
|
|
|
|
|
|
base64Clean = base64Clean.split('base64,')[1];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
filename: adj.filename || 'qr.png',
|
|
|
|
|
|
content: Buffer.from(base64Clean, adj.encoding || 'base64'),
|
|
|
|
|
|
cid: adj.cid || 'qrCode', // el mismo que uses en <img src="cid:..."/>
|
|
|
|
|
|
contentType: 'image/png' // recomendable para que sepa que es PNG
|
|
|
|
|
|
};
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-02-27 12:41:56 -06:00
|
|
|
|
};
|
|
|
|
|
|
|
2025-04-03 11:17:00 -06:00
|
|
|
|
|
|
|
|
|
|
console.log(mailOptions);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-03-07 14:14:37 -06:00
|
|
|
|
let resMail = await this.transporter.sendMail(mailOptions);
|
|
|
|
|
|
const statusTexto = resMail.accepted.length > 0 ? "Enviado" : "Fallido";
|
|
|
|
|
|
|
2025-04-23 15:57:52 -06:00
|
|
|
|
|
2025-03-07 14:14:37 -06:00
|
|
|
|
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,
|
2025-03-15 12:02:41 -06:00
|
|
|
|
id_sistema: sistema,
|
2025-03-07 14:14:37 -06:00
|
|
|
|
fecha_recibido: fecha_recibido,
|
|
|
|
|
|
fecha_enviado: new Date(),
|
|
|
|
|
|
destinatario: to,
|
|
|
|
|
|
remitente: process.env.USER_GMAIL,
|
|
|
|
|
|
|
2025-04-23 15:57:52 -06:00
|
|
|
|
});
|
2025-04-02 09:50:01 -06:00
|
|
|
|
|
|
|
|
|
|
|
2025-03-07 14:14:37 -06:00
|
|
|
|
if(!resMail){
|
|
|
|
|
|
throw new Error("fallo")
|
|
|
|
|
|
}
|
2025-04-23 15:57:52 -06:00
|
|
|
|
this.correoRepository.save(info);
|
2025-03-07 14:14:37 -06:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-03-15 12:02:41 -06:00
|
|
|
|
return (statusTexto);
|
2025-02-27 12:41:56 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-15 12:02:41 -06:00
|
|
|
|
|
|
|
|
|
|
|
2025-02-27 12:41:56 -06:00
|
|
|
|
}
|