178 lines
5.0 KiB
JavaScript
178 lines
5.0 KiB
JavaScript
const admin = require("firebase-admin");
|
||
const handlebars = require("handlebars");
|
||
const fs = require("fs").promises;
|
||
const path = require("path");
|
||
const {EMAIL_CONFIG} = require("./emailConfig");
|
||
|
||
/**
|
||
* Vérifie si l'utilisateur souhaite recevoir ce type d'alerte
|
||
*/
|
||
function checkAlertPreference(alertType, preferences) {
|
||
const typeMapping = {
|
||
"EVENT_CREATED": "eventsNotifications",
|
||
"EVENT_MODIFIED": "eventsNotifications",
|
||
"EVENT_CANCELLED": "eventsNotifications",
|
||
"LOST": "equipmentNotifications",
|
||
"EQUIPMENT_MISSING": "equipmentNotifications",
|
||
"DAMAGED": "equipmentNotifications",
|
||
"QUANTITY_MISMATCH": "equipmentNotifications",
|
||
"MAINTENANCE_REMINDER": "maintenanceNotifications",
|
||
"STOCK_LOW": "stockNotifications",
|
||
};
|
||
|
||
const prefKey = typeMapping[alertType];
|
||
return prefKey ? (preferences[prefKey] !== false) : true;
|
||
}
|
||
|
||
/**
|
||
* Prépare les données pour le template
|
||
*/
|
||
async function prepareTemplateData(alert, user) {
|
||
const data = {
|
||
userName: `${user.firstName || ""} ${user.lastName || ""}`.trim() ||
|
||
"Utilisateur",
|
||
alertTitle: getAlertTitle(alert.type),
|
||
alertMessage: alert.message,
|
||
isCritical: alert.severity === "CRITICAL",
|
||
actionUrl: `${EMAIL_CONFIG.appUrl}${alert.actionUrl || "/alerts"}`,
|
||
appUrl: EMAIL_CONFIG.appUrl,
|
||
unsubscribeUrl: `${EMAIL_CONFIG.appUrl}/my_account?tab=notifications`,
|
||
year: new Date().getFullYear(),
|
||
subject: getEmailSubject(alert),
|
||
};
|
||
|
||
// Ajouter des détails selon le type d'alerte
|
||
if (alert.eventId) {
|
||
try {
|
||
const eventDoc = await admin.firestore()
|
||
.collection("events")
|
||
.doc(alert.eventId)
|
||
.get();
|
||
|
||
if (eventDoc.exists) {
|
||
const event = eventDoc.data();
|
||
data.eventName = event.Name || event.name || "Événement";
|
||
if (event.StartDateTime || event.startDate) {
|
||
const dateField = event.StartDateTime || event.startDate;
|
||
const date = dateField.toDate ? dateField.toDate() : new Date(dateField);
|
||
data.eventDate = date.toLocaleDateString("fr-FR", {
|
||
day: "2-digit",
|
||
month: "2-digit",
|
||
year: "numeric",
|
||
});
|
||
}
|
||
}
|
||
} catch (error) {
|
||
// Ignorer silencieusement
|
||
}
|
||
}
|
||
|
||
if (alert.equipmentId) {
|
||
try {
|
||
const eqDoc = await admin.firestore()
|
||
.collection("equipments")
|
||
.doc(alert.equipmentId)
|
||
.get();
|
||
|
||
if (eqDoc.exists) {
|
||
data.equipmentName = eqDoc.data().name;
|
||
}
|
||
} catch (error) {
|
||
// Ignorer silencieusement
|
||
}
|
||
}
|
||
|
||
return data;
|
||
}
|
||
|
||
/**
|
||
* Génère le titre de l'email selon le type d'alerte
|
||
*/
|
||
function getEmailSubject(alert) {
|
||
const subjects = {
|
||
"EVENT_CREATED": "📅 Nouvel événement créé",
|
||
"EVENT_MODIFIED": "📝 Événement modifié",
|
||
"EVENT_CANCELLED": "❌ Événement annulé",
|
||
"LOST": "🔴 Alerte critique : Équipement perdu",
|
||
"EQUIPMENT_MISSING": "⚠️ Équipement manquant",
|
||
"DAMAGED": "⚠️ Équipement endommagé",
|
||
"QUANTITY_MISMATCH": "ℹ️ Quantité incorrecte",
|
||
"MAINTENANCE_REMINDER": "🔧 Rappel de maintenance",
|
||
"STOCK_LOW": "📦 Stock faible",
|
||
};
|
||
|
||
return subjects[alert.type] || "🔔 Nouvelle alerte - EM2 Events";
|
||
}
|
||
|
||
/**
|
||
* Génère le titre pour le corps de l'email
|
||
*/
|
||
function getAlertTitle(type) {
|
||
const titles = {
|
||
"EVENT_CREATED": "Nouvel événement créé",
|
||
"EVENT_MODIFIED": "Événement modifié",
|
||
"EVENT_CANCELLED": "Événement annulé",
|
||
"LOST": "Équipement perdu",
|
||
"EQUIPMENT_MISSING": "Équipement manquant",
|
||
"DAMAGED": "Équipement endommagé",
|
||
"QUANTITY_MISMATCH": "Quantité incorrecte",
|
||
"MAINTENANCE_REMINDER": "Maintenance requise",
|
||
"STOCK_LOW": "Stock faible",
|
||
};
|
||
|
||
return titles[type] || "Nouvelle alerte";
|
||
}
|
||
|
||
/**
|
||
* Rend un template HTML avec Handlebars
|
||
*/
|
||
async function renderTemplate(templateName, data) {
|
||
try {
|
||
// Lire le template de base
|
||
const basePath = path.join(__dirname, "..", "templates", "base-template.html");
|
||
const baseTemplate = await fs.readFile(basePath, "utf8");
|
||
|
||
// Lire le template de contenu
|
||
const contentPath = path.join(
|
||
__dirname,
|
||
"..",
|
||
"templates",
|
||
`${templateName}.html`,
|
||
);
|
||
const contentTemplate = await fs.readFile(contentPath, "utf8");
|
||
|
||
// Compiler les templates
|
||
const compileContent = handlebars.compile(contentTemplate);
|
||
const compileBase = handlebars.compile(baseTemplate);
|
||
|
||
// Rendre le contenu
|
||
const renderedContent = compileContent(data);
|
||
|
||
// Rendre le template de base avec le contenu
|
||
return compileBase({
|
||
...data,
|
||
content: renderedContent,
|
||
});
|
||
} catch (error) {
|
||
// Fallback vers un template simple
|
||
return `
|
||
<html>
|
||
<body>
|
||
<h2>${data.alertTitle}</h2>
|
||
<p>${data.alertMessage}</p>
|
||
<a href="${data.actionUrl}">Voir l'alerte</a>
|
||
</body>
|
||
</html>
|
||
`;
|
||
}
|
||
}
|
||
|
||
module.exports = {
|
||
checkAlertPreference,
|
||
prepareTemplateData,
|
||
getEmailSubject,
|
||
getAlertTitle,
|
||
renderTemplate,
|
||
};
|
||
|