@travetto/email
Version:
Email transmission module.
84 lines (76 loc) • 2.59 kB
text/typescript
import { Runtime, BinaryUtil } from '@travetto/runtime';
import type { EmailAttachment, EmailIdentity, EmailIdentityList, EmailOptions } from './types.ts';
/**
* Utilities for email
*/
export class MailUtil {
/** Remove brand from text */
static purgeBrand(text: string): string {
return text.replace(/<!-- WARNING:[^\n]{0,500}\n/m, '');
}
/** Add brand to text */
static buildBrand(file: string, content: string, compile?: string): string {
const out = [
'WARNING: Do not modify.',
`File is generated from "${file.replace(Runtime.workspace.path, '.')}"`,
compile ? `Run \`${compile.replaceAll('\n', ' ')}\` to regenerate` : ''
];
return `<!-- ${out.join(' ').trim()} -->\n${content}`;
}
/**
* Extract images from html as attachments
*
* @param html
*/
static async extractImageAttachments(html: string): Promise<{ html: string, attachments: EmailAttachment[] }> {
let idx = 0;
const attachments: EmailAttachment[] = [];
const contentMap = new Map<string, string>();
// Max of 10mb
html = html.replace(/data:(image\/[^;]{1,50});base64,([^"']{1,10000000})/g, (__, contentType, content) => {
// Ensure same data uris map to a single cid
if (!contentMap.has(content)) {
const contentId = `image-${idx += 1}`;
const ext = contentType.split('/')[1];
attachments.push({
cid: contentId,
filename: `${contentId}.${ext}`,
headers: {
'X-Attachment-Id': `${contentId}`
},
content: Buffer.from(content, 'base64'),
contentDisposition: 'inline',
contentType
});
contentMap.set(content, contentId);
return `cid:${contentId}`;
} else {
return contentMap.get(content)!;
}
});
return {
html, attachments
};
}
/**
* Get the primary email, if set from an email identity or identity list
*/
static getPrimaryEmail(identity?: EmailIdentity | EmailIdentityList): string | undefined {
if (!identity) {
return;
}
if (Array.isArray(identity)) {
identity = identity[0];
}
return (typeof identity === 'string') ? identity : identity.address;
}
/**
* Build a unique message id
*/
static buildUniqueMessageId(message: EmailOptions): string {
const from = this.getPrimaryEmail(message.from)!;
const to = this.getPrimaryEmail(message.to)!;
const uniqueId = BinaryUtil.hash(`${to}${from}${message.subject}${Date.now()}`, 12);
return `<${uniqueId}@${from.split('@')[1]}>`;
}
}