feat: setup plunk for transactional/marketing emails

This commit is contained in:
Henry
2025-07-28 07:09:30 +01:00
parent 0cefd17484
commit babaa9f1b1
8 changed files with 48 additions and 3 deletions

View File

@@ -11,7 +11,7 @@ import type { dbClient } from "@kan/db/client";
import * as memberRepo from "@kan/db/repository/member.repo";
import * as userRepo from "@kan/db/repository/user.repo";
import * as schema from "@kan/db/schema";
import { sendEmail } from "@kan/email";
import { cloudMailerClient, sendEmail } from "@kan/email";
import { createStripeClient } from "@kan/stripe";
export const configuredProviders = socialProviderList.reduce<
@@ -183,6 +183,17 @@ export const initAuth = (db: dbClient) => {
return Promise.resolve(true);
},
async after(user) {
if (cloudMailerClient) {
await cloudMailerClient.events.track({
event: "user-signup",
email: user.email,
data: {
name: user.name,
userId: user.id,
},
});
}
if (
user.image &&
!user.image.includes(process.env.NEXT_PUBLIC_STORAGE_DOMAIN!)

View File

@@ -23,6 +23,7 @@
"typecheck": "tsc --noEmit --emitDeclarationOnly false"
},
"dependencies": {
"@plunk/node": "^3.0.3",
"@react-email/components": "^0.0.25",
"nodemailer": "^7.0.3",
"react-email": "^3.0.1"

View File

@@ -0,0 +1,8 @@
import Plunk from "@plunk/node";
export const cloudMailerClient =
process.env.NEXT_PUBLIC_KAN_ENV === "cloud"
? new Plunk(process.env.PLUNK_API_KEY ?? "", {
baseUrl: process.env.PLUNK_API_URL,
})
: null;

View File

@@ -1,3 +1,4 @@
export const name = "email";
export { sendEmail } from "./sendEmail";
export { cloudMailerClient } from "./cloudMailerClient";

View File

@@ -1,6 +1,7 @@
import { render } from "@react-email/render";
import nodemailer from "nodemailer";
import { cloudMailerClient } from "./cloudMailerClient";
import JoinWorkspaceTemplate from "./templates/join-workspace";
import MagicLinkTemplate from "./templates/magic-link";
import ResetPasswordTemplate from "./templates/reset-password";
@@ -44,6 +45,15 @@ export const sendEmail = async (
html,
};
if (cloudMailerClient) {
const response = await cloudMailerClient.emails.send({
...options,
body: html,
});
return response;
}
const response = await transporter.sendMail(options);
if (!response.accepted.length) {