infoalloggi-monorepo/apps/infoalloggi/src/server/services/mailer.ts

223 lines
5.6 KiB
TypeScript
Raw Normal View History

2025-08-04 17:45:44 +02:00
import { render } from "@react-email/render";
import { TRPCError } from "@trpc/server";
import ContattoAdminEmail, {
2025-08-28 18:27:07 +02:00
type ContattoAdmin_NewMail,
2025-08-04 17:45:44 +02:00
} from "emails/contatto";
2025-08-28 18:27:07 +02:00
import type { ContattoAnnuncio_NewMail } from "emails/contatto_annuncio";
import ContattoAnnuncioEmail from "emails/contatto_annuncio";
2025-08-04 17:45:44 +02:00
import EmailContattoInteressato, {
2025-08-28 18:27:07 +02:00
type ContattoInteressato_NewMail,
2025-08-04 17:45:44 +02:00
} from "emails/email-interessato";
2025-08-28 18:27:07 +02:00
import type { Generic_NewMail } from "emails/gereric-email";
import Generic from "emails/gereric-email";
import OnboardingServizio, {
type OnboardingServizio_NewMail,
} from "emails/onboarding-servizio";
2025-08-04 17:45:44 +02:00
import type { PagamentoConferma_NewMail } from "emails/pagamento-conferma";
import PagamentoConferma from "emails/pagamento-conferma";
import type { PagamentoErrore_NewMail } from "emails/pagamento-errore";
import PagamentoErrore from "emails/pagamento-errore";
import type { PagamentoRicezione_NewMail } from "emails/pagamento-ricezione";
import PagamentoRicezione from "emails/pagamento-ricezione";
import type { PwResetLink_NewMail } from "emails/pw-reset-link";
import PwResetLink from "emails/pw-reset-link";
import type { Recesso_NewMail } from "emails/recesso";
import Recesso from "emails/recesso";
import type { RegistrazioneAvvenuta_NewMail } from "emails/registrazione-avvenuta";
import RegistrazioneAvvenuta from "emails/registrazione-avvenuta";
2025-08-28 18:27:07 +02:00
import VerificaEmail, {
type VerificaEmail_NewMail,
} from "emails/VerificaEmail";
import { createTransport } from "nodemailer";
2025-08-28 18:27:07 +02:00
import type { Options } from "nodemailer/lib/mailer";
2025-08-04 17:45:44 +02:00
import { htmlToText } from "nodemailer-html-to-text";
import type { JSX } from "react";
import { env } from "~/env";
2025-08-04 17:45:44 +02:00
import type { UsersId } from "~/schemas/public/Users";
import { GetFlagValueHandler } from "~/server/controllers/flags.controller";
import { db } from "~/server/db";
2025-08-28 18:27:07 +02:00
import { StoreEmail } from "~/server/services/email.service";
2025-08-04 17:45:44 +02:00
type MailerProps = {
2025-08-28 18:27:07 +02:00
to: string;
subject: string;
html: string;
2025-08-04 17:45:44 +02:00
};
const mailer = async ({ to, subject, html }: MailerProps) => {
2025-08-28 18:27:07 +02:00
const smtpTransport = createTransport({
auth: {
pass: env.ARUBA_PASS,
2025-08-29 16:18:32 +02:00
user: env.ARUBA_USER,
2025-08-28 18:27:07 +02:00
},
2025-08-29 16:18:32 +02:00
debug: false,
host: "smtps.aruba.it",
logger: false,
port: 465,
secure: true,
2025-08-28 18:27:07 +02:00
tls: {
ciphers: "HIGH:MEDIUM:!aNULL:!eNULL:@STRENGTH:!DH:!kEDH",
2025-08-29 16:18:32 +02:00
minVersion: "TLSv1",
2025-08-28 18:27:07 +02:00
},
});
smtpTransport.use("compile", htmlToText());
const message: Options = {
2025-08-29 16:18:32 +02:00
from: `"InfoAlloggi" <${env.ARUBA_USER}>`,
html: html,
subject: subject,
to: to,
2025-08-28 18:27:07 +02:00
};
smtpTransport.sendMail(message, (err, info) => {
if (err) {
throw new Error(err.message);
}
return info;
});
2025-08-04 17:45:44 +02:00
};
type base_NewMailProps = {
2025-08-28 18:27:07 +02:00
userId?: UsersId;
to: string;
subject: string;
2025-08-04 17:45:44 +02:00
};
export type NewMailProps = base_NewMailProps & MailsTemplates;
export type MailsTemplates =
2025-08-28 18:27:07 +02:00
| ContattoAdmin_NewMail
| ContattoAnnuncio_NewMail
| ContattoInteressato_NewMail
| PagamentoConferma_NewMail
| PagamentoErrore_NewMail
| PagamentoRicezione_NewMail
| PwResetLink_NewMail
| Recesso_NewMail
| RegistrazioneAvvenuta_NewMail
| VerificaEmail_NewMail
| OnboardingServizio_NewMail
| Generic_NewMail;
2025-08-04 17:45:44 +02:00
export const genMail = async ({ ...mail }: MailsTemplates) => {
2025-08-28 18:27:07 +02:00
let mailComponent: JSX.Element | null = null;
let title = "";
switch (mail.mailType) {
case "contattoAdminEmail":
mailComponent = ContattoAdminEmail({
...mail.props,
});
title = "Contatto amministratore";
break;
case "contattoAnnuncioEmail":
mailComponent = ContattoAnnuncioEmail({
...mail.props,
});
title = "Contatto annuncio";
break;
case "emailContattoInteressato":
mailComponent = EmailContattoInteressato({
...mail.props,
});
title = "Contatto interessato";
break;
case "pagamentoConferma":
mailComponent = PagamentoConferma({
...mail.props,
});
title = "Conferma pagamento";
break;
case "pagamentoErrore":
mailComponent = PagamentoErrore();
2025-08-28 18:27:07 +02:00
title = "Errore pagamento";
break;
case "pagamentoRicezione":
mailComponent = PagamentoRicezione();
2025-08-28 18:27:07 +02:00
title = "Ricezione pagamento";
break;
case "pwResetLink":
mailComponent = PwResetLink({
...mail.props,
});
title = "Reset password";
break;
case "recesso":
mailComponent = Recesso();
title = "Recesso";
break;
case "registrazioneAvvenuta":
mailComponent = RegistrazioneAvvenuta();
2025-08-28 18:27:07 +02:00
title = "Registrazione avvenuta";
break;
case "verificaEmail":
mailComponent = VerificaEmail({
...mail.props,
});
title = "Verifica email";
break;
case "onboardingServizio":
mailComponent = OnboardingServizio({
...mail.props,
});
title = "Onboarding Servizio";
break;
case "generic":
mailComponent = Generic({
...mail.props,
});
title = mail.props.title || "Email Generica";
break;
}
if (mailComponent === null) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "Errore nella creazione dell'email",
});
}
return { html: await render(mailComponent), title };
2025-08-04 17:45:44 +02:00
};
export const NewMail = async ({
2025-08-28 18:27:07 +02:00
userId,
to,
subject,
...mail
2025-08-04 17:45:44 +02:00
}: NewMailProps) => {
2025-08-28 18:27:07 +02:00
const emailFlag = await GetFlagValueHandler({
db: db,
id: "EMAIL_OFF",
});
if (emailFlag === "false") {
try {
const { html } = await genMail({ ...mail });
await mailer({
html,
2025-08-29 16:18:32 +02:00
subject: subject,
to: to,
2025-08-28 18:27:07 +02:00
});
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Errore nell'invio dell'email: ${(e as Error).message}`,
});
}
} else {
console.warn(
`Email sending is disabled to:${to} subj:${subject} msgType: ${mail.mailType}`,
);
}
if (userId) {
// Store the email in the database if userId is provided
2025-08-29 16:18:32 +02:00
await StoreEmail({ data: mail, userId });
2025-08-28 18:27:07 +02:00
}
2025-08-04 17:45:44 +02:00
};