From 9197be0ec74dedfd105bcd80a917dce7fefd0f7f Mon Sep 17 00:00:00 2001 From: roo hutton Date: Wed, 1 Apr 2026 10:22:35 +0100 Subject: [PATCH] Merge pull request #32376 from overleaf/rh-cio-migrate-identifiers Replace analytics id with user id as main identifier in customer.io GitOrigin-RevId: 780671a51b652c73a940bc152d8fd6916dd611ce --- .../src/Features/User/UserPagesController.mjs | 8 ++-- services/web/app/views/_customer_io.pug | 7 +++- ...finalize-stripe-subscription-migration.mjs | 38 +++++++++---------- .../rollback-finalized-stripe-migration.mjs | 22 +++++------ 4 files changed, 35 insertions(+), 40 deletions(-) diff --git a/services/web/app/src/Features/User/UserPagesController.mjs b/services/web/app/src/Features/User/UserPagesController.mjs index ba308bb032..ef7a5fd7e5 100644 --- a/services/web/app/src/Features/User/UserPagesController.mjs +++ b/services/web/app/src/Features/User/UserPagesController.mjs @@ -6,7 +6,6 @@ import Settings from '@overleaf/settings' import AuthenticationController from '../Authentication/AuthenticationController.mjs' import SessionManager from '../Authentication/SessionManager.mjs' import SubscriptionLocator from '../Subscription/SubscriptionLocator.mjs' -import UserAnalyticsIdCache from '../Analytics/UserAnalyticsIdCache.mjs' import _ from 'lodash' import { expressify } from '@overleaf/promise-utils' import Features from '../../infrastructure/Features.mjs' @@ -217,14 +216,15 @@ async function emailPreferencesPage(req, res) { let subscribed = false - const analyticsId = await UserAnalyticsIdCache.get(userId) - if (analyticsId) { + try { const [preferences] = await Modules.promises.hooks.fire( 'getSubscriptionPreferences', - analyticsId + userId ) subscribed = Boolean(preferences?.newsletter) + } catch (err) { + logger.error({ err, userId }, 'Error fetching newsletter subscription') } res.render('user/email-preferences', { diff --git a/services/web/app/views/_customer_io.pug b/services/web/app/views/_customer_io.pug index 182356d597..9ff8bb4bcc 100644 --- a/services/web/app/views/_customer_io.pug +++ b/services/web/app/views/_customer_io.pug @@ -1,7 +1,8 @@ if(customerIoEnabled && ExposedSettings.cioWriteKey && ExposedSettings.cioSiteId) - script(type="text/javascript", id="cio-loader", nonce=scriptNonce, data-cio-write-key=ExposedSettings.cioWriteKey, data-cio-site-id=ExposedSettings.cioSiteId, data-session-analytics-id=getSessionAnalyticsId()). + script(type="text/javascript", id="cio-loader", nonce=scriptNonce, data-cio-write-key=ExposedSettings.cioWriteKey, data-cio-site-id=ExposedSettings.cioSiteId, data-session-analytics-id=getSessionAnalyticsId(), data-user-id=((user && user._id) || '')). var cioSettings = document.querySelector('#cio-loader').dataset; var analyticsId = cioSettings.sessionAnalyticsId; + var userId = cioSettings.userId; var siteId = cioSettings.cioSiteId; var writeKey = cioSettings.cioWriteKey; @@ -19,6 +20,8 @@ if(customerIoEnabled && ExposedSettings.cioWriteKey && ExposedSettings.cioSiteId ); if (analyticsId) { analytics.setAnonymousId(analyticsId); - analytics.identify(analyticsId); + } + if (userId) { + analytics.identify(userId); }; }}(); diff --git a/services/web/scripts/stripe/finalize-stripe-subscription-migration.mjs b/services/web/scripts/stripe/finalize-stripe-subscription-migration.mjs index 76812baf68..eaf1b28fe3 100755 --- a/services/web/scripts/stripe/finalize-stripe-subscription-migration.mjs +++ b/services/web/scripts/stripe/finalize-stripe-subscription-migration.mjs @@ -457,7 +457,6 @@ async function processMigration(input, commit) { recurlySubscription, stripeClient, stripeCustomer, - analyticsId, mongoUser?.email ) } catch (err) { @@ -685,7 +684,6 @@ async function performCutover( recurlySubscription, stripeClient, stripeCustomer, - analyticsId, mongoUserEmail ) { const adminUserId = mongoSubscription.admin_id.toString() @@ -785,27 +783,25 @@ async function performCutover( } // Step 6. Send data to customer.io - if (analyticsId) { - try { - const migrationDate = new Date().toISOString().slice(0, 10) - const needsToUpdateTaxInfo = - (stripeCustomer.metadata?.taxInfoPending || '').length > 0 + try { + const migrationDate = new Date().toISOString().slice(0, 10) + const needsToUpdateTaxInfo = + (stripeCustomer.metadata?.taxInfoPending || '').length > 0 - // TODO: request Recurly account and billingInfo to verify if tax info in Stripe is up to date + // TODO: request Recurly account and billingInfo to verify if tax info in Stripe is up to date - CustomerIoHandler.updateUserAttributes(analyticsId, { - email: mongoUserEmail || stripeCustomer.email, - stripe_migration: { - migration_date: migrationDate, - needs_to_update_tax_id: needsToUpdateTaxInfo, - }, - }) - } catch (err) { - throw new ReportError( - 'migrated-customerio-upload-failed', - `Successfully migrated to Stripe but failed to upload user to customer.io: ${err.message}` - ) - } + CustomerIoHandler.updateUserAttributes(adminUserId, { + email: mongoUserEmail || stripeCustomer.email, + stripe_migration: { + migration_date: migrationDate, + needs_to_update_tax_id: needsToUpdateTaxInfo, + }, + }) + } catch (err) { + throw new ReportError( + 'migrated-customerio-upload-failed', + `Successfully migrated to Stripe but failed to upload user to customer.io: ${err.message}` + ) } // Step 7: Release subscription schedule associated with the migration diff --git a/services/web/scripts/stripe/rollback-finalized-stripe-migration.mjs b/services/web/scripts/stripe/rollback-finalized-stripe-migration.mjs index beee1b667a..e49d83dbde 100755 --- a/services/web/scripts/stripe/rollback-finalized-stripe-migration.mjs +++ b/services/web/scripts/stripe/rollback-finalized-stripe-migration.mjs @@ -38,7 +38,6 @@ import { getRegionClient } from '../../modules/subscriptions/app/src/StripeClien import RecurlyWrapper from '../../app/src/Features/Subscription/RecurlyWrapper.mjs' import { Subscription } from '../../app/src/models/Subscription.mjs' import AnalyticsManager from '../../app/src/Features/Analytics/AnalyticsManager.mjs' -import UserAnalyticsIdCache from '../../app/src/Features/Analytics/UserAnalyticsIdCache.mjs' import CustomerIoHandler from '../../modules/customer-io/app/src/CustomerIoHandler.mjs' import { ReportError } from './helpers.mjs' import AccountMappingHelper from '../../app/src/Features/Analytics/AccountMappingHelper.mjs' @@ -428,18 +427,15 @@ async function performRollback( } // Step 5: Remove migration date from customer.io - const analyticsId = await UserAnalyticsIdCache.get(adminUserId) - if (analyticsId) { - try { - CustomerIoHandler.updateUserAttributes(analyticsId, { - stripe_migration: {}, - }) - } catch (err) { - throw new ReportError( - 'rolled-back-customerio-update-failed', - `Restored Mongo, Recurly, Stripe but failed to update user in customer.io: ${err.message}` - ) - } + try { + CustomerIoHandler.updateUserAttributes(adminUserId, { + stripe_migration: {}, + }) + } catch (err) { + throw new ReportError( + 'rolled-back-customerio-update-failed', + `Restored Mongo, Recurly, Stripe but failed to update user in customer.io: ${err.message}` + ) } }