Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Remove PostHog event calls #6915

Merged
merged 11 commits into from
Aug 17, 2023
43 changes: 16 additions & 27 deletions packages/cli/src/InternalHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ export class InternalHooks implements IInternalHooksClass {
return this.telemetry.track(
'User responded to personalization questions',
personalizationSurveyData,
{ withPostHog: true },
);
}

Expand Down Expand Up @@ -190,21 +189,17 @@ export class InternalHooks implements IInternalHooksClass {
workflowName: workflow.name,
},
}),
this.telemetry.track(
'User saved workflow',
{
user_id: user.id,
workflow_id: workflow.id,
node_graph_string: JSON.stringify(nodeGraph),
notes_count_overlapping: overlappingCount,
notes_count_non_overlapping: notesCount - overlappingCount,
version_cli: N8N_VERSION,
num_tags: workflow.tags?.length ?? 0,
public_api: publicApi,
sharing_role: userRole,
},
{ withPostHog: true },
),
this.telemetry.track('User saved workflow', {
user_id: user.id,
workflow_id: workflow.id,
node_graph_string: JSON.stringify(nodeGraph),
notes_count_overlapping: overlappingCount,
notes_count_non_overlapping: notesCount - overlappingCount,
version_cli: N8N_VERSION,
num_tags: workflow.tags?.length ?? 0,
public_api: publicApi,
sharing_role: userRole,
}),
]);
}

Expand Down Expand Up @@ -415,11 +410,7 @@ export class InternalHooks implements IInternalHooksClass {
node_id: nodeGraphResult.nameIndices[runData.data.startData?.destinationNode],
};

promises.push(
this.telemetry.track('Manual node exec finished', telemetryPayload, {
withPostHog: true,
}),
);
promises.push(this.telemetry.track('Manual node exec finished', telemetryPayload));
} else {
nodeGraphResult.webhookNodeNames.forEach((name: string) => {
const execJson = runData.data.resultData.runData[name]?.[0]?.data?.main?.[0]?.[0]
Expand All @@ -432,9 +423,7 @@ export class InternalHooks implements IInternalHooksClass {
});

promises.push(
this.telemetry.track('Manual workflow exec finished', manualExecEventProperties, {
withPostHog: true,
}),
this.telemetry.track('Manual workflow exec finished', manualExecEventProperties),
);
}
}
Expand Down Expand Up @@ -484,7 +473,7 @@ export class InternalHooks implements IInternalHooksClass {
user_id_list: userList,
};

return this.telemetry.track('User updated workflow sharing', properties, { withPostHog: true });
return this.telemetry.track('User updated workflow sharing', properties);
}

async onN8nStop(): Promise<void> {
Expand Down Expand Up @@ -1017,7 +1006,7 @@ export class InternalHooks implements IInternalHooksClass {
user_id: string;
workflow_id: string;
}): Promise<void> {
return this.telemetry.track('Workflow first prod success', data, { withPostHog: true });
return this.telemetry.track('Workflow first prod success', data);
}

async onFirstWorkflowDataLoad(data: {
Expand All @@ -1028,7 +1017,7 @@ export class InternalHooks implements IInternalHooksClass {
credential_type?: string;
credential_id?: string;
}): Promise<void> {
return this.telemetry.track('Workflow first data fetched', data, { withPostHog: true });
return this.telemetry.track('Workflow first data fetched', data);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/Server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ export class Server extends AbstractServer {
const controllers: object[] = [
new EventBusController(),
new AuthController({ config, internalHooks, repositories, logger, postHog }),
new OwnerController({ config, internalHooks, repositories, logger }),
new OwnerController({ config, internalHooks, repositories, logger, postHog }),
new MeController({ externalHooks, internalHooks, repositories, logger }),
new NodeTypesController({ config, nodeTypes }),
new PasswordResetController({
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/config/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ export const schema = {
externalFrontendHooksUrls: {
doc: 'URLs to external frontend hooks files, ; separated',
format: String,
default: 'https://public.n8n.cloud/posthog-hooks.js',
default: '',
env: 'EXTERNAL_FRONTEND_HOOKS_URLS',
},

Expand Down
9 changes: 8 additions & 1 deletion packages/cli/src/controllers/owner.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
hashPassword,
sanitizeUser,
validatePassword,
withFeatureFlags,
} from '@/UserManagement/UserManagementHelper';
import { issueCookie } from '@/auth/jwt';
import { Response } from 'express';
Expand All @@ -14,6 +15,7 @@ import type { Config } from '@/config';
import { OwnerRequest } from '@/requests';
import type { IDatabaseCollections, IInternalHooksClass } from '@/Interfaces';
import type { SettingsRepository, UserRepository } from '@db/repositories';
import type { PostHogClient } from '@/posthog';

@Authorized(['global', 'owner'])
@RestController('/owner')
Expand All @@ -28,22 +30,27 @@ export class OwnerController {

private readonly settingsRepository: SettingsRepository;

private readonly postHog?: PostHogClient;

constructor({
config,
logger,
internalHooks,
repositories,
postHog,
}: {
config: Config;
logger: ILogger;
internalHooks: IInternalHooksClass;
repositories: Pick<IDatabaseCollections, 'User' | 'Settings'>;
postHog?: PostHogClient;
}) {
this.config = config;
this.logger = logger;
this.internalHooks = internalHooks;
this.userRepository = repositories.User;
this.settingsRepository = repositories.Settings;
this.postHog = postHog;
}

/**
Expand Down Expand Up @@ -122,7 +129,7 @@ export class OwnerController {

void this.internalHooks.onInstanceOwnerSetup({ user_id: userId });

return sanitizeUser(owner);
return withFeatureFlags(this.postHog, sanitizeUser(owner));
}

@Post('/dismiss-banner')
Expand Down
14 changes: 5 additions & 9 deletions packages/cli/src/telemetry/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,11 @@ export class Telemetry {
return sum > 0;
})
.map(async (workflowId) => {
const promise = this.track(
'Workflow execution count',
{
event_version: '2',
workflow_id: workflowId,
...this.executionCountsBuffer[workflowId],
},
{ withPostHog: true },
);
const promise = this.track('Workflow execution count', {
event_version: '2',
workflow_id: workflowId,
...this.executionCountsBuffer[workflowId],
});

return promise;
});
Expand Down
6 changes: 6 additions & 0 deletions packages/editor-ui/src/Interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ declare global {
reset?(resetDeviceId?: boolean): void;
onFeatureFlags?(callback: (keys: string[], map: FeatureFlags) => void): void;
reloadFeatureFlags?(): void;
capture?(event: string, properties: IDataObject): void;
register?(metadata: IDataObject): void;
people?: {
set?(metadata: IDataObject): void;
};
debug?(): void;
};
analytics?: {
track(event: string, proeprties?: ITelemetryTrackProperties): void;
Expand Down
2 changes: 1 addition & 1 deletion packages/editor-ui/src/api/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export async function logout(context: IRestApiContext): Promise<void> {
export async function setupOwner(
context: IRestApiContext,
params: { firstName: string; lastName: string; email: string; password: string },
): Promise<IUserResponse> {
): Promise<CurrentUserResponse> {
return makeRestApiRequest(context, 'POST', '/owner/setup', params as unknown as IDataObject);
}

Expand Down
5 changes: 4 additions & 1 deletion packages/editor-ui/src/components/PersonalizationModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ import { useSettingsStore } from '@/stores/settings.store';
import { useRootStore } from '@/stores/n8nRoot.store';
import { useUsersStore } from '@/stores/users.store';
import { createEventBus } from 'n8n-design-system/utils';
import { usePostHog } from '@/stores';
export default defineComponent({
name: 'PersonalizationModal',
Expand Down Expand Up @@ -166,7 +167,7 @@ export default defineComponent({
};
},
computed: {
...mapStores(useRootStore, useSettingsStore, useUIStore, useUsersStore),
...mapStores(useRootStore, useSettingsStore, useUIStore, useUsersStore, usePostHog),
survey() {
const survey: IFormInputs = [
{
Expand Down Expand Up @@ -645,6 +646,8 @@ export default defineComponent({
await this.usersStore.submitPersonalizationSurvey(survey as IPersonalizationLatestVersion);
this.posthogStore.setMetadata(survey, 'user');
if (Object.keys(values).length === 0) {
this.closeDialog();
}
Expand Down
15 changes: 12 additions & 3 deletions packages/editor-ui/src/plugins/telemetry/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useSettingsStore } from '@/stores/settings.store';
import { useRootStore } from '@/stores/n8nRoot.store';
import { useTelemetryStore } from '@/stores/telemetry.store';
import { SLACK_NODE_TYPE } from '@/constants';
import { usePostHog } from '@/stores/posthog.store';

export class Telemetry {
constructor(
Expand Down Expand Up @@ -72,7 +73,11 @@ export class Telemetry {
}
}

track(event: string, properties?: ITelemetryTrackProperties) {
track(
event: string,
properties?: ITelemetryTrackProperties,
{ withPostHog } = { withPostHog: false },
) {
if (!this.rudderStack) return;

const updatedProperties = {
Expand All @@ -81,6 +86,10 @@ export class Telemetry {
};

this.rudderStack.track(event, updatedProperties);

if (withPostHog) {
usePostHog().capture(event, updatedProperties);
}
}

page(route: Route) {
Expand Down Expand Up @@ -119,7 +128,7 @@ export class Telemetry {
properties.session_id = useRootStore().sessionId;
switch (event) {
case 'askAi.generationFinished':
this.track('Ai code generation finished', properties);
this.track('Ai code generation finished', properties, { withPostHog: true });
case 'ask.generationClicked':
this.track('User clicked on generate code button', properties);
default:
Expand Down Expand Up @@ -189,7 +198,7 @@ export class Telemetry {
this.track('User viewed node category', properties);
break;
case 'nodeView.addNodeButton':
this.track('User added node to workflow canvas', properties);
this.track('User added node to workflow canvas', properties, { withPostHog: true });
break;
case 'nodeView.addSticky':
this.track('User inserted workflow note', properties);
Expand Down
21 changes: 20 additions & 1 deletion packages/editor-ui/src/stores/posthog.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { defineStore } from 'pinia';
import { useUsersStore } from '@/stores/users.store';
import { useRootStore } from '@/stores/n8nRoot.store';
import { useSettingsStore } from '@/stores/settings.store';
import type { FeatureFlags } from 'n8n-workflow';
import type { FeatureFlags, IDataObject } from 'n8n-workflow';
import { EXPERIMENTS_TO_TRACK, LOCAL_STORAGE_EXPERIMENT_OVERRIDES } from '@/constants';
import { useTelemetryStore } from './telemetry.store';
import { debounce } from 'lodash-es';
Expand Down Expand Up @@ -161,10 +161,29 @@ export const usePostHog = defineStore('posthog', () => {
trackedDemoExp.value[name] = variant;
};

const capture = (event: string, properties: IDataObject) => {
RicardoE105 marked this conversation as resolved.
Show resolved Hide resolved
if (typeof window.posthog?.capture === 'function') {
window.posthog.capture(event, properties);
}
};

const setMetadata = (metadata: IDataObject, target: 'user' | 'events') => {
if (typeof window.posthog?.people?.set !== 'function') return;
if (typeof window.posthog?.register !== 'function') return;

if (target === 'user') {
window.posthog?.people?.set(metadata);
} else if (target === 'events') {
window.posthog?.register(metadata);
}
};

return {
RicardoE105 marked this conversation as resolved.
Show resolved Hide resolved
init,
isVariantEnabled,
getVariant,
reset,
capture,
setMetadata,
};
});
4 changes: 2 additions & 2 deletions packages/editor-ui/src/stores/users.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ export const useUsersStore = defineStore(STORES.USERS, {
this.addUsers([user]);
this.currentUserId = user.id;
settingsStore.stopShowingSetupPage();
usePostHog().init(user.featureFlags);
}
},
async validateSignupToken(params: {
Expand All @@ -221,9 +222,8 @@ export const useUsersStore = defineStore(STORES.USERS, {
if (user) {
this.addUsers([user]);
this.currentUserId = user.id;
usePostHog().init(user.featureFlags);
}

usePostHog().init(user.featureFlags);
},
async sendForgotPasswordEmail(params: { email: string }): Promise<void> {
const rootStore = useRootStore();
Expand Down
8 changes: 5 additions & 3 deletions packages/editor-ui/src/views/TemplatesCollectionView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import type {
import { setPageTitle } from '@/utils';
import { VIEWS } from '@/constants';
import { useTemplatesStore } from '@/stores/templates.store';
import { usePostHog } from '@/stores/posthog.store';

export default defineComponent({
name: 'TemplatesCollectionView',
Expand All @@ -78,7 +79,7 @@ export default defineComponent({
TemplatesView,
},
computed: {
...mapStores(useTemplatesStore),
...mapStores(useTemplatesStore, usePostHog),
collection(): null | ITemplatesCollectionFull {
return this.templatesStore.getCollectionById(this.collectionId);
},
Expand Down Expand Up @@ -122,8 +123,9 @@ export default defineComponent({
source: 'collection',
};
void this.$externalHooks().run('templatesCollectionView.onUseWorkflow', telemetryPayload);
this.$telemetry.track('User inserted workflow template', telemetryPayload);

this.$telemetry.track('User inserted workflow template', telemetryPayload, {
withPostHog: true,
});
this.navigateTo(event, VIEWS.TEMPLATE_IMPORT, id);
},
navigateTo(e: MouseEvent, page: string, id: string) {
Expand Down
8 changes: 5 additions & 3 deletions packages/editor-ui/src/views/TemplatesWorkflowView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import { workflowHelpers } from '@/mixins/workflowHelpers';
import { setPageTitle } from '@/utils';
import { VIEWS } from '@/constants';
import { useTemplatesStore } from '@/stores/templates.store';
import { usePostHog } from '@/stores/posthog.store';
export default defineComponent({
name: 'TemplatesWorkflowView',
Expand All @@ -77,7 +78,7 @@ export default defineComponent({
WorkflowPreview,
},
computed: {
...mapStores(useTemplatesStore),
...mapStores(useTemplatesStore, usePostHog),
template(): ITemplatesWorkflow | ITemplatesWorkflowFull {
return this.templatesStore.getTemplateById(this.templateId);
},
Expand All @@ -101,8 +102,9 @@ export default defineComponent({
};
void this.$externalHooks().run('templatesWorkflowView.openWorkflow', telemetryPayload);
this.$telemetry.track('User inserted workflow template', telemetryPayload);
this.$telemetry.track('User inserted workflow template', telemetryPayload, {
withPostHog: true,
});
if (e.metaKey || e.ctrlKey) {
const route = this.$router.resolve({ name: VIEWS.TEMPLATE_IMPORT, params: { id } });
window.open(route.href, '_blank');
Expand Down
Loading