diff --git a/apps/web/src/server/aws/ses.ts b/apps/web/src/server/aws/ses.ts index 884e0d3..8214b54 100644 --- a/apps/web/src/server/aws/ses.ts +++ b/apps/web/src/server/aws/ses.ts @@ -114,6 +114,7 @@ export async function sendEmailThroughSes({ region, configurationSetName, unsubUrl, + isBulk, }: Partial & { region: string; configurationSetName: string; @@ -121,6 +122,7 @@ export async function sendEmailThroughSes({ bcc?: string[]; replyTo?: string[]; to?: string[]; + isBulk?: boolean; }) { const sesClient = getSesClient(region); const command = new SendEmailCommand({ @@ -155,14 +157,21 @@ export async function sendEmailThroughSes({ } : undefined, }, - ...(unsubUrl - ? { - Headers: [ + Headers: [ + // Spread in any unsubscribe headers if unsubUrl is defined + ...(unsubUrl + ? [ { Name: "List-Unsubscribe", Value: `<${unsubUrl}>` }, - { Name: "List-Unsubscribe-Post", Value: "One-Click" }, - ], - } - : {}), + { Name: "List-Unsubscribe-Post", Value: "List-Unsubscribe=One-Click" }, + ] + : [] + ), + // Spread in the precedence header if present + ...(isBulk + ? [{ Name: "Precedence", Value: "bulk" }] + : [] + ), + ], }, }, ConfigurationSetName: configurationSetName, diff --git a/apps/web/src/server/service/campaign-service.ts b/apps/web/src/server/service/campaign-service.ts index d875125..3cc3903 100644 --- a/apps/web/src/server/service/campaign-service.ts +++ b/apps/web/src/server/service/campaign-service.ts @@ -270,9 +270,10 @@ export async function sendCampaignEmail( // Queue emails await Promise.all( - emails.map((email) => - EmailQueueService.queueEmail(email.id, domain.region, false) - ) + emails.map((email) => { + const unsubscribeUrl = createUnsubUrl(email.contactId, campaignId); + EmailQueueService.queueEmail(email.id, domain.region, false, unsubscribeUrl); + }) ); } diff --git a/apps/web/src/server/service/email-queue-service.ts b/apps/web/src/server/service/email-queue-service.ts index dd30ccb..37d8524 100644 --- a/apps/web/src/server/service/email-queue-service.ts +++ b/apps/web/src/server/service/email-queue-service.ts @@ -100,12 +100,13 @@ export class EmailQueueService { const queue = transactional ? this.transactionalQueue.get(region) : this.marketingQueue.get(region); + const isBulk = !transactional; if (!queue) { throw new Error(`Queue for region ${region} not found`); } queue.add( emailId, - { emailId, timestamp: Date.now(), unsubUrl }, + { emailId, timestamp: Date.now(), unsubUrl, isBulk }, { jobId: emailId, delay } ); } @@ -169,7 +170,12 @@ export class EmailQueueService { } async function executeEmail( - job: Job<{ emailId: string; timestamp: number; unsubUrl?: string }> + job: Job<{ + emailId: string; + timestamp: number; + unsubUrl?: string; + isBulk?: boolean; + }> ) { console.log( `[EmailQueueService]: Executing email job ${job.data.emailId}, time elapsed: ${Date.now() - job.data.timestamp}ms` @@ -207,6 +213,7 @@ async function executeEmail( console.log(`[EmailQueueService]: Sending email ${email.id}`); const unsubUrl = job.data.unsubUrl; + const isBulk = job.data.isBulk; const text = email.text ? email.text @@ -240,6 +247,7 @@ async function executeEmail( configurationSetName, attachments, unsubUrl, + isBulk, }); // Delete attachments after sending the email