diff --git a/apps/web/src/server/aws/ses.ts b/apps/web/src/server/aws/ses.ts index 3c669e8..c6050a9 100644 --- a/apps/web/src/server/aws/ses.ts +++ b/apps/web/src/server/aws/ses.ts @@ -123,6 +123,7 @@ export async function sendRawEmail({ unsubUrl, isBulk, inReplyToMessageId, + emailId, }: Partial & { region: string; configurationSetName: string; @@ -134,6 +135,7 @@ export async function sendRawEmail({ unsubUrl?: string; isBulk?: boolean; inReplyToMessageId?: string; + emailId?: string; }) { const sesClient = getSesClient(region); @@ -155,6 +157,7 @@ export async function sendRawEmail({ bcc, headers: { "X-Entity-Ref-ID": nanoid(), + ...(emailId ? { "X-Unsend-Email-ID": emailId } : {}), ...(unsubUrl ? { "List-Unsubscribe": `<${unsubUrl}>`, diff --git a/apps/web/src/server/service/email-queue-service.ts b/apps/web/src/server/service/email-queue-service.ts index 7a72eb1..cd11dec 100644 --- a/apps/web/src/server/service/email-queue-service.ts +++ b/apps/web/src/server/service/email-queue-service.ts @@ -381,6 +381,7 @@ async function executeEmail(job: QueueEmailJob) { unsubUrl, isBulk, inReplyToMessageId, + emailId: email.id, }); logger.info( diff --git a/apps/web/src/server/service/ses-hook-parser.ts b/apps/web/src/server/service/ses-hook-parser.ts index aaee8c4..829d679 100644 --- a/apps/web/src/server/service/ses-hook-parser.ts +++ b/apps/web/src/server/service/ses-hook-parser.ts @@ -32,12 +32,39 @@ export async function parseSesHook(data: SesEvent) { const mailData = getEmailData(data); - const email = await db.email.findUnique({ + let email = await db.email.findUnique({ where: { sesEmailId, }, }); + // Handle race condition: If email not found by sesEmailId, try to find by custom header + if (!email) { + const emailIdHeader = data.mail.headers.find( + (h) => h.name === "X-Unsend-Email-ID" + ); + + if (emailIdHeader?.value) { + email = await db.email.findUnique({ + where: { + id: emailIdHeader.value, + }, + }); + + // If found, update the sesEmailId to fix the missing reference + if (email) { + await db.email.update({ + where: { id: email.id }, + data: { sesEmailId }, + }); + logger.info( + { emailId: email.id, sesEmailId }, + "Updated email with sesEmailId from webhook (race condition resolved)" + ); + } + } + } + logger.setBindings({ sesEmailId, mailId: email?.id,