UNPKG

@webda/core

Version:

Expose API with Lambda

176 lines 5.34 kB
import Email from "email-templates"; import * as fs from "fs"; import * as nodemailer from "nodemailer"; import * as path from "path"; import { Counter } from "../index.js"; import { Service, ServiceParameters } from "./service.js"; export class MailerParameters extends ServiceParameters { constructor(params) { var _a, _b, _c; super(params); this.templates ?? (this.templates = "./templates"); if (!this.templates.endsWith("/")) { this.templates += "/"; } this.templatesEngine ?? (this.templatesEngine = "mustache"); this.emailTemplateOptions ?? (this.emailTemplateOptions = {}); (_a = this.emailTemplateOptions).juiceResources ?? (_a.juiceResources = {}); (_b = this.emailTemplateOptions.juiceResources).webResources ?? (_b.webResources = {}); (_c = this.emailTemplateOptions.juiceResources.webResources).relativeTo ?? (_c.relativeTo = path.resolve(this.templates)); } } export class AbstractMailer extends Service { /** * @override */ initMetrics() { var _a; super.initMetrics(); this.metrics.sent = this.getMetric(Counter, { name: "mailer_sent", help: "Number of emails sent" }); (_a = this.metrics).errors ?? (_a.errors = this.getMetric(Counter, { name: "mailer_errors", help: "Number of emails in error" })); } /** * If user has an email * @param user * @returns */ async handleNotificationFor(user) { return user.getEmail() !== undefined; } /** * @override */ async sendNotification(user, notification, replacements) { let email = user.getEmail(); if (!email) { throw new Error(`Cannot find a valid email for ${user.__type} '${user.getUuid()}'`); } this.metrics.sent.inc(); try { await this.send({ template: notification, replacements: { ...replacements }, to: email }); } catch (err) { this.metrics.errors.inc(); throw err; } } } /** * A basic Mailer based on the nodemailer module * * Inside config it is the nodemailer module option for the method createTransport ( https://nodemailer.com/ ) * * Only ses transport module is installed by default * * Parameters * config: { ... } * @category CoreServices * @WebdaModda */ class Mailer extends AbstractMailer { constructor() { super(...arguments); this._templates = {}; } /** * Load parameters * * @param params * @ignore */ loadParameters(params) { return new MailerParameters(params); } /** * Compute parameters */ async init() { this._transporter = nodemailer.createTransport(this.parameters); return this; } /** * Get a template by name * * @param name * @returns */ _getTemplate(name) { if (!this._templates[name]) { if (!this.hasNotification(name)) { this._webda.log("WARN", "No template found for", name); return; } this._templates[name] = new Email({ ...this.parameters.emailTemplateOptions, views: { root: this.parameters.templates, options: { extension: this.parameters.templatesEngine } } }); } return this._templates[name]; } /** * Check if the email template exists * * @param name * @returns */ hasNotification(name) { // Load template return fs.existsSync(this.parameters.templates + name); } /** * * @params options Options to pass to the sendMail option of the nodemailer module * @params callback to pass to the sendMail */ async send(options, callback = undefined) { if (this._transporter === undefined) { this._webda.log("ERROR", "Cannot send email as no transporter is defined"); return Promise.reject("Cannot send email as no transporter is defined"); } if (!options.from) { options.from = this.parameters.sender; } if (options.template) { if (!options.replacements) { options.replacements = {}; } options.replacements.now = new Date(); let template = this._getTemplate(options.template); if (template) { let result = await template.renderAll(options.template, options.replacements); if (result.subject) { options.subject = result.subject; } if (result.html) { options.html = result.html; } if (result.text) { options.text = result.text; } } else { throw Error("Unknown mail template"); } } return this._transporter.sendMail(options, callback); } } export { Mailer }; //# sourceMappingURL=mailer.js.map