develop #1
@@ -0,0 +1,6 @@
|
||||
node_modules
|
||||
dist
|
||||
.git
|
||||
.env
|
||||
*.log
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# Gmail
|
||||
USER_GMAIL=
|
||||
PASS_GMAIL=
|
||||
|
||||
# MariaDB database settings
|
||||
db_type=mysql
|
||||
db_host=mariadb # <-- uso del nombre del servicio, NO IP
|
||||
db_port=3306
|
||||
db_username=root # <-- te conectarás con root
|
||||
db_password=mypass # <-- la misma que MARIADB_ROOT_PASSWORD
|
||||
db_database=ApiCorreos
|
||||
|
||||
# Puerto de la aplicación
|
||||
PORT=4100
|
||||
@@ -1,3 +1,7 @@
|
||||
|
||||
*.tar
|
||||
|
||||
|
||||
# compiled output
|
||||
/dist
|
||||
/node_modules
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
# Etapa de construcción
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
# Etapa de producción
|
||||
FROM node:20-alpine AS production
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/dist ./dist
|
||||
COPY --from=builder /app/package*.json ./
|
||||
|
||||
EXPOSE 4100
|
||||
|
||||
CMD ["node", "dist/main"]
|
||||
@@ -0,0 +1,32 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
mariadb:
|
||||
image: mariadb:latest
|
||||
container_name: mariadb-service
|
||||
ports:
|
||||
- "4101:3306"
|
||||
environment:
|
||||
MARIADB_ROOT_PASSWORD: mypass
|
||||
MARIADB_DATABASE: ApiCorreos
|
||||
volumes:
|
||||
- mariadb_data:/var/lib/mysql
|
||||
|
||||
api:
|
||||
image: correos_api:v0 # <--- la imagen final (comprobada en el paso anterior)
|
||||
container_name: nestjs-api
|
||||
environment:
|
||||
# Ajustar estas vars a tu conveniencia
|
||||
db_host: mariadb
|
||||
db_port: 3306
|
||||
db_username: root
|
||||
db_password: mypass
|
||||
db_database: ApiCorreos
|
||||
PORT: 4100
|
||||
ports:
|
||||
- "4100:4100"
|
||||
depends_on:
|
||||
- mariadb
|
||||
|
||||
volumes:
|
||||
mariadb_data:
|
||||
@@ -0,0 +1,28 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
mariadb:
|
||||
image: mariadb:latest
|
||||
container_name: mariadb-service
|
||||
ports:
|
||||
- "4101:3306"
|
||||
environment:
|
||||
MARIADB_ROOT_PASSWORD: mypass
|
||||
MARIADB_DATABASE: ApiCorreos
|
||||
volumes:
|
||||
- mariadb_data:/var/lib/mysql
|
||||
|
||||
api:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
container_name: nestjs-api
|
||||
env_file:
|
||||
- .env
|
||||
ports:
|
||||
- "4100:4100"
|
||||
depends_on:
|
||||
- mariadb
|
||||
|
||||
volumes:
|
||||
mariadb_data:
|
||||
@@ -31,9 +31,14 @@ export class MailController {
|
||||
@ApiSendMail()
|
||||
async sendMail(
|
||||
@Headers() headers:{password:string},
|
||||
@Body() body: { to: string; subject: string; text: string; fecha_recibido: Date }) {
|
||||
|
||||
@Body() body: { to: string; subject: string; text: string; fecha_recibido: Date, html:string, adjuntos:any }) {
|
||||
|
||||
/*
|
||||
|
||||
// esta parte hay que rehacerla, se tiene que obtener la contraseña del sistema en base a la clave del sistema.
|
||||
// debe de existir un modulo para crear contraseñas para las apis y administrar esas contraseñas
|
||||
|
||||
|
||||
if (!headers.password) {
|
||||
throw new UnauthorizedException('Header "Password" es requerido');
|
||||
}
|
||||
@@ -42,12 +47,17 @@ export class MailController {
|
||||
|
||||
if (!sistem) {
|
||||
throw new UnauthorizedException('Password incorrecto');
|
||||
}
|
||||
} */
|
||||
|
||||
|
||||
const { to, subject, text, fecha_recibido } = body;
|
||||
|
||||
|
||||
console.log("estos son los archivos adjuntos en el controller",body);
|
||||
|
||||
const result = await this.mailService.sendMail(to, subject, text, fecha_recibido,sistem);
|
||||
|
||||
|
||||
const { to, subject, text, html, fecha_recibido, adjuntos } = body;
|
||||
|
||||
const result = await this.mailService.sendMail(to, subject, text,html, fecha_recibido,1,adjuntos); // sistem
|
||||
return result;
|
||||
|
||||
|
||||
@@ -79,7 +89,7 @@ export class MailController {
|
||||
|
||||
for (const email of await emails) {
|
||||
try {
|
||||
await this.mailService.sendMail(email, "subject", "text", fechaActual,sistem);
|
||||
await this.mailService.sendMail(email, "subject", "text","html", fechaActual,sistem);
|
||||
console.log(`📧 Enviado a: ${email}`);
|
||||
} catch (error) {
|
||||
console.error(`❌ Error enviando a ${email}:`, error.message);
|
||||
|
||||
+10
-23
@@ -1,5 +1,5 @@
|
||||
import { applyDecorators } from '@nestjs/common';
|
||||
import { ApiBody, ApiConsumes, ApiOperation, ApiResponse } from '@nestjs/swagger';
|
||||
import { ApiBody, ApiConsumes, ApiHeader, ApiOperation, ApiResponse } from '@nestjs/swagger';
|
||||
|
||||
export const ApiSendMail = () => {
|
||||
return applyDecorators(
|
||||
@@ -9,7 +9,14 @@ export const ApiSendMail = () => {
|
||||
- **to**: Dirección de correo del destinatario.
|
||||
- **subject**: Asunto del correo.
|
||||
- **text**: Cuerpo del mensaje.
|
||||
- **fecha_recibido**: Fecha en que se registró la solicitud.`,
|
||||
- **fecha_recibido**: Fecha en que se registró la solicitud.
|
||||
- **sistema**: contraseña del sistema.`,
|
||||
}),
|
||||
ApiHeader({
|
||||
name: 'password',
|
||||
description: 'Contraseña del sistema para autenticación',
|
||||
required: true,
|
||||
example: 'mi-password-segura'
|
||||
}),
|
||||
ApiBody({
|
||||
description: 'Datos del correo a enviar',
|
||||
@@ -22,27 +29,7 @@ export const ApiSendMail = () => {
|
||||
fecha_recibido: { type: 'string', format: 'date-time', example: '2025-03-10T12:00:00Z' }
|
||||
},
|
||||
},
|
||||
}),
|
||||
ApiResponse({
|
||||
status: 200,
|
||||
description: 'Correo enviado con éxito',
|
||||
schema: {
|
||||
example: {
|
||||
message: 'Correo enviado correctamente',
|
||||
},
|
||||
},
|
||||
}),
|
||||
ApiResponse({
|
||||
status: 400,
|
||||
description: 'Error en el envío del correo',
|
||||
schema: {
|
||||
example: {
|
||||
statusCode: 400,
|
||||
message: 'Dirección de correo inválida',
|
||||
error: 'Bad Request',
|
||||
},
|
||||
},
|
||||
}),
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -42,18 +42,49 @@ export class MailService {
|
||||
// Función para generar el reporte de correos enviados y fallidos
|
||||
|
||||
|
||||
async sendMail(to: string, subject: string, text: string, fecha_recibido: Date, sistema) {
|
||||
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 } });
|
||||
|
||||
|
||||
@@ -70,11 +101,13 @@ export class MailService {
|
||||
destinatario: to,
|
||||
remitente: process.env.USER_GMAIL,
|
||||
|
||||
});
|
||||
}); */
|
||||
|
||||
|
||||
if(!resMail){
|
||||
throw new Error("fallo")
|
||||
}
|
||||
this.correoRepository.save(info);
|
||||
//this.correoRepository.save(info);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,9 @@ import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule);
|
||||
|
||||
|
||||
app.enableCors();
|
||||
|
||||
const config = new DocumentBuilder()
|
||||
.setTitle('Documentacion de la api de votaciones_mails v2')
|
||||
.setDescription(
|
||||
@@ -18,5 +21,7 @@ async function bootstrap() {
|
||||
SwaggerModule.setup('documentation', app, document);
|
||||
|
||||
await app.listen(process.env.PORT ?? 3000);
|
||||
|
||||
console.log(`Aplicación corriendo en: http://localhost:${process.env.PORT ?? 3000}`);
|
||||
}
|
||||
bootstrap();
|
||||
|
||||
Reference in New Issue
Block a user