UNPKG

@athenna/mail

Version:

The Athenna email handler. Built on top of nodemailer.

445 lines (444 loc) 11.2 kB
/** * @athenna/mail * * (c) Victor Tesoura Júnior <txsoura@athenna.io> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ import { Config } from '@athenna/config'; import { Macroable } from '@athenna/common'; import { DriverFactory } from '#src/factories/DriverFactory'; export class MailImpl extends Macroable { /** * Creates a new instance of Mail. */ constructor() { super(); /** * The mailer name used for this instance. */ this.mailerName = Config.get('mail.default'); /** * The driver responsible for transporting the mails. */ this.driver = null; /** * Runtime configurations to be used inside the Drivers. */ this.runtimeConfig = {}; this.driver = DriverFactory.fabricate(this.mailerName, this.runtimeConfig); } /** * Set runtime configuration for driver. */ config(runtimeConfig = {}) { this.runtimeConfig = runtimeConfig; return this; } /** * Change the mail mailer. * * @example * ```ts * await Mail.mailer('my-smtp') * .from('support@athenna.io') * .to('lenon@athenna.io') * .content('Hello World!') * .send() * ``` */ mailer(mailer) { this.runtimeConfig = {}; this.driver = DriverFactory.fabricate(mailer, this.runtimeConfig); return this; } /** * Send a new mail message. * * @example * ```ts * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .content('Hello World!') * .send() * ``` */ async send() { return this.driver.send(); } /** * Define the email that is sending the email. * * @example * ```ts * await Mail.from('support@athenna.io').send() * ``` */ from(from) { this.driver.from(from); return this; } /** * Define who will receive the email. * * @example * ```ts * await Mail.from('support@athenna.io') * .to('lenon@athenna.io, mailer@athenna.io') * .to('lenon@athenna.io', 'mailer@athenna.io') * .send() * ``` */ to(...to) { this.driver.to(...to); return this; } /** * Define the email subject that will appear on the * subject field. * * @example * ```ts * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .subject('Hello World!') * .send() * ``` */ subject(subject) { this.driver.subject(subject); return this; } /** * Define the emails that will appear on the cc field. * * @example * ```ts * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .cc('mailer@athenna.io, mailer2@athenna.io') * .cc('mailer@athenna.io', 'mailer2@athenna.io') * .send() * ``` */ cc(...cc) { this.driver.cc(...cc); return this; } /** * Define the emails that will appear on the bcc field. * * @example * ```ts * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .bcc('mailer@athenna.io, mailer2@athenna.io') * .bcc('mailer@athenna.io', 'mailer2@athenna.io') * .send() * ``` */ bcc(...bcc) { this.driver.bcc(...bcc); return this; } /** * Define the email that will apear in the reply to field. * * @example * ```ts * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .replyTo('mailer@athenna.io') * .send() * ``` */ replyTo(replyTo) { this.driver.replyTo(replyTo); return this; } /** * Define the emails that this message is replying to. * * @example * ```ts * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .inReplyTo('mailer@athenna.io') * .send() * ``` */ inReplyTo(inReplyTo) { this.driver.inReplyTo(inReplyTo); return this; } /** * Define mail references. * * @example * ```ts * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .references('1, 2, 3') * .send() * ``` */ references(references) { this.driver.references(references); return this; } /** * The envelope is usually auto generated from `from()`, `to()`, * `cc()` and `bcc()` methods but if for some reason you want * to specify it yourself (custom envelopes are usually used * for VERP addresses), you can use this method: * * @example * ```ts * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .envelope({ * from: 'Lenon <lenon@athenna.io>', * to: 'mailer@athenna.io, Mailer <mailer2@athenna.io>' * cc: 'mailer3@athenna.io', * bcc: 'mailer4@athenna.io' * }) * .send() * ``` */ envelope(envelope) { this.driver.envelope(envelope); return this; } /** * Define a date for the email. If not defined, current * UTC string will be used. * * @example * ```ts * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .date(new Date()) * .send() * ``` */ date(value) { this.driver.date(value); return this; } /** * Identifies encoding for `text/html` strings * (defaults to ‘utf-8’, other values are ‘hex’ and * ‘base64’). * * @example * ```ts * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .encoding('utf-8') * .send() * ``` */ encoding(value) { this.driver.encoding(value); return this; } /** * Force content-transfer-encoding for text values (either * `quoted-printable` or `base64`). By default the best option * is detected (for lots of ascii use `quoted-printable`, * otherwise `base64`). * * @example * ```ts * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .textEncoding('base64') * .send() * ``` */ textEncoding(value) { this.driver.textEncoding(value); return this; } /** * If `true`, then does not allow to use files as content. * Use it when you want to use JSON data from untrusted * source as the email. If an attachment or message node * tries to fetch something from a file the sending returns * an error. If this field is also set in the transport * options, then the value in mail data is ignored. * * @example * ```ts * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .disableFileAccess(true) * .send() * ``` */ disableFileAccess(value) { this.driver.disableFileAccess(value); return this; } /** * If `true`, then does not allow to use Urls as content. * If this field is also set in the transport options, * then the value in mail data is ignored * * @example * ```ts * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .disableUrlAccess(true) * .send() * ``` */ disableUrlAccess(value) { this.driver.disableUrlAccess(value); return this; } /** * Sets the email importance headers, either `high`, * `normal` (default) or `low`. * * @example * ```ts * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .priority('high') * .send() * ``` */ priority(value) { this.driver.priority(value); return this; } /** * Define a header to your email. * * @example * ```ts * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .header('x-my-key', 'header value') * .send() * ``` */ header(key, value) { this.driver.header(key, value); return this; } /** * Define a header to your email only if it's not already * defined. * * @example * ```ts * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .safeHeader('x-my-key', 'header value') * .send() * ``` */ safeHeader(key, value) { this.driver.safeHeader(key, value); return this; } /** * Remove a header from your email. * * @example * ```ts * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .removeHeader('x-my-key') * .send() * ``` */ removeHeader(key) { this.driver.removeHeader(key); return this; } /** * Set a file as attachment or a file path to be sent in * the email. * * @example * ```ts * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .attachment({ * filename: 'file.txt', * content: 'hello world!' * }) * .attachment({ * filename: 'file.pdf', * path: Path.storage('mail/file.pdf'), * contentType: 'text/plain' * }) * .attachment({ * filename: 'license.txt', * path: 'https://raw.github.com/nodemailer/nodemailer/master/LICENSE' * }) * .attachment({ * filename: 'text1.txt', * content: 'aGVsbG8gd29ybGQh', * encoding: 'base64' * }) * .send() * ``` */ attachment(attachment) { this.driver.attachment(attachment); return this; } /** * Set the email content. You can choose between `text` * `html` or `markdown`. * * @example * ```ts * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .content('<h1>Hello World!</h1>') * .send() * * // Or choosing the email content type: * * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .content('# Hello World!', { type: 'markdown' }) * .send() * ``` */ content(value, options = {}) { this.driver.content(value, options); return this; } /** * Define mail view to be rendered instead of a raw content. * * @example * ```ts * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .view('mail.welcome', { title: 'Welcome to Athenna!' }) * .send() * * // Or choosing the view content type: * * await Mail.from('support@athenna.io') * .to('lenon@athenna.io') * .content('mail.markdown.welcome', * { title: 'Welcome to Athenna!' }, * { type: 'markdown' } * ) * .send() * ``` */ view(name, data = {}, options = {}) { this.driver.view(name, data, options); return this; } }