freealberta/map/app/services/emailTemplates.js

70 lines
2.1 KiB
JavaScript

const fs = require('fs').promises;
const path = require('path');
const logger = require('../utils/logger');
class EmailTemplateService {
constructor() {
this.templatesDir = path.join(__dirname, '../templates/email');
this.cache = new Map();
}
async loadTemplate(templateName, type = 'html') {
const cacheKey = `${templateName}.${type}`;
// Check cache first
if (this.cache.has(cacheKey)) {
return this.cache.get(cacheKey);
}
try {
const templatePath = path.join(this.templatesDir, `${templateName}.${type}`);
const template = await fs.readFile(templatePath, 'utf-8');
// Cache the template
this.cache.set(cacheKey, template);
return template;
} catch (error) {
logger.error(`Failed to load email template ${templateName}.${type}:`, error);
throw new Error(`Email template not found: ${templateName}.${type}`);
}
}
renderTemplate(template, variables) {
let rendered = template;
// Replace all {{VARIABLE}} with actual values
Object.entries(variables).forEach(([key, value]) => {
const regex = new RegExp(`{{${key}}}`, 'g');
rendered = rendered.replace(regex, value || '');
});
return rendered;
}
async render(templateName, variables) {
try {
// Load both HTML and text versions
const [htmlTemplate, textTemplate] = await Promise.all([
this.loadTemplate(templateName, 'html'),
this.loadTemplate(templateName, 'txt')
]);
return {
html: this.renderTemplate(htmlTemplate, variables),
text: this.renderTemplate(textTemplate, variables)
};
} catch (error) {
logger.error('Failed to render email template:', error);
throw error;
}
}
// Clear template cache (useful for development)
clearCache() {
this.cache.clear();
}
}
module.exports = new EmailTemplateService();