TofuStack/src/lib/server/api/services/mailer.service.ts

96 lines
2.9 KiB
TypeScript
Raw Normal View History

import fs from 'fs';
import path from 'path';
2024-05-25 06:02:26 +00:00
import nodemailer from 'nodemailer';
import handlebars from 'handlebars';
import { fileURLToPath } from 'url';
import { injectable } from 'tsyringe';
2024-05-25 06:02:26 +00:00
/* -------------------------------------------------------------------------- */
/* Service */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* ---------------------------------- About --------------------------------- */
/*
Services are responsible for handling business logic and data manipulation.
They genreally call on repositories or other services to complete a use-case.
*/
/* ---------------------------------- Notes --------------------------------- */
/*
Services should be kept as clean and simple as possible.
Create private functions to handle complex logic and keep the public methods as
simple as possible. This makes the service easier to read, test and understand.
*/
/* -------------------------------------------------------------------------- */
2024-05-25 06:02:26 +00:00
type SendMail = {
to: string | string[];
subject: string;
html: string;
};
type SendTemplate<T> = {
to: string | string[];
props: T;
};
@injectable()
export class MailerService {
private nodemailer = nodemailer.createTransport({
host: 'smtp.ethereal.email',
port: 587,
secure: false, // Use `true` for port 465, `false` for all other ports
auth: {
user: 'adella.hoppe@ethereal.email',
pass: 'dshNQZYhATsdJ3ENke'
}
});
sendEmailVerification(data: SendTemplate<{ token: string }>) {
const template = handlebars.compile(this.getTemplate('email-verification'));
return this.send({
to: data.to,
subject: 'Email Verification',
html: template({ token: data.props.token })
});
}
sendLoginRequest(data: SendTemplate<{ token: string }>) {
const template = handlebars.compile(this.getTemplate('email-verification'));
return this.send({
to: data.to,
subject: 'Login Request',
html: template({ token: data.props.token })
});
}
sendWelcome(data: SendTemplate<null>) {
const template = handlebars.compile(this.getTemplate('welcome'));
return this.send({
to: data.to,
subject: 'Welcome!',
html: template(null)
});
}
2024-05-25 06:02:26 +00:00
private async send({ to, subject, html }: SendMail) {
const message = await this.nodemailer.sendMail({
from: '"Example" <example@ethereal.email>', // sender address
bcc: to,
subject, // Subject line
text: html,
html
});
console.log(nodemailer.getTestMessageUrl(message));
}
private getTemplate(template: string) {
const __filename = fileURLToPath(import.meta.url); // get the resolved path to the file
const __dirname = path.dirname(__filename); // get the name of the directory
return fs.readFileSync(
2024-05-25 06:02:33 +00:00
path.join(__dirname, `../infrastructure/email-templates/${template}.handlebars`),
2024-05-25 06:02:26 +00:00
'utf-8'
);
}
}