135 lines
4.7 KiB
JavaScript
135 lines
4.7 KiB
JavaScript
const fs = require('fs').promises;
|
|
const path = require('path');
|
|
|
|
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) {
|
|
console.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) : '';
|
|
});
|
|
|
|
// Handle line breaks in MESSAGE field for HTML templates
|
|
if (variables.MESSAGE && processed.includes('{{MESSAGE}}')) {
|
|
processed = processed.replace(/\{\{MESSAGE\}\}/g, variables.MESSAGE.replace(/\n/g, '<br>'));
|
|
}
|
|
|
|
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')
|
|
]);
|
|
|
|
// Add default variables
|
|
const defaultVariables = {
|
|
APP_NAME: process.env.APP_NAME || 'BNKops Influence Campaign',
|
|
TIMESTAMP: new Date().toLocaleString(),
|
|
...variables
|
|
};
|
|
|
|
// Use processTemplate which handles conditionals properly
|
|
return {
|
|
html: this.processTemplate(htmlTemplate, defaultVariables),
|
|
text: this.processTemplate(textTemplate, defaultVariables)
|
|
};
|
|
} catch (error) {
|
|
console.error('Failed to render email template:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Get available template names
|
|
async getAvailableTemplates() {
|
|
try {
|
|
const files = await fs.readdir(this.templatesDir);
|
|
const templates = new Set();
|
|
|
|
files.forEach(file => {
|
|
const ext = path.extname(file);
|
|
const name = path.basename(file, ext);
|
|
if (ext === '.html' || ext === '.txt') {
|
|
templates.add(name);
|
|
}
|
|
});
|
|
|
|
return Array.from(templates);
|
|
} catch (error) {
|
|
console.error('Failed to get available templates:', error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
// Clear template cache (useful for development)
|
|
clearCache() {
|
|
this.cache.clear();
|
|
console.log('Email template cache cleared');
|
|
}
|
|
|
|
// Check if template exists
|
|
async templateExists(templateName) {
|
|
try {
|
|
const htmlPath = path.join(this.templatesDir, `${templateName}.html`);
|
|
const txtPath = path.join(this.templatesDir, `${templateName}.txt`);
|
|
|
|
// Check if at least one format exists
|
|
const [htmlExists, txtExists] = await Promise.all([
|
|
fs.access(htmlPath).then(() => true).catch(() => false),
|
|
fs.access(txtPath).then(() => true).catch(() => false)
|
|
]);
|
|
|
|
return htmlExists || txtExists;
|
|
} catch (error) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = new EmailTemplateService(); |