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, @InjectRepository(Status) private readonly statusRepository: Repository, @InjectRepository(Sistema) private readonly sistemaRepository: Repository ) { /* 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 smtp‑relay.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 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); } }