feat: mejorar el envío de correos electrónicos y agregar validaciones en el adaptador de notificaciones

This commit is contained in:
2026-08-19 14:51:42 -03:00
parent 18fa523fbe
commit c8029a6762
5 changed files with 87 additions and 93 deletions
@@ -3,13 +3,37 @@ import { INotificationsAdapter, NotificationDataEmail } from "./Notifications.In
export class NotificationsDonWebAdapter implements INotificationsAdapter<NotificationDataEmail> {
async send(data: NotificationDataEmail): Promise<void> {
const dataEmail = {
if (data.context && data.substitutions) {
throw new Error("No se puede enviar un email con context y substitutions al mismo tiempo.");
}
if (!data.templateId && !data.message) {
throw new Error("Debe indicarse el contenido del email mediante message o templateId.");
}
const dataEmail: Record<string, unknown> = {
from: "norepply@turnosxpress.com.ar",
to: data.email,
subject: data.subject,
html: data.message,
};
if (data.templateId) {
dataEmail.templateID = data.templateId;
} else {
dataEmail.html = data.message;
}
if (data.subject) {
dataEmail.subject = data.subject;
}
if (data.context) {
dataEmail.context = data.context;
}
if (data.substitutions) {
dataEmail.substitutions = data.substitutions;
}
const apiConfig = {
method: "post",
maxBodyLength: Infinity,
@@ -6,8 +6,11 @@ export enum NOTIFICATION_TYPES {
export type NotificationDataEmail = {
email: string;
subject: string;
message: string;
subject?: string;
message?: string;
templateId?: string;
context?: Record<string, unknown>;
substitutions?: Record<string, string | number | boolean>;
};
export type NotificationDataWap = {
+54 -6
View File
@@ -351,6 +351,28 @@ class UsersManager implements IUsersManager {
.substring(0, 6);
}
private async sendWelcomeEmail(email: string, firstName?: string): Promise<void> {
try {
await NotificationsManager.sendEmail({
email: cleanEmail(email),
templateId: "68139f23f3e003139b08b4f0",
context: {
username: firstName || cleanEmail(email),
},
});
} catch (e) {
if (axios.isAxiosError(e)) {
console.error("Error enviando email de bienvenida:", {
status: e.response?.status,
data: e.response?.data,
});
return;
}
console.error("Error enviando email de bienvenida:", e);
}
}
public async signUp(data: SignUpParams): Promise<IUser> {
// Destructure email and password from the data object
const {
@@ -406,12 +428,13 @@ class UsersManager implements IUsersManager {
const newUser = await this.users.create(newUserData);
const signUpUrl = "https://turnosxpress.com.ar/landing/login/verification";
await NotificationsManager.sendEmail({
email: cleanEmail(email),
subject: "TurnosXpress :: Bienvenido/a",
message: `Hola ${firstName}, Gracias por registrarte en turnosXpress. Primero debes activar tu cuenta ingresando en ${signUpUrl} . Tu código de verificación es: ${verificationCode}`,
templateId: "6a85dd644ea98ccfcd05bdc7",
context: {
username: firstName || cleanEmail(email),
verificationcode: verificationCode,
},
});
return newUser;
@@ -459,8 +482,11 @@ class UsersManager implements IUsersManager {
await NotificationsManager.sendEmail({
email: cleanEmail(data.email),
subject: "TurnosXpress :: Recuperación de cuenta",
message: `Hola ${user.firstName}, Te enviamos un código de verificación para recuperar tu cuenta. Tu código de verificación es: ${code}. Ingresa https://turnosxpress.com.ar/landing/recover-account/verify para establecer una nueva clave`,
templateId: "6a85c7ad96475f2825015277",
context: {
username: user.firstName || cleanEmail(data.email),
verificationcode: code,
},
});
return;
@@ -515,10 +541,16 @@ class UsersManager implements IUsersManager {
throw new Error("El código de verificación es incorrecto");
}
const wasVerificated = Boolean(userTest.verificated);
userTest.verificated = true;
await userTest.save();
if (!wasVerificated) {
await this.sendWelcomeEmail(userTest.email, userTest.firstName);
}
try {
const freePlan = await PlansList.plans.findOne({ price: 0 });
if (freePlan) {
@@ -724,11 +756,17 @@ class UsersManager implements IUsersManager {
});
if (userCheck) {
const wasVerificated = Boolean(userCheck.verificated);
userCheck.external_id = googleUserId;
userCheck.external_service = "google";
userCheck.verificated = true;
await userCheck.save();
if (!wasVerificated) {
await this.sendWelcomeEmail(userCheck.email, userCheck.firstName);
}
const subscription = await PlanSubscriptionsList.getSubscriptionByUser({
sessionUser: userCheck.id,
});
@@ -770,6 +808,8 @@ class UsersManager implements IUsersManager {
throw new Error("Error creating user");
}
await this.sendWelcomeEmail(newUser.email, newUser.firstName);
const subscription = await PlanSubscriptionsList.getSubscriptionByUser({
sessionUser: newUser.id,
});
@@ -821,11 +861,17 @@ class UsersManager implements IUsersManager {
});
if (userCheck) {
const wasVerificated = Boolean(userCheck.verificated);
userCheck.external_id = googleData.id;
userCheck.external_service = "google";
userCheck.verificated = true;
await userCheck.save();
if (!wasVerificated) {
await this.sendWelcomeEmail(userCheck.email, userCheck.firstName);
}
const subscription = await PlanSubscriptionsList.getSubscriptionByUser({
sessionUser: userCheck.id,
});
@@ -867,6 +913,8 @@ class UsersManager implements IUsersManager {
throw new Error("Error creating user");
}
await this.sendWelcomeEmail(newUser.email, newUser.firstName);
const subscription = await PlanSubscriptionsList.getSubscriptionByUser({
sessionUser: newUser.id,
});