85 lines
2.9 KiB
JavaScript
85 lines
2.9 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}`);
|
|
}
|
|
}
|
|
|
|
processTemplate(template, variables) {
|
|
if (!template) return '';
|
|
|
|
let processed = template;
|
|
|
|
// Handle conditional blocks {{#if VARIABLE}}...{{/if}}
|
|
processed = processed.replace(/\{\{#if\s+(\w+)\}\}([\s\S]*?)\{\{\/if\}\}/g, (match, varName, content) => {
|
|
const value = variables[varName];
|
|
// Check if value exists and is not empty string
|
|
if (value !== undefined && value !== null && value !== '') {
|
|
// Recursively process the content inside the conditional block
|
|
return this.processTemplate(content, variables);
|
|
}
|
|
return '';
|
|
});
|
|
|
|
// Replace variables {{VARIABLE}}
|
|
processed = processed.replace(/\{\{(\w+)\}\}/g, (match, varName) => {
|
|
const value = variables[varName];
|
|
// Return the value or empty string if undefined
|
|
return value !== undefined && value !== null ? String(value) : '';
|
|
});
|
|
|
|
return processed;
|
|
}
|
|
|
|
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')
|
|
]);
|
|
|
|
// Use processTemplate which handles conditionals properly
|
|
return {
|
|
html: this.processTemplate(htmlTemplate, variables),
|
|
text: this.processTemplate(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();
|