mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-07 14:09:59 +00:00
feat(telemetry): track API credit top-up succeeded via credit_added audit events\n\n- Add TelemetryEvents.API_CREDIT_TOPUP_SUCCEEDED and provider method\n- Emit on credit_added events in useCustomerEventsService with in-memory dedupe\n- No local storage, naive based on backend audit log
(cherry picked from commit 0a50e43ae467f378f5f1c155679e818ed88b0aac)
This commit is contained in:
@@ -2,6 +2,8 @@ import type { OverridedMixpanel } from 'mixpanel-browser'
|
||||
|
||||
import type {
|
||||
AuthMetadata,
|
||||
CreditTopupMetadata,
|
||||
CreditTopupSucceededMetadata,
|
||||
ExecutionContext,
|
||||
ExecutionErrorMetadata,
|
||||
ExecutionSuccessMetadata,
|
||||
@@ -282,6 +284,27 @@ export class MixpanelTelemetryProvider implements TelemetryProvider {
|
||||
this.trackEvent(eventName)
|
||||
}
|
||||
|
||||
trackAddApiCreditButtonClicked(): void {
|
||||
this.trackEvent(TelemetryEvents.ADD_API_CREDIT_BUTTON_CLICKED)
|
||||
}
|
||||
|
||||
trackMonthlySubscriptionSucceeded(): void {
|
||||
this.trackEvent(TelemetryEvents.MONTHLY_SUBSCRIPTION_SUCCEEDED)
|
||||
}
|
||||
|
||||
trackApiCreditTopupButtonPurchaseClicked(amount: number): void {
|
||||
const metadata: CreditTopupMetadata = {
|
||||
credit_amount: amount
|
||||
}
|
||||
this.trackEvent(
|
||||
TelemetryEvents.API_CREDIT_TOPUP_BUTTON_PURCHASE_CLICKED,
|
||||
metadata
|
||||
)
|
||||
}
|
||||
|
||||
trackApiCreditTopupSucceeded(metadata: CreditTopupSucceededMetadata): void {
|
||||
this.trackEvent(TelemetryEvents.API_CREDIT_TOPUP_SUCCEEDED, metadata)
|
||||
}
|
||||
trackRunButton(options?: { subscribe_to_run?: boolean }): void {
|
||||
if (this.isOnboardingMode) {
|
||||
// During onboarding, track basic run button click without workflow context
|
||||
|
||||
@@ -89,6 +89,22 @@ export interface TemplateMetadata {
|
||||
template_license?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Credit topup metadata
|
||||
*/
|
||||
export interface CreditTopupMetadata {
|
||||
credit_amount: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Credit top-up succeeded metadata
|
||||
*/
|
||||
export interface CreditTopupSucceededMetadata {
|
||||
credit_amount: number
|
||||
payment_method?: string
|
||||
transaction_id?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Workflow import metadata
|
||||
*/
|
||||
@@ -169,6 +185,10 @@ export interface TelemetryProvider {
|
||||
|
||||
// Subscription flow events
|
||||
trackSubscription(event: 'modal_opened' | 'subscribe_clicked'): void
|
||||
trackMonthlySubscriptionSucceeded(): void
|
||||
trackAddApiCreditButtonClicked(): void
|
||||
trackApiCreditTopupButtonPurchaseClicked(amount: number): void
|
||||
trackApiCreditTopupSucceeded(metadata: CreditTopupSucceededMetadata): void
|
||||
trackRunButton(options?: { subscribe_to_run?: boolean }): void
|
||||
|
||||
// Survey flow events
|
||||
@@ -221,6 +241,11 @@ export const TelemetryEvents = {
|
||||
RUN_BUTTON_CLICKED: 'app:run_button_click',
|
||||
SUBSCRIPTION_REQUIRED_MODAL_OPENED: 'app:subscription_required_modal_opened',
|
||||
SUBSCRIBE_NOW_BUTTON_CLICKED: 'app:subscribe_now_button_clicked',
|
||||
MONTHLY_SUBSCRIPTION_SUCCEEDED: 'app:monthly_subscription_succeeded',
|
||||
ADD_API_CREDIT_BUTTON_CLICKED: 'app:add_api_credit_button_clicked',
|
||||
API_CREDIT_TOPUP_BUTTON_PURCHASE_CLICKED:
|
||||
'app:api_credit_topup_button_purchase_clicked',
|
||||
API_CREDIT_TOPUP_SUCCEEDED: 'app:api_credit_topup_succeeded',
|
||||
|
||||
// Onboarding Survey
|
||||
USER_SURVEY_OPENED: 'app:user_survey_opened',
|
||||
@@ -267,6 +292,8 @@ export type TelemetryEventProperties =
|
||||
| RunButtonProperties
|
||||
| ExecutionErrorMetadata
|
||||
| ExecutionSuccessMetadata
|
||||
| CreditTopupMetadata
|
||||
| CreditTopupSucceededMetadata
|
||||
| WorkflowImportMetadata
|
||||
| TemplateLibraryMetadata
|
||||
| TemplateLibraryClosedMetadata
|
||||
|
||||
@@ -4,6 +4,7 @@ import { ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { COMFY_API_BASE_URL } from '@/config/comfyApi'
|
||||
import { useTelemetry } from '@/platform/telemetry'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import type { components, operations } from '@/types/comfyRegistryTypes'
|
||||
import { isAbortError } from '@/utils/typeGuardUtil'
|
||||
@@ -34,6 +35,8 @@ export const useCustomerEventsService = () => {
|
||||
const isLoading = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
const { d } = useI18n()
|
||||
const telemetry = useTelemetry()
|
||||
const seenCreditAddedEventIds = new Set<string>()
|
||||
|
||||
const handleRequestError = (
|
||||
err: unknown,
|
||||
@@ -179,7 +182,7 @@ export const useCustomerEventsService = () => {
|
||||
return null
|
||||
}
|
||||
|
||||
return executeRequest<CustomerEventsResponse>(
|
||||
const result = await executeRequest<CustomerEventsResponse>(
|
||||
() =>
|
||||
customerApiClient.get('/customers/events', {
|
||||
params: { page, limit },
|
||||
@@ -187,6 +190,33 @@ export const useCustomerEventsService = () => {
|
||||
}),
|
||||
{ errorContext, routeSpecificErrors }
|
||||
)
|
||||
|
||||
if (result?.events?.length) {
|
||||
for (const evt of result.events) {
|
||||
if (evt?.event_id && evt.event_type === EventType.CREDIT_ADDED) {
|
||||
if (!seenCreditAddedEventIds.has(evt.event_id)) {
|
||||
const amount = Number((evt as any)?.params?.amount)
|
||||
if (!Number.isNaN(amount) && amount > 0) {
|
||||
const creditAmountUsd = amount / 100
|
||||
const paymentMethod = (evt as any)?.params?.payment_method as
|
||||
| string
|
||||
| undefined
|
||||
const transactionId = (evt as any)?.params?.transaction_id as
|
||||
| string
|
||||
| undefined
|
||||
telemetry?.trackApiCreditTopupSucceeded({
|
||||
credit_amount: creditAmountUsd,
|
||||
payment_method: paymentMethod,
|
||||
transaction_id: transactionId
|
||||
})
|
||||
}
|
||||
seenCreditAddedEventIds.add(evt.event_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user