Add schedule api (#60)
This commit is contained in:
@@ -3,9 +3,32 @@ import { db } from "../db";
|
||||
import { UnsendApiError } from "~/server/public-api/api-error";
|
||||
import { EmailQueueService } from "./email-queue-service";
|
||||
import { validateDomainFromEmail } from "./domain-service";
|
||||
import { Campaign, Contact } from "@prisma/client";
|
||||
import { EmailRenderer } from "@unsend/email-editor/src/renderer";
|
||||
import { createUnsubUrl } from "./campaign-service";
|
||||
|
||||
async function checkIfValidEmail(emailId: string) {
|
||||
const email = await db.email.findUnique({
|
||||
where: { id: emailId },
|
||||
});
|
||||
|
||||
if (!email || !email.domainId) {
|
||||
throw new UnsendApiError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Email not found",
|
||||
});
|
||||
}
|
||||
|
||||
const domain = await db.domain.findUnique({
|
||||
where: { id: email.domainId },
|
||||
});
|
||||
|
||||
if (!domain) {
|
||||
throw new UnsendApiError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Email not found",
|
||||
});
|
||||
}
|
||||
|
||||
return { email, domain };
|
||||
}
|
||||
|
||||
/**
|
||||
Send transactional email
|
||||
@@ -24,10 +47,16 @@ export async function sendEmail(
|
||||
replyTo,
|
||||
cc,
|
||||
bcc,
|
||||
scheduledAt,
|
||||
} = emailContent;
|
||||
|
||||
const domain = await validateDomainFromEmail(from, teamId);
|
||||
|
||||
const scheduledAtDate = scheduledAt ? new Date(scheduledAt) : undefined;
|
||||
const delay = scheduledAtDate
|
||||
? Math.max(0, scheduledAtDate.getTime() - Date.now())
|
||||
: undefined;
|
||||
|
||||
const email = await db.email.create({
|
||||
data: {
|
||||
to: Array.isArray(to) ? to : [to],
|
||||
@@ -45,11 +74,19 @@ export async function sendEmail(
|
||||
teamId,
|
||||
domainId: domain.id,
|
||||
attachments: attachments ? JSON.stringify(attachments) : undefined,
|
||||
scheduledAt: scheduledAtDate,
|
||||
latestStatus: scheduledAtDate ? "SCHEDULED" : "QUEUED",
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
await EmailQueueService.queueEmail(email.id, domain.region, true);
|
||||
await EmailQueueService.queueEmail(
|
||||
email.id,
|
||||
domain.region,
|
||||
true,
|
||||
undefined,
|
||||
delay
|
||||
);
|
||||
} catch (error: any) {
|
||||
await db.emailEvent.create({
|
||||
data: {
|
||||
@@ -69,3 +106,62 @@ export async function sendEmail(
|
||||
|
||||
return email;
|
||||
}
|
||||
|
||||
export async function updateEmail(
|
||||
emailId: string,
|
||||
{
|
||||
scheduledAt,
|
||||
}: {
|
||||
scheduledAt?: string;
|
||||
}
|
||||
) {
|
||||
const { email, domain } = await checkIfValidEmail(emailId);
|
||||
|
||||
if (email.latestStatus !== "SCHEDULED") {
|
||||
throw new UnsendApiError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Email already processed",
|
||||
});
|
||||
}
|
||||
|
||||
const scheduledAtDate = scheduledAt ? new Date(scheduledAt) : undefined;
|
||||
const delay = scheduledAtDate
|
||||
? Math.max(0, scheduledAtDate.getTime() - Date.now())
|
||||
: undefined;
|
||||
|
||||
await db.email.update({
|
||||
where: { id: emailId },
|
||||
data: {
|
||||
scheduledAt: scheduledAtDate,
|
||||
},
|
||||
});
|
||||
|
||||
await EmailQueueService.changeDelay(emailId, domain.region, true, delay ?? 0);
|
||||
}
|
||||
|
||||
export async function cancelEmail(emailId: string) {
|
||||
const { email, domain } = await checkIfValidEmail(emailId);
|
||||
|
||||
if (email.latestStatus !== "SCHEDULED") {
|
||||
throw new UnsendApiError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Email already processed",
|
||||
});
|
||||
}
|
||||
|
||||
await EmailQueueService.chancelEmail(emailId, domain.region, true);
|
||||
|
||||
await db.email.update({
|
||||
where: { id: emailId },
|
||||
data: {
|
||||
latestStatus: "CANCELLED",
|
||||
},
|
||||
});
|
||||
|
||||
await db.emailEvent.create({
|
||||
data: {
|
||||
emailId,
|
||||
status: "CANCELLED",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
Reference in New Issue
Block a user