From bd5f6fcc0264877a7f234ccae7c1bd4de16f2752 Mon Sep 17 00:00:00 2001 From: Chris Anderson Date: Fri, 23 Aug 2024 13:19:50 +0200 Subject: [PATCH] Add email unsubscribe header (#493) --- apps/platform/src/providers/email/Email.ts | 1 + apps/platform/src/providers/email/EmailChannel.ts | 8 ++++++++ apps/platform/src/providers/email/EmailProvider.ts | 9 +-------- apps/platform/src/render/index.ts | 2 +- .../src/subscriptions/SubscriptionController.ts | 10 ++++++++++ 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/apps/platform/src/providers/email/Email.ts b/apps/platform/src/providers/email/Email.ts index 57b3d941..729cb4aa 100644 --- a/apps/platform/src/providers/email/Email.ts +++ b/apps/platform/src/providers/email/Email.ts @@ -10,4 +10,5 @@ export interface Email { text: string html: string headers?: Record + list?: { unsubscribe: string } } diff --git a/apps/platform/src/providers/email/EmailChannel.ts b/apps/platform/src/providers/email/EmailChannel.ts index f7f5f2de..2a2933d5 100644 --- a/apps/platform/src/providers/email/EmailChannel.ts +++ b/apps/platform/src/providers/email/EmailChannel.ts @@ -1,6 +1,7 @@ import App from '../../app' import { Variables, Wrap } from '../../render' import { EmailTemplate } from '../../render/Template' +import { unsubscribeEmailLink } from '../../subscriptions/SubscriptionService' import { encodeHashid, pick } from '../../utilities' import { Email } from './Email' import EmailProvider from './EmailProvider' @@ -34,6 +35,13 @@ export default class EmailChannel { 'X-Campaign-Id': encodeHashid(variables.context.campaign_id), 'X-Subscription-Id': encodeHashid(variables.context.subscription_id), }, + list: { + unsubscribe: unsubscribeEmailLink({ + userId: variables.user.id, + campaignId: variables.context.campaign_id, + referenceId: variables.context.reference_id, + }), + }, } const result = await this.provider.send(email) return { diff --git a/apps/platform/src/providers/email/EmailProvider.ts b/apps/platform/src/providers/email/EmailProvider.ts index 8783498b..0aae14c4 100644 --- a/apps/platform/src/providers/email/EmailProvider.ts +++ b/apps/platform/src/providers/email/EmailProvider.ts @@ -14,14 +14,7 @@ export default abstract class EmailProvider extends Provider { static group = 'email' as ProviderGroup async send(message: Email): Promise { - const list = this.unsubscribe - ? { unsubscribe: [this.unsubscribe] } - : undefined - - return await this.transport?.sendMail({ - ...message, - list, - }) + return await this.transport?.sendMail(message) } async verify(): Promise { diff --git a/apps/platform/src/render/index.ts b/apps/platform/src/render/index.ts index e24f26b5..6c15aaa3 100644 --- a/apps/platform/src/render/index.ts +++ b/apps/platform/src/render/index.ts @@ -81,7 +81,7 @@ export const Render = (template: string, { user, event, journey, context }: Vari context, unsubscribeEmailUrl: new Handlebars.SafeString(unsubscribeEmailLink({ userId: user.id, - campaignId: context?.campaign_id, + campaignId: context.campaign_id, referenceId: context.reference_id, })), preferencesUrl: new Handlebars.SafeString(preferencesLink(user.id)), diff --git a/apps/platform/src/subscriptions/SubscriptionController.ts b/apps/platform/src/subscriptions/SubscriptionController.ts index 1e35a1ea..c41eefc0 100644 --- a/apps/platform/src/subscriptions/SubscriptionController.ts +++ b/apps/platform/src/subscriptions/SubscriptionController.ts @@ -54,6 +54,16 @@ publicRouter.get('/email', async ctx => { ctx.body = '

You have been unsubscribed!

' }) +publicRouter.post('/email', async ctx => { + const { user, campaign } = await encodedLinkToParts(ctx.URL) + + if (!user) throw new RequestError(SubscriptionError.UnsubscribeInvalidUser) + if (!campaign) throw new RequestError(SubscriptionError.UnsubscribeInvalidCampaign) + + await unsubscribe(user.id, campaign.subscription_id) + ctx.status = 200 +}) + /** *** * User-facing subscription preferences page