feat(email): Enhance email integration by updating @push.rocks/smartmail to ^2.1.0 and improving the entire email stack including validation, DKIM verification, templating, MIME conversion, and attachment handling.

This commit is contained in:
2025-05-07 17:41:04 +00:00
parent 2ee66ef967
commit c852e954c9
17 changed files with 2566 additions and 625 deletions

View File

@@ -3,6 +3,8 @@ import * as paths from '../paths.js';
import { MtaConnector } from './classes.connector.mta.js';
import { RuleManager } from './classes.rulemanager.js';
import { ApiManager } from './classes.apimanager.js';
import { TemplateManager } from './classes.templatemanager.js';
import { EmailValidator } from './classes.emailvalidator.js';
import { logger } from '../logger.js';
import type { SzPlatformService } from '../platformservice.js';
@@ -12,6 +14,13 @@ import { MtaService, type IMtaConfig } from '../mta/index.js';
export interface IEmailConstructorOptions {
useMta?: boolean;
mtaConfig?: IMtaConfig;
templateConfig?: {
from?: string;
replyTo?: string;
footerHtml?: string;
footerText?: string;
};
loadTemplatesFromDir?: boolean;
}
/**
@@ -33,6 +42,8 @@ export class EmailService {
// services
public apiManager: ApiManager;
public ruleManager: RuleManager;
public templateManager: TemplateManager;
public emailValidator: EmailValidator;
// configuration
private config: IEmailConstructorOptions;
@@ -44,9 +55,17 @@ export class EmailService {
// Set default options
this.config = {
useMta: options.useMta ?? true,
mtaConfig: options.mtaConfig || {}
mtaConfig: options.mtaConfig || {},
templateConfig: options.templateConfig || {},
loadTemplatesFromDir: options.loadTemplatesFromDir ?? true
};
// Initialize validator
this.emailValidator = new EmailValidator();
// Initialize template manager
this.templateManager = new TemplateManager(this.config.templateConfig);
if (this.config.useMta) {
// Initialize MTA service
this.mtaService = new MtaService(platformServiceRefArg, this.config.mtaConfig);
@@ -72,6 +91,15 @@ export class EmailService {
// Initialize rule manager
await this.ruleManager.init();
// Load email templates if configured
if (this.config.loadTemplatesFromDir) {
try {
await this.templateManager.loadTemplatesFromDirectory(paths.emailTemplatesDir);
} catch (error) {
logger.log('error', `Failed to load email templates: ${error.message}`);
}
}
// Start MTA service if enabled
if (this.config.useMta && this.mtaService) {
await this.mtaService.start();
@@ -101,7 +129,7 @@ export class EmailService {
* @param options Additional options
*/
public async sendEmail(
email: plugins.smartmail.Smartmail<>,
email: plugins.smartmail.Smartmail<any>,
to: string | string[],
options: any = {}
): Promise<string> {
@@ -112,6 +140,52 @@ export class EmailService {
throw new Error('No email provider configured');
}
}
/**
* Send an email using a template
* @param templateId The template ID
* @param to Recipient email(s)
* @param context The template context data
* @param options Additional options
*/
public async sendTemplateEmail(
templateId: string,
to: string | string[],
context: any = {},
options: any = {}
): Promise<string> {
try {
// Get email from template
const smartmail = await this.templateManager.prepareEmail(templateId, context);
// Send the email
return this.sendEmail(smartmail, to, options);
} catch (error) {
logger.log('error', `Failed to send template email: ${error.message}`, {
templateId,
to,
error: error.message
});
throw error;
}
}
/**
* Validate an email address
* @param email The email address to validate
* @param options Validation options
* @returns Validation result
*/
public async validateEmail(
email: string,
options: {
checkMx?: boolean;
checkDisposable?: boolean;
checkRole?: boolean;
} = {}
): Promise<any> {
return this.emailValidator.validate(email, options);
}
/**
* Get email service statistics