backend/src/api/email/services/email.ts (view raw)
1import fs from "node:fs/promises";
2import _ from "lodash";
3import { marked } from "marked";
4import { getHTMLMeta } from "../utils/layout";
5
6const langs = ["en", "fr"];
7
8let locales: Record<
9 string,
10 {
11 template: Record<"header" | "footer", string>;
12 notifications: Record<string, { title: string; content: string }>;
13 }
14> = null;
15
16export default () => ({
17 async loadContentFiles() {
18 strapi.log.info(
19 `🌐 Load localized content files for email notifications...`
20 );
21 const content = await Promise.all(
22 langs.map(async (lang) => {
23 const langFile = await fs.readFile(
24 `${__dirname}/../locales/${lang}.json`,
25 "utf-8"
26 );
27 return [lang, JSON.parse(langFile)];
28 })
29 );
30 locales = Object.fromEntries(content);
31 return locales;
32 },
33
34 async sendEmailNotif(
35 to: string,
36 notifType: string,
37 lang: string,
38 variables?: object
39 ) {
40 const emailTemplate = await this.getEmailTemplate(
41 notifType,
42 lang,
43 variables
44 );
45 if (!emailTemplate)
46 throw new Error(`No locale found for ${notifType} in ${lang}`);
47
48 try {
49 await strapi.plugins["email"].services.email.send({
50 to,
51 ...emailTemplate,
52 });
53 } catch (error) {
54 strapi.log.error(`Can't send email notification to ${to}`);
55 console.error(error);
56 }
57 },
58
59 async getEmailTemplate(notifType: string, lang: string, variables = {}) {
60 let notif = locales?.[lang]?.notifications?.[notifType];
61
62 if (!notif) {
63 strapi.log.warn(
64 `No email notification locale found for type '${notifType}' and lang '${lang}'`
65 );
66 notif = locales?.["en"]?.notifications?.[notifType];
67 if (!notif) return null;
68 }
69
70 try {
71 const mdContent = _.template(notif.content)({
72 ...variables,
73 host: strapi.config.server.url,
74 });
75 const mdHeader = locales?.[lang]?.template.header;
76 const mdFooter = locales?.[lang]?.template.footer;
77 const htmlContent = await marked.parse(mdContent, { breaks: true });
78 const htmlHeader = await marked.parse(mdHeader, { breaks: true });
79 const htmlFooter = await marked.parse(mdFooter, { breaks: true });
80 const emailContent = `${getHTMLMeta()}<main>${htmlHeader}${htmlContent}${htmlFooter}</main>`;
81
82 return {
83 subject: notif.title,
84 text: notif.content,
85 html: emailContent,
86 };
87 } catch (error) {
88 strapi.log.error(
89 `Can't parse email notification locale for type '${notifType}' and lang '${lang}'`
90 );
91 console.error(error);
92 return null;
93 }
94 },
95});