Verstuur uitnodigingen voor experts via SendGrid, zoals het ZRM-platform
- lib/mail.ts gebruikt SendGrid met dezelfde variabelen als het Rikx ZRM-platform (SENDGRID_API_KEY, SENDGRID_FROM_EMAIL, SENDGRID_FROM_NAME); SMTP blijft beschikbaar als alternatief - Uitnodigingsmail krijgt ook een HTML-versie met knop - Zonder SendGrid of SMTP blijft de pagina Experts de link tonen - .env.example en CLAUDE.md bijgewerkt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+33
-5
@@ -1,12 +1,39 @@
|
||||
import nodemailer from "nodemailer";
|
||||
|
||||
// E-mail via SMTP (zie SMTP_* in CLAUDE.md). Zonder SMTP_HOST wordt er niets verstuurd;
|
||||
// de aanroeper toont dan bijvoorbeeld de uitnodigingslink in beeld.
|
||||
// E-mail versturen. Voorkeur: SendGrid, met dezelfde instellingen als het Rikx ZRM-platform
|
||||
// (SENDGRID_API_KEY, SENDGRID_FROM_EMAIL, SENDGRID_FROM_NAME). Anders SMTP (SMTP_*).
|
||||
// Zonder beide wordt er niets verstuurd; de aanroeper toont dan bijvoorbeeld de uitnodigingslink in beeld.
|
||||
export function isMailConfigured(): boolean {
|
||||
return Boolean(process.env.SMTP_HOST);
|
||||
return Boolean(process.env.SENDGRID_API_KEY || process.env.SMTP_HOST);
|
||||
}
|
||||
|
||||
export async function sendMail(message: { to: string; subject: string; text: string; html?: string }): Promise<void> {
|
||||
type Message = { to: string; toName?: string; subject: string; text: string; html?: string };
|
||||
|
||||
export async function sendMail(message: Message): Promise<void> {
|
||||
if (process.env.SENDGRID_API_KEY) return sendViaSendGrid(message, process.env.SENDGRID_API_KEY);
|
||||
return sendViaSmtp(message);
|
||||
}
|
||||
|
||||
async function sendViaSendGrid(message: Message, apiKey: string): Promise<void> {
|
||||
const res = await fetch("https://api.sendgrid.com/v3/mail/send", {
|
||||
method: "POST",
|
||||
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
personalizations: [{ to: [{ email: message.to, name: message.toName }], subject: message.subject }],
|
||||
from: {
|
||||
email: process.env.SENDGRID_FROM_EMAIL || "no-reply@rikxplatform.nl",
|
||||
name: process.env.SENDGRID_FROM_NAME || "Rikx",
|
||||
},
|
||||
content: [
|
||||
{ type: "text/plain", value: message.text },
|
||||
...(message.html ? [{ type: "text/html", value: message.html }] : []),
|
||||
],
|
||||
}),
|
||||
});
|
||||
if (!res.ok) throw new Error(`SendGrid ${res.status}: ${await res.text()}`);
|
||||
}
|
||||
|
||||
async function sendViaSmtp(message: Message): Promise<void> {
|
||||
const port = Number(process.env.SMTP_PORT || 587);
|
||||
const transport = nodemailer.createTransport({
|
||||
host: process.env.SMTP_HOST,
|
||||
@@ -14,5 +41,6 @@ export async function sendMail(message: { to: string; subject: string; text: str
|
||||
secure: port === 465,
|
||||
auth: process.env.SMTP_USER ? { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS } : undefined,
|
||||
});
|
||||
await transport.sendMail({ from: process.env.SMTP_FROM || "noreply@rikx.nl", ...message });
|
||||
const { toName: _toName, ...rest } = message;
|
||||
await transport.sendMail({ from: process.env.SMTP_FROM || "noreply@rikx.nl", ...rest });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user