allow telemetry events to be disabled by name in feature flags (#6946)

## Summary

Adds ability to toggle events on/off by name from dynamic feature flags.
Also makes some events disabled by default (not being used for any
analysis and taking too much of event quota currently).

Note: telemetry is only enabled on cloud - this doesn't affect local
users in any way.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6946-allow-telemetry-events-to-be-disabled-by-name-in-feature-flags-2b76d73d365081ea8676cfbb8217e640)
by [Unito](https://www.unito.io)
This commit is contained in:
Christian Byrne
2025-11-26 13:20:21 -08:00
committed by GitHub
parent df66a96976
commit 8b2c1fc45d
2 changed files with 61 additions and 0 deletions

View File

@@ -1,3 +1,5 @@
import type { TelemetryEventName } from '@/platform/telemetry/types'
/**
* Server health alert configuration from the backend
*/
@@ -31,4 +33,5 @@ export type RemoteConfig = {
comfy_api_base_url?: string
comfy_platform_base_url?: string
firebase_config?: FirebaseRuntimeConfig
telemetry_disabled_events?: TelemetryEventName[]
}

View File

@@ -1,4 +1,5 @@
import type { OverridedMixpanel } from 'mixpanel-browser'
import { watch } from 'vue'
import { useCurrentUser } from '@/composables/auth/useCurrentUser'
import {
@@ -41,9 +42,30 @@ import type {
WorkflowCreatedMetadata,
WorkflowImportMetadata
} from '../../types'
import { remoteConfig } from '@/platform/remoteConfig/remoteConfig'
import type { RemoteConfig } from '@/platform/remoteConfig/types'
import { TelemetryEvents } from '../../types'
import { normalizeSurveyResponses } from '../../utils/surveyNormalization'
const DEFAULT_DISABLED_EVENTS = [
TelemetryEvents.WORKFLOW_OPENED,
TelemetryEvents.PAGE_VISIBILITY_CHANGED,
TelemetryEvents.TAB_COUNT_TRACKING,
TelemetryEvents.NODE_SEARCH,
TelemetryEvents.NODE_SEARCH_RESULT_SELECTED,
TelemetryEvents.TEMPLATE_FILTER_CHANGED,
TelemetryEvents.SETTING_CHANGED,
TelemetryEvents.HELP_CENTER_OPENED,
TelemetryEvents.HELP_RESOURCE_CLICKED,
TelemetryEvents.HELP_CENTER_CLOSED,
TelemetryEvents.WORKFLOW_CREATED,
TelemetryEvents.UI_BUTTON_CLICKED
] as const satisfies TelemetryEventName[]
const TELEMETRY_EVENT_SET = new Set<TelemetryEventName>(
Object.values(TelemetryEvents) as TelemetryEventName[]
)
interface QueuedEvent {
eventName: TelemetryEventName
properties?: TelemetryEventProperties
@@ -67,8 +89,19 @@ export class MixpanelTelemetryProvider implements TelemetryProvider {
private eventQueue: QueuedEvent[] = []
private isInitialized = false
private lastTriggerSource: ExecutionTriggerSource | undefined
private disabledEvents = new Set<TelemetryEventName>(DEFAULT_DISABLED_EVENTS)
constructor() {
this.configureDisabledEvents(
(window.__CONFIG__ as Partial<RemoteConfig> | undefined) ?? null
)
watch(
remoteConfig,
(config) => {
this.configureDisabledEvents(config)
},
{ immediate: true }
)
const token = window.__CONFIG__?.mixpanel_token
if (token) {
@@ -131,6 +164,10 @@ export class MixpanelTelemetryProvider implements TelemetryProvider {
return
}
if (this.disabledEvents.has(eventName)) {
return
}
const event: QueuedEvent = { eventName, properties }
if (this.isInitialized && this.mixpanel) {
@@ -146,6 +183,27 @@ export class MixpanelTelemetryProvider implements TelemetryProvider {
}
}
private configureDisabledEvents(config: Partial<RemoteConfig> | null): void {
const disabledSource =
config?.telemetry_disabled_events ?? DEFAULT_DISABLED_EVENTS
this.disabledEvents = this.buildEventSet(disabledSource)
}
private buildEventSet(values: TelemetryEventName[]): Set<TelemetryEventName> {
return new Set(
values.filter((value) => {
const isValid = TELEMETRY_EVENT_SET.has(value)
if (!isValid && import.meta.env.DEV) {
console.warn(
`Unknown telemetry event name in disabled list: ${value}`
)
}
return isValid
})
)
}
trackSignupOpened(): void {
this.trackEvent(TelemetryEvents.USER_SIGN_UP_OPENED)
}