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();
}
}