Skip to content

Commit 777e751

Browse files
benceruleanluactions-user
authored andcommitted
feat(telemetry): add unified run_triggered event for all run initiations (#6499)
Summary - Add new telemetry event: `app:run_triggered` with `{ trigger_source: 'button' | 'keybinding' | 'menu' }`. - Instrument all run initiation paths: - UI Queue button emits `run_triggered` (source `button`) and keeps emitting `run_button_click` for UI-only tracking. - Keybindings (Ctrl+Enter / Ctrl+Shift+Enter) emit `run_triggered` (source `keybinding`). - Menus (menubar + legacy menu buttons) emit `run_triggered` (source `menu`). - Mixpanel provider now supports `trackRunTriggered` and forwards `run_triggered`. - `execution_start` tracking remains unchanged. Motivation GTM observed more `execution_start` events than `run_button_click`. This change clarifies attribution by adding a unified event across all triggers while preserving the UI-only `run_button_click` metric. Files - src/platform/telemetry/types.ts: Add `RunTriggeredMetadata`, `RUN_TRIGGERED`, provider method signature. - src/platform/telemetry/providers/cloud/MixpanelTelemetryProvider.ts: Implement `trackRunTriggered`. - src/components/actionbar/ComfyRunButton/ComfyQueueButton.vue: Emit `run_triggered` on button path. - src/services/keybindingService.ts: Emit `run_triggered` when queue commands are invoked via keybindings. - src/stores/menuItemStore.ts: Emit `run_triggered` for queue commands invoked via menubar. - src/scripts/ui.ts: Emit `run_triggered` for legacy menu queue buttons. Notes - `run_button_click` continues to represent UI button presses only. - `run_triggered` now represents all user-initiated runs with clear source attribution. QA - Cloud build: verify `app:run_triggered` appears with the correct `trigger_source` for button, keybinding, and menu triggers. - Verify `app:run_button_click` only fires for the button path. - Confirm `execution_start` still tracks as before. If preferred, we can extend `run_triggered` with additional fields (e.g., queue mode, batchCount) in a follow-up. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6499-feat-telemetry-add-unified-run_triggered-event-for-all-run-initiations-29e6d73d3650819fb481d3e0e925c50f) by [Unito](https://www.unito.io) --------- Co-authored-by: GitHub Action <[email protected]>
1 parent 4658b42 commit 777e751

File tree

5 files changed

+49
-3
lines changed

5 files changed

+49
-3
lines changed

src/platform/telemetry/providers/cloud/MixpanelTelemetryProvider.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,14 @@ export class MixpanelTelemetryProvider implements TelemetryProvider {
338338
this.trackEvent(TelemetryEvents.RUN_BUTTON_CLICKED, runButtonProperties)
339339
}
340340

341+
trackRunTriggeredViaKeybinding(): void {
342+
this.trackEvent(TelemetryEvents.RUN_TRIGGERED_KEYBINDING)
343+
}
344+
345+
trackRunTriggeredViaMenu(): void {
346+
this.trackEvent(TelemetryEvents.RUN_TRIGGERED_MENU)
347+
}
348+
341349
trackSurvey(
342350
stage: 'opened' | 'submitted',
343351
responses?: SurveyResponses

src/platform/telemetry/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ export interface TelemetryProvider {
206206
trackAddApiCreditButtonClicked(): void
207207
trackApiCreditTopupButtonPurchaseClicked(amount: number): void
208208
trackRunButton(options?: { subscribe_to_run?: boolean }): void
209+
trackRunTriggeredViaKeybinding(): void
210+
trackRunTriggeredViaMenu(): void
209211

210212
// Survey flow events
211213
trackSurvey(stage: 'opened' | 'submitted', responses?: SurveyResponses): void
@@ -256,6 +258,8 @@ export const TelemetryEvents = {
256258

257259
// Subscription Flow
258260
RUN_BUTTON_CLICKED: 'app:run_button_click',
261+
RUN_TRIGGERED_KEYBINDING: 'app:run_triggered_keybinding',
262+
RUN_TRIGGERED_MENU: 'app:run_triggered_menu',
259263
SUBSCRIPTION_REQUIRED_MODAL_OPENED: 'app:subscription_required_modal_opened',
260264
SUBSCRIBE_NOW_BUTTON_CLICKED: 'app:subscribe_now_button_clicked',
261265
MONTHLY_SUBSCRIPTION_SUCCEEDED: 'app:monthly_subscription_succeeded',

src/scripts/ui.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { useSettingStore } from '@/platform/settings/settingStore'
22
import { WORKFLOW_ACCEPT_STRING } from '@/platform/workflow/core/types/formats'
33
import { type StatusWsMessageStatus, type TaskItem } from '@/schemas/apiSchema'
44
import { useDialogService } from '@/services/dialogService'
5+
import { isCloud } from '@/platform/distribution/types'
6+
import { useTelemetry } from '@/platform/telemetry'
57
import { useLitegraphService } from '@/services/litegraphService'
68
import { useCommandStore } from '@/stores/commandStore'
79
import { useWorkspaceStore } from '@/stores/workspaceStore'
@@ -476,7 +478,12 @@ export class ComfyUI {
476478
$el('button.comfy-queue-btn', {
477479
id: 'queue-button',
478480
textContent: 'Queue Prompt',
479-
onclick: () => app.queuePrompt(0, this.batchCount)
481+
onclick: () => {
482+
if (isCloud) {
483+
useTelemetry()?.trackRunTriggeredViaMenu()
484+
}
485+
app.queuePrompt(0, this.batchCount)
486+
}
480487
}),
481488
$el('div', {}, [
482489
$el('label', { innerHTML: 'Extra options' }, [
@@ -578,7 +585,12 @@ export class ComfyUI {
578585
$el('button', {
579586
id: 'queue-front-button',
580587
textContent: 'Queue Front',
581-
onclick: () => app.queuePrompt(-1, this.batchCount)
588+
onclick: () => {
589+
if (isCloud) {
590+
useTelemetry()?.trackRunTriggeredViaMenu()
591+
}
592+
app.queuePrompt(-1, this.batchCount)
593+
}
582594
}),
583595
$el('button', {
584596
$: (b) => (this.queue.button = b as HTMLButtonElement),

src/services/keybindingService.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { CORE_KEYBINDINGS } from '@/constants/coreKeybindings'
2+
import { isCloud } from '@/platform/distribution/types'
23
import { useSettingStore } from '@/platform/settings/settingStore'
4+
import { useTelemetry } from '@/platform/telemetry'
35
import { app } from '@/scripts/app'
46
import { useCommandStore } from '@/stores/commandStore'
57
import { useDialogStore } from '@/stores/dialogStore'
@@ -64,6 +66,14 @@ export const useKeybindingService = () => {
6466

6567
// Prevent default browser behavior first, then execute the command
6668
event.preventDefault()
69+
if (
70+
isCloud &&
71+
(keybinding.commandId === 'Comfy.QueuePrompt' ||
72+
keybinding.commandId === 'Comfy.QueuePromptFront' ||
73+
keybinding.commandId === 'Comfy.QueueSelectedOutputNodes')
74+
) {
75+
useTelemetry()?.trackRunTriggeredViaKeybinding()
76+
}
6777
await commandStore.execute(keybinding.commandId)
6878
return
6979
}

src/stores/menuItemStore.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import type { MenuItem } from 'primevue/menuitem'
33
import { ref } from 'vue'
44

55
import { CORE_MENU_COMMANDS } from '@/constants/coreMenuCommands'
6+
import { isCloud } from '@/platform/distribution/types'
7+
import { useTelemetry } from '@/platform/telemetry'
68
import type { ComfyExtension } from '@/types/comfy'
79

810
import { useCommandStore } from './commandStore'
@@ -62,7 +64,17 @@ export const useMenuItemStore = defineStore('menuItem', () => {
6264
.map(
6365
(command) =>
6466
({
65-
command: () => commandStore.execute(command.id),
67+
command: () => {
68+
if (
69+
isCloud &&
70+
(command.id === 'Comfy.QueuePrompt' ||
71+
command.id === 'Comfy.QueuePromptFront' ||
72+
command.id === 'Comfy.QueueSelectedOutputNodes')
73+
) {
74+
useTelemetry()?.trackRunTriggeredViaMenu()
75+
}
76+
return commandStore.execute(command.id)
77+
},
6678
label: command.menubarLabel,
6779
icon: command.icon,
6880
tooltip: command.tooltip,

0 commit comments

Comments
 (0)