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

153 lines
4.0 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Injectable, UnauthorizedException } from '@nestjs/common';
import * as nodemailer from 'nodemailer';
import * as dotenv from 'dotenv';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Correo, Sistema, Status } from '../typeorm/votacionesPrueba.entity';
dotenv.config();
@Injectable()
export class MailService {
private transporter;
constructor(
@InjectRepository(Correo) private readonly correoRepository: Repository<Correo>,
@InjectRepository(Status) private readonly statusRepository: Repository<Status>,
@InjectRepository(Sistema) private readonly sistemaRepository: Repository<Sistema>
) {
/* this.transporter = nodemailer.createTransport({
host: 'smtp-relay.gmail.com',
port: 587,
secure: false,
requireTLS: true,
auth: {
user: process.env.USER_GMAIL,
pass: process.env.PASS_GMAIL,
},
}); */
this.transporter = nodemailer.createTransport({
host: 'smtp.gmail.com', // o smtprelay.gmail.com (ver punto 2)
port: 587,
secure: false,
requireTLS: true, // TLS STARTTLS
auth: { user: process.env.USER_GMAIL, pass: process.env.PASS_GMAIL },
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
});
/*
this.transporter = nodemailer.createTransport({
host: 'localhost',
port: 1025,
ignoreTLS: true,
});
*/
}
async findAll(TOKEN:string){
if (!TOKEN) {
throw new UnauthorizedException('Header "Password" es requerido');
}
const sistem = await this.sistemaRepository.findOne({ where: { token:TOKEN } });
if (!sistem) {
throw new UnauthorizedException('Password incorrecto');
}
const result= await this.correoRepository.find()
return result
}
async sendMail(to: string, subject: string, text: string, html: string, fecha_recibido: Date, sistema, adjuntos?: any[] ) {
console.log("estos son los archivos adjuntos en el service",adjuntos);
const mailOptions = {
from: process.env.USER_GMAIL,
to,
subject,
text,
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
};
})
};
console.log(mailOptions);
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,
id_sistema: sistema,
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 (statusTexto);
}
}