feat(structure): Use unified Email class

This commit is contained in:
2025-05-27 15:38:34 +00:00
parent cfea44742a
commit 243a45d24c
11 changed files with 546 additions and 143 deletions

View File

@ -1,6 +1,7 @@
import * as plugins from '../../plugins.js';
import * as paths from '../../paths.js';
import { logger } from '../../logger.js';
import { Email, type IEmailOptions, type IAttachment } from './classes.email.js';
/**
* Email template type definition
@ -40,7 +41,7 @@ export enum TemplateCategory {
}
/**
* Enhanced template manager using smartmail's capabilities
* Enhanced template manager using Email class for template rendering
*/
export class TemplateManager {
private templates: Map<string, IEmailTemplate> = new Map();
@ -191,80 +192,74 @@ export class TemplateManager {
}
/**
* Create a Smartmail instance from a template
* Create an Email instance from a template
* @param templateId The template ID
* @param context The template context data
* @returns A configured Smartmail instance
* @returns A configured Email instance
*/
public async createSmartmail<T = any>(
public async createEmail<T = any>(
templateId: string,
context?: ITemplateContext
): Promise<plugins.smartmail.Smartmail<T>> {
): Promise<Email> {
const template = this.getTemplate(templateId);
if (!template) {
throw new Error(`Template with ID '${templateId}' not found`);
}
// Create Smartmail instance with template content
const smartmail = new plugins.smartmail.Smartmail<T>({
from: template.from || this.defaultConfig.from,
subject: template.subject,
body: template.bodyHtml || template.bodyText || '',
creationObjectRef: context as T
});
// Build attachments array for Email
const attachments: IAttachment[] = [];
// Add any template attachments
if (template.attachments && template.attachments.length > 0) {
for (const attachment of template.attachments) {
// Load attachment file
try {
const attachmentPath = plugins.path.isAbsolute(attachment.path)
? attachment.path
: plugins.path.join(paths.MtaAttachmentsDir, attachment.path);
// Use appropriate SmartFile method - either read from file or create with empty buffer
// For a file path, use the fromFilePath static method
const file = await plugins.smartfile.SmartFile.fromFilePath(attachmentPath);
// Read the file
const fileBuffer = await plugins.fs.promises.readFile(attachmentPath);
// Set content type if specified
if (attachment.contentType) {
(file as any).contentType = attachment.contentType;
}
smartmail.addAttachment(file);
attachments.push({
filename: attachment.name,
content: fileBuffer,
contentType: attachment.contentType || 'application/octet-stream'
});
} catch (error) {
logger.log('error', `Failed to add attachment '${attachment.name}': ${error.message}`);
}
}
}
// Apply template variables if context provided
if (context) {
// Use applyVariables from smartmail v2.1.0+
smartmail.applyVariables(context);
}
// Create Email instance with template content
const emailOptions: IEmailOptions = {
from: template.from || this.defaultConfig.from,
subject: template.subject,
text: template.bodyText || '',
html: template.bodyHtml,
to: '', // Will be set when sending
attachments,
variables: context || {}
};
return smartmail;
return new Email(emailOptions);
}
/**
* Create and completely process a Smartmail instance from a template
* Create and completely process an Email instance from a template
* @param templateId The template ID
* @param context The template context data
* @returns A complete, processed Smartmail instance ready to send
* @returns A complete, processed Email instance ready to send
*/
public async prepareEmail<T = any>(
templateId: string,
context: ITemplateContext = {}
): Promise<plugins.smartmail.Smartmail<T>> {
const smartmail = await this.createSmartmail<T>(templateId, context);
): Promise<Email> {
const email = await this.createEmail<T>(templateId, context);
// Pre-compile all mustache templates (subject, body)
smartmail.getSubject();
smartmail.getBody();
// Email class processes variables when needed, no pre-compilation required
return smartmail;
return email;
}
/**
@ -277,8 +272,8 @@ export class TemplateManager {
templateId: string,
context: ITemplateContext = {}
): Promise<string> {
const smartmail = await this.prepareEmail(templateId, context);
return smartmail.toMimeFormat();
const email = await this.prepareEmail(templateId, context);
return email.toRFC822String(context);
}