@webda/core
Version:
Expose API with Lambda
176 lines • 5.34 kB
JavaScript
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