Add unsend campaign feature (#45)

* Add unsend email editor

Add email editor

Add more email editor

Add renderer partial

Add more marketing email features

* Add more campaign feature

* Add variables

* Getting there

* campaign is there mfs

* Add migration
This commit is contained in:
KM Koushik
2024-08-10 10:09:10 +10:00
committed by GitHub
parent 0c072579b9
commit 5ddc0a7bb9
92 changed files with 11766 additions and 338 deletions
+32 -21
View File
@@ -1,8 +1,8 @@
import { EmailStatus } from "@prisma/client";
import { SesEvent, SesEventDataKey } from "~/types/aws-types";
import { EmailStatus, Prisma } from "@prisma/client";
import { SesClick, SesEvent, SesEventDataKey } from "~/types/aws-types";
import { db } from "../db";
const STATUS_LIST = Object.values(EmailStatus);
import { updateCampaignAnalytics } from "./campaign-service";
import { env } from "~/env";
export async function parseSesHook(data: SesEvent) {
const mailStatus = getEmailStatus(data);
@@ -34,14 +34,34 @@ export async function parseSesHook(data: SesEvent) {
return true;
}
await db.email.update({
where: {
id: email.id,
},
data: {
latestStatus: getLatestStatus(email.latestStatus, mailStatus),
},
});
// Update the latest status and to avoid race conditions
await db.$executeRaw`
UPDATE "Email"
SET "latestStatus" = CASE
WHEN ${mailStatus}::text::\"EmailStatus\" > "latestStatus" OR "latestStatus" IS NULL
THEN ${mailStatus}::text::\"EmailStatus\"
ELSE "latestStatus"
END
WHERE id = ${email.id}
`;
if (email.campaignId) {
if (
mailStatus !== "CLICKED" ||
!(mailData as SesClick).link.startsWith(`${env.NEXTAUTH_URL}/unsubscribe`)
) {
const mailEvent = await db.emailEvent.findFirst({
where: {
emailId: email.id,
status: mailStatus,
},
});
if (!mailEvent) {
await updateCampaignAnalytics(email.campaignId, mailStatus);
}
}
}
await db.emailEvent.create({
data: {
@@ -89,12 +109,3 @@ function getEmailData(data: SesEvent) {
return data[eventType.toLowerCase() as SesEventDataKey];
}
}
function getLatestStatus(
currentEmailStatus: EmailStatus,
incomingStatus: EmailStatus
) {
const index = STATUS_LIST.indexOf(currentEmailStatus);
const incomingIndex = STATUS_LIST.indexOf(incomingStatus);
return STATUS_LIST[Math.max(index, incomingIndex)] ?? incomingStatus;
}