113 lines
3.1 KiB
TypeScript
113 lines
3.1 KiB
TypeScript
import nodemailer from 'nodemailer';
|
|
import { createSSRApp, h } from 'vue';
|
|
import { renderToString } from 'vue/server-renderer';
|
|
import postcss from 'postcss';
|
|
import tailwindcss from 'tailwindcss';
|
|
import { join } from 'node:path';
|
|
|
|
import base from '../components/mail/base.vue';
|
|
import registration from '../components/mail/registration.vue';
|
|
import revalidation from '../components/mail/revalidation.vue';
|
|
|
|
const config = useRuntimeConfig();
|
|
const [domain, selector, dkim] = config.mail.dkim.split(":");
|
|
|
|
export const templates: Record<string, { component: any, subject: string }> = {
|
|
"registration": { component: registration, subject: 'Bienvenue sur d[any] 😎' },
|
|
"revalidate-mail": { component: revalidation, subject: 'd[any]: Valider votre email' },
|
|
};
|
|
|
|
import 'nitropack/types';
|
|
import type Mail from 'nodemailer/lib/mailer';
|
|
declare module 'nitropack/types'
|
|
{
|
|
interface TaskPayload
|
|
{
|
|
type: 'mail'
|
|
to: string[]
|
|
template: string
|
|
data: Record<string, any>
|
|
}
|
|
}
|
|
|
|
const transport = nodemailer.createTransport({
|
|
//@ts-ignore
|
|
pool: true,
|
|
host: config.mail.host,
|
|
port: config.mail.port,
|
|
secure: false,
|
|
auth: {
|
|
user: config.mail.user,
|
|
pass: config.mail.passwd,
|
|
},
|
|
requireTLS: true,
|
|
dkim: {
|
|
domainName: domain,
|
|
keySelector: selector,
|
|
privateKey: dkim,
|
|
},
|
|
});
|
|
|
|
export default defineTask({
|
|
meta: {
|
|
name: 'mail',
|
|
description: 'Send email',
|
|
},
|
|
async run(e) {
|
|
try {
|
|
if(e.payload.type !== 'mail')
|
|
{
|
|
throw new Error(`Données inconnues`);
|
|
}
|
|
|
|
const payload = e.payload;
|
|
const template = templates[payload.template];
|
|
|
|
if(!template)
|
|
{
|
|
throw new Error(`Modèle de mail ${payload.template} inconnu`);
|
|
}
|
|
|
|
console.time('Generating HTML');
|
|
const mail: Mail.Options = {
|
|
from: 'd[any] - Ne pas répondre <no-reply@peaceultime.com>',
|
|
to: payload.to,
|
|
html: await render(template.component, payload.data),
|
|
subject: template.subject,
|
|
|
|
};
|
|
console.timeEnd('Generating HTML');
|
|
|
|
if(mail.html === '')
|
|
return { result: false, error: new Error("Invalid content") };
|
|
|
|
console.time('Sending Mail');
|
|
const status = await transport.sendMail(mail);
|
|
console.timeEnd('Sending Mail');
|
|
|
|
if(status.rejected.length > 0)
|
|
{
|
|
return { result: false, error: status.response, details: status.rejectedErrors };
|
|
}
|
|
|
|
return { result: true };
|
|
}
|
|
catch(e)
|
|
{
|
|
return { result: false, error: e };
|
|
}
|
|
},
|
|
})
|
|
|
|
async function render(component: any, data: Record<string, any>): Promise<string>
|
|
{
|
|
const app = createSSRApp({
|
|
render(){
|
|
return h(base, null, { default: () => h(component, data, { default: () => null }) });
|
|
}
|
|
});
|
|
|
|
const html = await renderToString(app);
|
|
|
|
return (`<html><body><div>${html}</div></body></html>`);
|
|
} |