import { Injectable, Logger } from "@nestjs/common"; import { TemplatesService } from "./templates.service"; // import { PersonalityDataType, SectionItemType, TextType } from "../interfaces/structure.interface"; interface ProcessedTemplateResult { html: string; text: string; hasTemplate: boolean; } @Injectable() export class TemplateProcessorService { private readonly logger = new Logger(TemplateProcessorService.name); constructor(private readonly templatesService: TemplatesService) {} /** * Process email content through business template */ async processEmailWithTemplate( businessId: string, emailContent: { text?: string; html?: string; subject?: string }, // userId?: string, ): Promise { try { this.logger.log(`Processing email with template for business: ${businessId}`); // Get business templates const templates = await this.templatesService.getTemplatesByBusinessId(businessId); if (!templates || templates.length === 0) { this.logger.log(`No templates found for business: ${businessId}, using original content`); return { html: emailContent.html || this.convertTextToHtml(emailContent.text || ""), text: emailContent.text || this.stripHtmlTags(emailContent.html || ""), hasTemplate: false, }; } // Use the first template const template = templates[0]; this.logger.log(`Using template: ${template.name} for email processing`); // Process the template with email content const processedContent = await this.injectContentIntoTemplate(emailContent, template.rawHtml); return { html: processedContent.html, text: processedContent.text, hasTemplate: true, }; } catch (error) { this.logger.error(`Failed to process email with template for business ${businessId}:`, error); // Fallback to original content if template processing fails return { html: emailContent.html || this.convertTextToHtml(emailContent.text || ""), text: emailContent.text || this.stripHtmlTags(emailContent.html || ""), hasTemplate: false, }; } } /** * Inject email content into template structure */ private async injectContentIntoTemplate( // templateStructure: Record, emailContent: { text?: string; html?: string; subject?: string }, rawHtml?: string, ): Promise<{ html: string; text: string }> { try { // If template has raw HTML, use it as base and inject content if (rawHtml) { const html = this.injectContentIntoRawHtml(rawHtml, emailContent); return { html, text: this.stripHtmlTags(html), }; } // Otherwise, build simple HTML with email content const html = this.buildSimpleTemplate(emailContent); return { html, text: this.stripHtmlTags(html), }; } catch (error) { this.logger.error("Failed to inject content into template:", error); throw error; } } /** * Inject email content into raw HTML template */ private injectContentIntoRawHtml(rawHtml: string, emailContent: { text?: string; html?: string; subject?: string }): string { let processedHtml = rawHtml; // Replace placeholders with actual content const contentToInject = emailContent.html || this.convertTextToHtml(emailContent.text || ""); // Common placeholder patterns const placeholders = [/\{\{content\}\}/gi, /\{\{message\}\}/gi, /\{\{body\}\}/gi, /\{content\}/gi, /\{message\}/gi, /\{body\}/gi]; placeholders.forEach((placeholder) => { processedHtml = processedHtml.replace(placeholder, contentToInject); }); // Replace subject placeholders if (emailContent.subject) { const subjectPlaceholders = [/\{\{subject\}\}/gi, /\{\{title\}\}/gi, /\{subject\}/gi, /\{title\}/gi]; subjectPlaceholders.forEach((placeholder) => { processedHtml = processedHtml.replace(placeholder, emailContent.subject!); }); } return processedHtml; } /** * Build simple HTML template */ private buildSimpleTemplate(emailContent: { text?: string; html?: string; subject?: string }): string { const content = emailContent.html || this.convertTextToHtml(emailContent.text || ""); return ` ${emailContent.subject || "Email"} `; } /** * Convert plain text to HTML */ private convertTextToHtml(text: string): string { return text .replace(/\n\n/g, "

") .replace(/\n/g, "
") .replace(/^(.*)$/, "

$1

"); } /** * Strip HTML tags from content */ private stripHtmlTags(html: string): string { return html .replace(/<[^>]*>/g, "") .replace(/ /g, " ") .replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">") .replace(/"/g, '"') .trim(); } }