diff --git a/app/components/lobbyside-widget/index.hbs b/app/components/lobbyside-widget/index.hbs index 63a4772d58..57a634b5d8 100644 --- a/app/components/lobbyside-widget/index.hbs +++ b/app/components/lobbyside-widget/index.hbs @@ -25,6 +25,7 @@ this.customFields.stages_completed this.customFields.signed_up_date this.customFields.subscription_type + this.customFields.other_emails }} {{will-destroy this.removeScript}} > diff --git a/app/components/lobbyside-widget/index.ts b/app/components/lobbyside-widget/index.ts index a33cfaab73..7961d40ca5 100644 --- a/app/components/lobbyside-widget/index.ts +++ b/app/components/lobbyside-widget/index.ts @@ -15,6 +15,7 @@ declare global { stages_completed: string; signed_up_date: string; subscription_type: string; + other_emails: string; }): void; }; } @@ -30,12 +31,15 @@ interface VisitorSource { hasActiveSubscription?: boolean; teamHasActiveSubscription?: boolean; courseParticipations?: { completedStageSlugs?: string[] }[]; + primaryEmailAddress?: string | null; + emailAddresses?: { value?: string | null }[]; } export interface LobbysideCustomFields { stages_completed: string; signed_up_date: string; subscription_type: string; + other_emails: string; } function subscriptionType(user: VisitorSource | null | undefined): string { @@ -62,6 +66,21 @@ function subscriptionType(user: VisitorSource | null | undefined): string { return 'free'; } +function otherEmails(user: VisitorSource | null | undefined): string { + const primary = (user?.primaryEmailAddress ?? '').trim(); + const seen = new Set(); + + for (const entry of user?.emailAddresses ?? []) { + const value = (entry?.value ?? '').trim(); + + if (value && value !== primary) { + seen.add(value); + } + } + + return Array.from(seen).join(', '); +} + export function lobbysideCustomFields(user: VisitorSource | null | undefined): LobbysideCustomFields { const stagesCompleted = (user?.courseParticipations ?? []).reduce( (sum, participation) => sum + (participation.completedStageSlugs?.length ?? 0), @@ -72,6 +91,7 @@ export function lobbysideCustomFields(user: VisitorSource | null | undefined): L stages_completed: String(stagesCompleted), signed_up_date: user?.createdAt ? user.createdAt.toISOString().slice(0, 10) : '', subscription_type: subscriptionType(user), + other_emails: otherEmails(user), }; } diff --git a/app/services/authenticator.ts b/app/services/authenticator.ts index ade1e9a669..486303a503 100644 --- a/app/services/authenticator.ts +++ b/app/services/authenticator.ts @@ -118,6 +118,8 @@ export default class AuthenticatorService extends Service { 'affiliate-links.user', // Powers the `stages_completed` field the Lobbyside widget pushes via setVisitor. 'course-participations', + // Powers the `other_emails` field the Lobbyside widget pushes via setVisitor. + 'email-addresses', 'feature-suggestions', 'promotional-discounts', 'promotional-discounts.affiliate-referral', diff --git a/tests/unit/components/lobbyside-widget-test.ts b/tests/unit/components/lobbyside-widget-test.ts index fd8994d7ac..ba91341f36 100644 --- a/tests/unit/components/lobbyside-widget-test.ts +++ b/tests/unit/components/lobbyside-widget-test.ts @@ -20,6 +20,7 @@ module('Unit | Component | lobbyside-widget', function () { stages_completed: '0', signed_up_date: '', subscription_type: '', + other_emails: '', }); }); @@ -57,4 +58,37 @@ module('Unit | Component | lobbyside-widget', function () { assert.strictEqual(lobbysideCustomFields(createUser()).subscription_type, 'free'); }); + + test('other_emails joins every non-primary email, comma-separated', function (assert) { + const user = createUser({ + primaryEmailAddress: 'primary@example.com', + emailAddresses: [{ value: 'primary@example.com' }, { value: 'work@example.com' }, { value: 'school@example.com' }], + } as unknown as Partial); + + assert.strictEqual(lobbysideCustomFields(user).other_emails, 'work@example.com, school@example.com'); + }); + + test('other_emails excludes the primary email and is empty when it is the only one', function (assert) { + const user = createUser({ + primaryEmailAddress: 'primary@example.com', + emailAddresses: [{ value: 'primary@example.com' }], + } as unknown as Partial); + + assert.strictEqual(lobbysideCustomFields(user).other_emails, ''); + }); + + test('other_emails dedupes and drops blank values', function (assert) { + const user = createUser({ + primaryEmailAddress: 'primary@example.com', + emailAddresses: [{ value: 'work@example.com' }, { value: ' work@example.com ' }, { value: '' }, { value: 'alt@example.com' }], + } as unknown as Partial); + + assert.strictEqual(lobbysideCustomFields(user).other_emails, 'work@example.com, alt@example.com'); + }); + + test('other_emails is empty when the user has no email addresses', function (assert) { + const user = createUser({ primaryEmailAddress: 'primary@example.com', emailAddresses: [] } as unknown as Partial); + + assert.strictEqual(lobbysideCustomFields(user).other_emails, ''); + }); });