mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-14 14:13:43 +01:00
Merge pull request #29838 from overleaf/rh-cio-remove-limits
Enable customer.io for all users GitOrigin-RevId: 74d8424924ec30ad3a6cb48c15e285cc696186fd
This commit is contained in:
@@ -807,6 +807,12 @@ const _ProjectController = {
|
||||
userIsMemberOfGroupSubscription
|
||||
)
|
||||
|
||||
AnalyticsManager.setUserPropertyForUserInBackground(
|
||||
userId,
|
||||
'customer-io-integration',
|
||||
true
|
||||
)
|
||||
|
||||
const template =
|
||||
detachRole === 'detached'
|
||||
? 'project/ide-react-detached'
|
||||
@@ -845,15 +851,6 @@ const _ProjectController = {
|
||||
fullFeatureSet?.aiErrorAssistant) &&
|
||||
!assistantDisabled
|
||||
|
||||
const customerIoEnabled =
|
||||
await SplitTestHandler.promises.hasUserBeenAssignedToVariant(
|
||||
req,
|
||||
userId,
|
||||
'customer-io-trial-conversion',
|
||||
'enabled',
|
||||
true
|
||||
)
|
||||
|
||||
const addonPrices =
|
||||
isOverleafAssistBundleEnabled &&
|
||||
(await ProjectController._getAddonPrices(req, res))
|
||||
@@ -971,7 +968,7 @@ const _ProjectController = {
|
||||
isSaas: Features.hasFeature('saas'),
|
||||
shouldLoadHotjar,
|
||||
isOverleafAssistBundleEnabled,
|
||||
customerIoEnabled,
|
||||
customerIoEnabled: true,
|
||||
addonPrices,
|
||||
compileSettings: {
|
||||
compileTimeout: ownerFeatures?.compileTimeout,
|
||||
|
||||
@@ -179,6 +179,13 @@ async function projectListPage(req, res, next) {
|
||||
|
||||
user.refProviders = _.mapValues(user.refProviders, Boolean)
|
||||
|
||||
let onboardingDataCollection
|
||||
let customerIoEnabled = false
|
||||
let subjectArea
|
||||
let usedLatex
|
||||
let primaryOccupation
|
||||
let role
|
||||
|
||||
if (isSaas) {
|
||||
await SplitTestSessionHandler.promises.sessionMaintenance(req, user)
|
||||
|
||||
@@ -227,6 +234,26 @@ async function projectListPage(req, res, next) {
|
||||
) {
|
||||
return res.redirect('/user/emails/primary-email-check')
|
||||
}
|
||||
|
||||
onboardingDataCollection = await OnboardingDataCollection.findById(
|
||||
userId,
|
||||
'subjectArea usedLatex primaryOccupation role'
|
||||
)
|
||||
|
||||
if (onboardingDataCollection) {
|
||||
subjectArea = onboardingDataCollection.subjectArea
|
||||
usedLatex = onboardingDataCollection.usedLatex
|
||||
primaryOccupation = onboardingDataCollection.primaryOccupation
|
||||
role = onboardingDataCollection.role
|
||||
}
|
||||
|
||||
customerIoEnabled = true
|
||||
|
||||
AnalyticsManager.setUserPropertyForUserInBackground(
|
||||
userId,
|
||||
'customer-io-integration',
|
||||
true
|
||||
)
|
||||
}
|
||||
|
||||
const tags = await TagsHandler.promises.getAllTags(userId)
|
||||
@@ -274,6 +301,10 @@ async function projectListPage(req, res, next) {
|
||||
return result
|
||||
})
|
||||
|
||||
const commonsInstitution = userAffiliations.find(
|
||||
affiliation => affiliation.institution?.commonsAccount
|
||||
)?.institution?.name
|
||||
|
||||
const portalTemplates = _buildPortalTemplatesList(userAffiliations)
|
||||
|
||||
const { allInReconfirmNotificationPeriods } = userEmailsData
|
||||
@@ -474,64 +505,9 @@ async function projectListPage(req, res, next) {
|
||||
logger.error({ err: error }, 'Failed to get individual subscription')
|
||||
}
|
||||
|
||||
const affiliations = userAffiliations || []
|
||||
const commonsInstitution = affiliations.find(
|
||||
affiliation => affiliation.institution?.commonsAccount
|
||||
)?.institution?.name
|
||||
|
||||
let onboardingDataCollection
|
||||
let subjectArea
|
||||
let usedLatex
|
||||
let primaryOccupation
|
||||
let role
|
||||
|
||||
// customer.io: Premium nudge experiment
|
||||
// Only do customer-io-trial-conversion assignment for users not in India/China and not in group/commons
|
||||
let customerIoEnabled = false
|
||||
const aiBlocked = !(await _canUseAIAssist(user))
|
||||
const hasAiAssist = await _userHasAIAssist(user)
|
||||
|
||||
if (!userIsMemberOfGroupSubscription && !commonsInstitution && isSaas) {
|
||||
try {
|
||||
const excludedCountries = ['IN', 'CN']
|
||||
|
||||
if (!excludedCountries.includes(countryCode)) {
|
||||
const cioAssignment =
|
||||
await SplitTestHandler.promises.getAssignmentForUser(
|
||||
userId,
|
||||
'customer-io-trial-conversion'
|
||||
)
|
||||
if (cioAssignment.variant === 'enabled') {
|
||||
customerIoEnabled = true
|
||||
onboardingDataCollection = await OnboardingDataCollection.findById(
|
||||
userId,
|
||||
'subjectArea usedLatex primaryOccupation role'
|
||||
)
|
||||
|
||||
if (onboardingDataCollection) {
|
||||
subjectArea = onboardingDataCollection.subjectArea
|
||||
usedLatex = onboardingDataCollection.usedLatex
|
||||
primaryOccupation = onboardingDataCollection.primaryOccupation
|
||||
role = onboardingDataCollection.role
|
||||
}
|
||||
|
||||
AnalyticsManager.setUserPropertyForUserInBackground(
|
||||
userId,
|
||||
'customer-io-integration',
|
||||
true
|
||||
)
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.error(
|
||||
{ err },
|
||||
'Error checking geo location for customer-io-trial-conversion'
|
||||
)
|
||||
// Fallback to not enabled if geoip fails
|
||||
customerIoEnabled = false
|
||||
}
|
||||
}
|
||||
|
||||
await SplitTestHandler.promises.getAssignment(
|
||||
req,
|
||||
res,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import SplitTestHandler from '../SplitTests/SplitTestHandler.mjs'
|
||||
import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
|
||||
import SubscriptionEmailHandler from './SubscriptionEmailHandler.mjs'
|
||||
import { AI_ADD_ON_CODE } from './AiHelper.mjs'
|
||||
@@ -15,6 +14,8 @@ async function sendRecurlyAnalyticsEvent(event, eventData) {
|
||||
return
|
||||
}
|
||||
|
||||
eventData['customerio-integration'] = true
|
||||
|
||||
const subscription =
|
||||
await SubscriptionLocator.promises.getUsersSubscription(userId)
|
||||
|
||||
@@ -26,16 +27,6 @@ async function sendRecurlyAnalyticsEvent(event, eventData) {
|
||||
return
|
||||
}
|
||||
|
||||
const customerIoEnabled =
|
||||
await SplitTestHandler.promises.hasUserBeenAssignedToVariant(
|
||||
{},
|
||||
userId,
|
||||
'customer-io-trial-conversion',
|
||||
'enabled',
|
||||
true
|
||||
)
|
||||
eventData['customerio-integration'] = customerIoEnabled || false
|
||||
|
||||
switch (event) {
|
||||
case 'new_subscription_notification':
|
||||
await _sendSubscriptionStartedEvent(userId, eventData)
|
||||
@@ -158,17 +149,6 @@ async function _sendSubscriptionStartedEvent(userId, eventData) {
|
||||
|
||||
if (isTrial) {
|
||||
await SubscriptionEmailHandler.sendTrialOnboardingEmail(userId, planCode)
|
||||
const cioAssignment = await SplitTestHandler.promises.getAssignmentForUser(
|
||||
userId,
|
||||
'customer-io-trial-conversion'
|
||||
)
|
||||
if (cioAssignment.variant === 'enabled') {
|
||||
AnalyticsManager.setUserPropertyForUserInBackground(
|
||||
userId,
|
||||
'customer-io-integration',
|
||||
true
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -417,6 +417,7 @@ describe('ProjectController', function () {
|
||||
() => ({
|
||||
default: {
|
||||
recordEventForUserInBackground: () => {},
|
||||
setUserPropertyForUserInBackground: () => {},
|
||||
},
|
||||
})
|
||||
)
|
||||
|
||||
@@ -10,7 +10,11 @@ const MODULE_PATH = `${import.meta.dirname}/../../../../app/src/Features/Project
|
||||
|
||||
// Mock AnalyticsManager as it isn't used in these tests but causes the User model to be imported and redeclares queues
|
||||
vi.mock('../../../../app/src/Features/Analytics/AnalyticsManager.mjs', () => {
|
||||
return {}
|
||||
return {
|
||||
default: {
|
||||
setUserPropertyForUserInBackground: () => {},
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
describe('ProjectListController', function () {
|
||||
|
||||
@@ -120,47 +120,6 @@ describe('RecurlyEventHandler', function () {
|
||||
})
|
||||
|
||||
it('with new_subscription_notification - free trial', async function (ctx) {
|
||||
await ctx.RecurlyEventHandler.sendRecurlyAnalyticsEvent(
|
||||
'new_subscription_notification',
|
||||
ctx.eventData
|
||||
)
|
||||
sinon.assert.calledWith(
|
||||
ctx.AnalyticsManager.recordEventForUserInBackground,
|
||||
ctx.userId,
|
||||
'subscription-started',
|
||||
{
|
||||
plan_code: ctx.planCode,
|
||||
quantity: 1,
|
||||
is_trial: true,
|
||||
has_ai_add_on: false,
|
||||
subscriptionId: ctx.eventData.subscription.uuid,
|
||||
payment_provider: 'recurly',
|
||||
'customerio-integration': false,
|
||||
}
|
||||
)
|
||||
sinon.assert.calledWith(
|
||||
ctx.AnalyticsManager.setUserPropertyForUserInBackground,
|
||||
ctx.userId,
|
||||
'subscription-plan-code',
|
||||
ctx.planCode
|
||||
)
|
||||
sinon.assert.calledWith(
|
||||
ctx.AnalyticsManager.setUserPropertyForUserInBackground,
|
||||
ctx.userId,
|
||||
'subscription-state',
|
||||
'active'
|
||||
)
|
||||
sinon.assert.calledWith(
|
||||
ctx.AnalyticsManager.setUserPropertyForUserInBackground,
|
||||
ctx.userId,
|
||||
'subscription-is-trial',
|
||||
true
|
||||
)
|
||||
})
|
||||
|
||||
it('with new_subscription_notification - free trial with customerio integration enabled', async function (ctx) {
|
||||
ctx.SplitTestHandler.promises.hasUserBeenAssignedToVariant.resolves(true)
|
||||
|
||||
await ctx.RecurlyEventHandler.sendRecurlyAnalyticsEvent(
|
||||
'new_subscription_notification',
|
||||
ctx.eventData
|
||||
@@ -232,7 +191,7 @@ describe('RecurlyEventHandler', function () {
|
||||
has_ai_add_on: false,
|
||||
subscriptionId: ctx.eventData.subscription.uuid,
|
||||
payment_provider: 'recurly',
|
||||
'customerio-integration': false,
|
||||
'customerio-integration': true,
|
||||
}
|
||||
)
|
||||
sinon.assert.calledWith(
|
||||
@@ -252,49 +211,6 @@ describe('RecurlyEventHandler', function () {
|
||||
it('with updated_subscription_notification', async function (ctx) {
|
||||
ctx.planCode = 'new-plan-code'
|
||||
ctx.eventData.subscription.plan.plan_code = ctx.planCode
|
||||
await ctx.RecurlyEventHandler.sendRecurlyAnalyticsEvent(
|
||||
'updated_subscription_notification',
|
||||
ctx.eventData
|
||||
)
|
||||
sinon.assert.calledWith(
|
||||
ctx.AnalyticsManager.recordEventForUserInBackground,
|
||||
ctx.userId,
|
||||
'subscription-updated',
|
||||
{
|
||||
plan_code: ctx.planCode,
|
||||
quantity: 1,
|
||||
is_trial: true,
|
||||
has_ai_add_on: false,
|
||||
subscriptionId: ctx.eventData.subscription.uuid,
|
||||
payment_provider: 'recurly',
|
||||
'customerio-integration': false,
|
||||
}
|
||||
)
|
||||
sinon.assert.calledWith(
|
||||
ctx.AnalyticsManager.setUserPropertyForUserInBackground,
|
||||
ctx.userId,
|
||||
'subscription-plan-code',
|
||||
ctx.planCode
|
||||
)
|
||||
sinon.assert.calledWith(
|
||||
ctx.AnalyticsManager.setUserPropertyForUserInBackground,
|
||||
ctx.userId,
|
||||
'subscription-state',
|
||||
'active'
|
||||
)
|
||||
sinon.assert.calledWith(
|
||||
ctx.AnalyticsManager.setUserPropertyForUserInBackground,
|
||||
ctx.userId,
|
||||
'subscription-is-trial',
|
||||
true
|
||||
)
|
||||
})
|
||||
|
||||
it('with updated_subscription_notification with customerio integration enabled', async function (ctx) {
|
||||
ctx.SplitTestHandler.promises.hasUserBeenAssignedToVariant.resolves(true)
|
||||
ctx.planCode = 'new-plan-code'
|
||||
ctx.eventData.subscription.plan.plan_code = ctx.planCode
|
||||
|
||||
await ctx.RecurlyEventHandler.sendRecurlyAnalyticsEvent(
|
||||
'updated_subscription_notification',
|
||||
ctx.eventData
|
||||
@@ -350,7 +266,7 @@ describe('RecurlyEventHandler', function () {
|
||||
has_ai_add_on: false,
|
||||
subscriptionId: ctx.eventData.subscription.uuid,
|
||||
payment_provider: 'recurly',
|
||||
'customerio-integration': false,
|
||||
'customerio-integration': true,
|
||||
}
|
||||
)
|
||||
sinon.assert.calledWith(
|
||||
@@ -384,7 +300,7 @@ describe('RecurlyEventHandler', function () {
|
||||
has_ai_add_on: false,
|
||||
subscriptionId: ctx.eventData.subscription.uuid,
|
||||
payment_provider: 'recurly',
|
||||
'customerio-integration': false,
|
||||
'customerio-integration': true,
|
||||
}
|
||||
)
|
||||
sinon.assert.calledWith(
|
||||
@@ -423,7 +339,7 @@ describe('RecurlyEventHandler', function () {
|
||||
has_ai_add_on: false,
|
||||
subscriptionId: ctx.eventData.subscription.uuid,
|
||||
payment_provider: 'recurly',
|
||||
'customerio-integration': false,
|
||||
'customerio-integration': true,
|
||||
}
|
||||
)
|
||||
})
|
||||
@@ -443,7 +359,7 @@ describe('RecurlyEventHandler', function () {
|
||||
has_ai_add_on: false,
|
||||
subscriptionId: ctx.eventData.subscription.uuid,
|
||||
payment_provider: 'recurly',
|
||||
'customerio-integration': false,
|
||||
'customerio-integration': true,
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user