backend/src/api/email/services/email.ts (view raw)
1import fs from "node:fs/promises";
2import _ from "lodash";
3import { marked } from "marked";
4import { getHTML } from "../utils/layout";
5
6const langs = ["en", "fr", "nl", "it"];
7
8let locales: Record<
9 string,
10 {
11 template: Record<"footer" | "carosterLink", 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 try {
41 const emailTemplate = await this.getEmailTemplate(
42 notifType,
43 lang,
44 variables
45 );
46 if (!emailTemplate)
47 throw new Error(`No locale found for ${notifType} in ${lang}`);
48
49 strapi.log.debug(
50 `Send email notification of type ${notifType} to ${to} (lang: ${lang})`
51 );
52 await strapi.plugins["email"].services.email.send({
53 to,
54 ...emailTemplate,
55 });
56 } catch (error) {
57 strapi.log.error(`Can't send email notification to ${to}`);
58 console.error(error);
59 }
60 },
61
62 async getEmailTemplate(notifType: string, lang: string, variables = {}) {
63 let matchingLocale = locales?.[lang];
64
65 if (!matchingLocale) {
66 strapi.log.warn(
67 `No email notification locale found for type '${notifType}' and lang '${lang}'`
68 );
69 matchingLocale = locales?.["en"];
70 if (!matchingLocale) return null;
71 }
72
73 try {
74 const notif =
75 matchingLocale.notifications?.[notifType] ||
76 locales?.["en"]?.notifications?.[notifType];
77
78 if (!notif) throw new Error(`Can't found notification locale`);
79
80 const subject = _.template(notif.title)({
81 ...variables,
82 host: strapi.config.server.url,
83 });
84 const mdContent = _.template(notif.content)({
85 ...variables,
86 host: strapi.config.server.url,
87 });
88 const mdFooter = matchingLocale.template.footer;
89 const carosterLink = matchingLocale.template.carosterLink;
90 const htmlContent = await marked.parse(mdContent, { breaks: true });
91 const htmlFooter = await marked.parse(mdFooter, { breaks: true });
92 const html = getHTML({ htmlContent, htmlFooter, carosterLink });
93
94 return {
95 subject,
96 html,
97 text: mdContent,
98 };
99 } catch (error) {
100 strapi.log.error(
101 `Can't parse email notification locale for type '${notifType}' and lang '${lang}'`
102 );
103 console.error(error);
104 return null;
105 }
106 },
107});