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 { EmailService } from './classes.emailservice.js';
import { logger } from '../../logger.js';
import { Email, type IEmailOptions, type IAttachment } from '../core/classes.email.js';
export class ApiManager {
public emailRef: EmailService;
@ -21,35 +22,40 @@ export class ApiManager {
// Register the SendEmail endpoint
this.typedRouter.addTypedHandler<plugins.servezoneInterfaces.platformservice.mta.IReq_SendEmail>(
new plugins.typedrequest.TypedHandler('sendEmail', async (requestData) => {
const mailToSend = new plugins.smartmail.Smartmail({
body: requestData.body,
from: requestData.from,
subject: requestData.title,
});
// Build attachments array
const attachments: IAttachment[] = [];
if (requestData.attachments) {
for (const attachment of requestData.attachments) {
mailToSend.addAttachment(
await plugins.smartfile.SmartFile.fromString(
attachment.name,
attachment.binaryAttachmentString,
'binary'
)
);
attachments.push({
filename: attachment.name,
content: Buffer.from(attachment.binaryAttachmentString, 'binary'),
contentType: 'application/octet-stream'
});
}
}
// Create Email instance
const emailOptions: IEmailOptions = {
from: requestData.from,
to: requestData.to,
subject: requestData.title,
text: requestData.body,
attachments
};
const mailToSend = new Email(emailOptions);
// Send email through the service which will route to the appropriate connector
const emailId = await this.emailRef.sendEmail(mailToSend, requestData.to, {});
const emailId = await this.emailRef.sendEmail(mailToSend, undefined, {});
logger.log(
'info',
`sent an email to ${requestData.to} with subject '${mailToSend.getSubject()}'`,
`sent an email to ${requestData.to} with subject '${mailToSend.subject}'`,
{
eventType: 'sentEmail',
email: {
to: requestData.to,
subject: mailToSend.getSubject(),
subject: mailToSend.subject,
},
}
);

View File

@ -269,44 +269,31 @@ export class EmailService {
/**
* Send an email using the UnifiedEmailServer
* @param email The email to send
* @param to Recipient(s)
* @param to Recipient(s) - if provided, overrides the email's 'to' field
* @param options Additional options
*/
public async sendEmail(
email: plugins.smartmail.Smartmail<any>,
to: string | string[],
email: Email,
to?: string | string[],
options: ISendEmailOptions = {}
): Promise<string> {
if (this.config.useEmail && this.unifiedEmailServer) {
// Convert Smartmail to Email format
const recipients = Array.isArray(to) ? to : [to];
// Access Smartmail properties using any type to bypass TypeScript checking
const emailAny = email as any;
const emailObj = new Email({
from: emailAny.from,
to: recipients,
subject: emailAny.subject,
text: emailAny.body || emailAny.text,
html: emailAny.htmlBody || emailAny.html,
attachments: emailAny.attachments ? emailAny.attachments.map((att: any) => ({
filename: att.filename,
content: att.contents || att.content,
contentType: att.contentType
})) : []
});
// If 'to' is provided, update the email's recipients
if (to) {
const recipients = Array.isArray(to) ? to : [to];
email.to = recipients;
}
// Determine the domain for routing
let matchedRule;
const recipientDomain = recipients[0].split('@')[1];
const recipientDomain = email.to[0].split('@')[1];
if (recipientDomain && this.domainRouter) {
matchedRule = this.domainRouter.matchRule(recipients[0]);
matchedRule = this.domainRouter.matchRule(email.to[0]);
}
// Send through UnifiedEmailServer
return this.unifiedEmailServer.sendEmail(
emailObj,
email,
matchedRule?.mode || 'mta',
matchedRule
);
@ -330,10 +317,10 @@ export class EmailService {
): Promise<string> {
try {
// Get email from template
const smartmail = await this.templateManager.prepareEmail(templateId, context);
const email = await this.templateManager.prepareEmail(templateId, context);
// Send the email through UnifiedEmailServer
return this.sendEmail(smartmail, to, options);
return this.sendEmail(email, to, options);
} catch (error) {
logger.log('error', `Failed to send template email: ${error.message}`, {
templateId,