feat: Support feature flag evaluation server side (#5511)
* feat(editor): roll out schema view * feat(editor): add posthog tracking * refactor: use composables * refactor: clean up console log * refactor: clean up impl * chore: clean up impl * fix: fix demo var * chore: add comment * refactor: clean up * chore: wrap error func * refactor: clean up import * refactor: make store * feat: enable rudderstack usebeacon, move event to unload * chore: clean up alert * refactor: move tracking from hooks * fix: reload flags on login * fix: add func to setup * fix: clear duplicate import * chore: add console to tesT * chore: add console to tesT * fix: try reload * chore: randomize instnace id for testing * chore: randomize instnace id for testing * chore: add console logs for testing * chore: move random id to fe * chore: use query param for testing * feat: update PostHog api endpoint * feat: update rs host * feat: update rs host * feat: update rs endpoints * refactor: use api host for BE events as well * refactor: refactor out posthog client * feat: add feature flags to login * feat: add feature flags to login * feat: get feature flags to work * feat: add created at to be events * chore: add todos * chore: clean up store * chore: add created at to identify * feat: add posthog config to settings * feat: add bootstrapping * chore: clean up * chore: fix build * fix: get dates to work * fix: get posthog to recognize dates * chore: refactor * fix: update back to number * fix: update key * fix: get experiment evals to work * feat: add posthog to signup router * feat: add feature flags on sign up * chore: clean up * fix: fix import * chore: clean up loading script * feat: add timeout, fix: script loader * fix: test timeout and get working on 8080 * refactor: move out posthog * feat: add experiment tracking * fix: clear tracked on reset * fix: fix signup bug * fix: handle errors when telmetry is disabled * refactor: remove redundant await * fix: add back posthog to telemetry * test: fix test * test: fix test * test: add tests for posthog client * lint: fix * fix: fix issue with slow decide endpoint * lint: fix * lint: fix * lint: fix * lint: fix * chore: address PR feedback * chore: address PR feedback * feat: add onboarding experiment
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
import type RudderStack from '@rudderstack/rudder-sdk-node';
|
||||
import type { PostHog } from 'posthog-node';
|
||||
import type { PostHogClient } from '../posthog';
|
||||
import type { ITelemetryTrackProperties } from 'n8n-workflow';
|
||||
import { LoggerProxy } from 'n8n-workflow';
|
||||
import config from '@/config';
|
||||
@@ -31,13 +31,11 @@ interface IExecutionsBuffer {
|
||||
export class Telemetry {
|
||||
private rudderStack?: RudderStack;
|
||||
|
||||
private postHog?: PostHog;
|
||||
|
||||
private pulseIntervalReference: NodeJS.Timeout;
|
||||
|
||||
private executionCountsBuffer: IExecutionsBuffer = {};
|
||||
|
||||
constructor(private instanceId: string) {}
|
||||
constructor(private instanceId: string, private postHog: PostHogClient) {}
|
||||
|
||||
async init() {
|
||||
const enabled = config.getEnv('diagnostics.enabled');
|
||||
@@ -58,12 +56,6 @@ export class Telemetry {
|
||||
const { default: RudderStack } = await import('@rudderstack/rudder-sdk-node');
|
||||
this.rudderStack = new RudderStack(key, url, { logLevel });
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
const { PostHog } = await import('posthog-node');
|
||||
this.postHog = new PostHog(config.getEnv('diagnostics.config.posthog.apiKey'), {
|
||||
host: config.getEnv('diagnostics.config.posthog.apiHost'),
|
||||
});
|
||||
|
||||
this.startPulse();
|
||||
}
|
||||
}
|
||||
@@ -137,10 +129,8 @@ export class Telemetry {
|
||||
async trackN8nStop(): Promise<void> {
|
||||
clearInterval(this.pulseIntervalReference);
|
||||
void this.track('User instance stopped');
|
||||
return new Promise<void>((resolve) => {
|
||||
if (this.postHog) {
|
||||
this.postHog.shutdown();
|
||||
}
|
||||
return new Promise<void>(async (resolve) => {
|
||||
await this.postHog.stop();
|
||||
|
||||
if (this.rudderStack) {
|
||||
this.rudderStack.flush(resolve);
|
||||
@@ -192,11 +182,7 @@ export class Telemetry {
|
||||
};
|
||||
|
||||
if (withPostHog) {
|
||||
this.postHog?.capture({
|
||||
distinctId: payload.userId,
|
||||
sendFeatureFlags: true,
|
||||
...payload,
|
||||
});
|
||||
this.postHog?.track(payload);
|
||||
}
|
||||
|
||||
return this.rudderStack.track(payload, resolve);
|
||||
@@ -206,19 +192,7 @@ export class Telemetry {
|
||||
});
|
||||
}
|
||||
|
||||
async isFeatureFlagEnabled(
|
||||
featureFlagName: string,
|
||||
{ user_id: userId }: ITelemetryTrackProperties = {},
|
||||
): Promise<boolean | undefined> {
|
||||
if (!this.postHog) return Promise.resolve(false);
|
||||
|
||||
const fullId = [this.instanceId, userId].join('#');
|
||||
|
||||
return this.postHog.isFeatureEnabled(featureFlagName, fullId);
|
||||
}
|
||||
|
||||
// test helpers
|
||||
|
||||
getCountsBuffer(): IExecutionsBuffer {
|
||||
return this.executionCountsBuffer;
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
/**
|
||||
* Create a script to init PostHog, for embedding before the Vue bundle in `<head>` in `index.html`.
|
||||
*/
|
||||
export const createPostHogLoadingScript = ({
|
||||
apiKey,
|
||||
apiHost,
|
||||
autocapture,
|
||||
disableSessionRecording,
|
||||
debug,
|
||||
}: {
|
||||
apiKey: string;
|
||||
apiHost: string;
|
||||
autocapture: boolean;
|
||||
disableSessionRecording: boolean;
|
||||
debug: boolean;
|
||||
}) =>
|
||||
`<script>!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.async=!0,p.src=s.api_host+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="capture identify alias people.set people.set_once set_config register register_once unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled onFeatureFlags".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);posthog.init('${apiKey}',{api_host:'${apiHost}', autocapture: ${autocapture.toString()}, disable_session_recording: ${disableSessionRecording.toString()}, debug:${debug.toString()}})</script>`;
|
||||
Reference in New Issue
Block a user