fix: mixpanel issues (#6840)

This commit is contained in:
pengx17
2024-05-09 07:50:14 +00:00
parent 3744a0a5e0
commit 917ad1965a
7 changed files with 52 additions and 23 deletions

View File

@@ -9,8 +9,6 @@ import bytes from 'bytes';
import { useAtom, useSetAtom } from 'jotai'; import { useAtom, useSetAtom } from 'jotai';
import { useCallback, useEffect, useMemo } from 'react'; import { useCallback, useEffect, useMemo } from 'react';
import { mixpanel } from '../../../utils';
export const CloudQuotaModal = () => { export const CloudQuotaModal = () => {
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const currentWorkspace = useService(WorkspaceService).workspace; const currentWorkspace = useService(WorkspaceService).workspace;
@@ -93,14 +91,6 @@ export const CloudQuotaModal = () => {
}; };
}, [currentWorkspace.engine.blob, setOpen, workspaceQuota]); }, [currentWorkspace.engine.blob, setOpen, workspaceQuota]);
useEffect(() => {
if (userQuota?.name) {
mixpanel.people.set({
plan: userQuota.name,
});
}
}, [userQuota?.name]);
return ( return (
<ConfirmModal <ConfirmModal
open={open} open={open}

View File

@@ -1,5 +1,4 @@
import { mixpanel } from '@affine/core/utils'; import { mixpanel } from '@affine/core/utils';
import { DebugLogger } from '@affine/debug';
import type { EditorHost } from '@blocksuite/block-std'; import type { EditorHost } from '@blocksuite/block-std';
import type { ElementModel } from '@blocksuite/blocks'; import type { ElementModel } from '@blocksuite/blocks';
import { AIProvider } from '@blocksuite/presets'; import { AIProvider } from '@blocksuite/presets';
@@ -58,8 +57,6 @@ type BlocksuiteActionEvent = Parameters<
Parameters<typeof AIProvider.slots.actions.on>[0] Parameters<typeof AIProvider.slots.actions.on>[0]
>[0]; >[0];
const logger = new DebugLogger('affine:ai-tracker');
const trackAction = ({ const trackAction = ({
eventName, eventName,
properties, properties,
@@ -67,7 +64,6 @@ const trackAction = ({
eventName: AIActionEventName; eventName: AIActionEventName;
properties: AIActionEventProperties; properties: AIActionEventProperties;
}) => { }) => {
logger.debug('trackAction', eventName, properties);
mixpanel.track(eventName, properties); mixpanel.track(eventName, properties);
}; };

View File

@@ -1,10 +1,23 @@
import { OnEvent, Service } from '@toeverything/infra'; import type { QuotaQuery } from '@affine/graphql';
import { createEvent, OnEvent, Service } from '@toeverything/infra';
import { UserQuota } from '../entities/user-quota'; import { UserQuota } from '../entities/user-quota';
import { AccountChanged } from './auth'; import { AccountChanged } from './auth';
type UserQuotaInfo = NonNullable<QuotaQuery['currentUser']>['quota'];
export const UserQuotaChanged = createEvent<UserQuotaInfo>('UserQuotaChanged');
@OnEvent(AccountChanged, e => e.onAccountChanged) @OnEvent(AccountChanged, e => e.onAccountChanged)
export class UserQuotaService extends Service { export class UserQuotaService extends Service {
constructor() {
super();
this.quota.quota$.distinctUntilChanged().subscribe(q => {
this.eventBus.emit(UserQuotaChanged, q);
});
}
quota = this.framework.createEntity(UserQuota); quota = this.framework.createEntity(UserQuota);
private onAccountChanged() { private onAccountChanged() {

View File

@@ -1,4 +1,5 @@
import { mixpanel } from '@affine/core/utils'; import { mixpanel } from '@affine/core/utils';
import type { QuotaQuery } from '@affine/graphql';
import { ApplicationStarted, OnEvent, Service } from '@toeverything/infra'; import { ApplicationStarted, OnEvent, Service } from '@toeverything/infra';
import { import {
@@ -6,10 +7,15 @@ import {
type AuthAccountInfo, type AuthAccountInfo,
type AuthService, type AuthService,
} from '../../cloud'; } from '../../cloud';
import { UserQuotaChanged } from '../../cloud/services/user-quota';
@OnEvent(ApplicationStarted, e => e.onApplicationStart) @OnEvent(ApplicationStarted, e => e.onApplicationStart)
@OnEvent(AccountChanged, e => e.onAccountChanged) @OnEvent(AccountChanged, e => e.onAccountChanged)
@OnEvent(UserQuotaChanged, e => e.onUserQuotaChanged)
export class TelemetryService extends Service { export class TelemetryService extends Service {
private prevQuota: NonNullable<QuotaQuery['currentUser']>['quota'] | null =
null;
constructor(private readonly auth: AuthService) { constructor(private readonly auth: AuthService) {
super(); super();
} }
@@ -22,9 +28,7 @@ export class TelemetryService extends Service {
}); });
} }
const account = this.auth.session.account$.value; const account = this.auth.session.account$.value;
if (account) { this.onAccountChanged(account);
mixpanel.identify(account.id);
}
} }
onAccountChanged(account: AuthAccountInfo | null) { onAccountChanged(account: AuthAccountInfo | null) {
@@ -33,6 +37,22 @@ export class TelemetryService extends Service {
} else { } else {
mixpanel.reset(); mixpanel.reset();
mixpanel.identify(account.id); mixpanel.identify(account.id);
mixpanel.people.set({
$email: account.email,
$name: account.label,
$avatar: account.avatar,
});
} }
} }
onUserQuotaChanged(quota: NonNullable<QuotaQuery['currentUser']>['quota']) {
const plan = quota?.humanReadable.name;
// only set when plan is not empty and changed
if (plan !== this.prevQuota?.humanReadable.name && plan) {
mixpanel.people.set({
plan: quota?.humanReadable.name,
});
}
this.prevQuota = quota;
}
} }

View File

@@ -30,6 +30,7 @@ function RootRouter() {
environment: runtimeConfig.appBuildType, environment: runtimeConfig.appBuildType,
editorVersion: runtimeConfig.editorVersion, editorVersion: runtimeConfig.editorVersion,
isSelfHosted: Boolean(runtimeConfig.isSelfHosted), isSelfHosted: Boolean(runtimeConfig.isSelfHosted),
isDesktop: environment.isDesktop,
}); });
}, [location]); }, [location]);
return ( return (

View File

@@ -1,6 +1,9 @@
import { DebugLogger } from '@affine/debug';
import type { OverridedMixpanel } from 'mixpanel-browser'; import type { OverridedMixpanel } from 'mixpanel-browser';
import mixpanelBrowser from 'mixpanel-browser'; import mixpanelBrowser from 'mixpanel-browser';
const logger = new DebugLogger('affine:mixpanel');
export const mixpanel = process.env.MIXPANEL_TOKEN export const mixpanel = process.env.MIXPANEL_TOKEN
? mixpanelBrowser ? mixpanelBrowser
: new Proxy( : new Proxy(
@@ -10,15 +13,19 @@ export const mixpanel = process.env.MIXPANEL_TOKEN
function createProxyHandler(property?: string | symbol) { function createProxyHandler(property?: string | symbol) {
const handler = { const handler = {
get: (_target, property) => { get: (_target, childProperty) => {
const path = property
? String(property) + '.' + String(childProperty)
: String(childProperty);
return new Proxy( return new Proxy(
function () {} as unknown as OverridedMixpanel, function () {} as unknown as OverridedMixpanel,
createProxyHandler(property) createProxyHandler(path)
); );
}, },
apply: (_target, _thisArg, args) => { apply: (_target, _thisArg, args) => {
console.info( logger.debug(
`Mixpanel is not initialized, calling ${property ? String(property) : 'mixpanel'} with args: ${JSON.stringify(args)}` `mixpanel.${property ? String(property) : 'mixpanel'}`,
...args
); );
}, },
} as ProxyHandler<OverridedMixpanel>; } as ProxyHandler<OverridedMixpanel>;

View File

@@ -349,7 +349,9 @@ export const createConfiguration: (
), ),
'process.env.SENTRY_DSN': JSON.stringify(process.env.SENTRY_DSN), 'process.env.SENTRY_DSN': JSON.stringify(process.env.SENTRY_DSN),
'process.env.BUILD_TYPE': JSON.stringify(process.env.BUILD_TYPE), 'process.env.BUILD_TYPE': JSON.stringify(process.env.BUILD_TYPE),
'process.env.MIXPANEL_TOKEN': `"${process.env.MIXPANEL_TOKEN}"`, 'process.env.MIXPANEL_TOKEN': JSON.stringify(
process.env.MIXPANEL_TOKEN
),
runtimeConfig: JSON.stringify(runtimeConfig), runtimeConfig: JSON.stringify(runtimeConfig),
}), }),
new CopyPlugin({ new CopyPlugin({