mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-07-15 19:54:32 +00:00
*PR Created by the Glary-Bot Agent* --- ## Summary Mirrors the existing Impact affiliate wiring for the new Rewardful affiliate network. The client reads `window.Rewardful.referral` when `getCheckoutAttribution()` runs at checkout time and emits it as a new optional `rewardful_referral` field on `CheckoutAttributionMetadata`. The Go backend consumes this field separately and passes it to Stripe as `ClientReferenceID` on the Checkout Session create call — that wiring lives in a sibling PR on `Comfy-Org/cloud` (services/comfy-api) and is the path that actually credits affiliate commissions for Stripe subscriptions. Per Rewardful's docs for server-side Stripe Checkout Sessions, the GTM-loaded Rewardful JS handles cookie persistence on the client but **cannot** attribute Checkout Sessions on its own — the merchant must explicitly pass the referral UUID server-side as `client_reference_id`. ## Why this is the simplest possible client-side change - Rewardful's JS (loaded via GTM) owns its own cookie persistence, so unlike Impact (where we capture `im_ref` from URL params and persist to localStorage ourselves), we just read `window.Rewardful.referral` at checkout time. No URL fallback, no localStorage handling. - If Rewardful's script hasn't loaded or the user didn't come from an affiliate link, the field is simply omitted from the payload. - Adds a narrow `RewardfulGlobal` interface to `global.d.ts` (`referral` plus optional `affiliate`/`campaign` metadata Rewardful exposes) so `window.Rewardful` is typed everywhere it's accessed. - 4 new unit tests covering: present, absent, empty-string, and alongside Impact attribution. The existing 10 Impact/UTM tests are untouched. ## Files touched | File | Change | |---|---| | `global.d.ts` | Add `RewardfulGlobal` interface + `Rewardful?:` on `Window` | | `src/platform/telemetry/types.ts` | Add `rewardful_referral?: string` to `CheckoutAttributionMetadata` | | `src/platform/telemetry/utils/checkoutAttribution.ts` | Read `window.Rewardful?.referral` in `getCheckoutAttribution()` | | `src/platform/telemetry/utils/__tests__/checkoutAttribution.test.ts` | 4 new tests + `window.Rewardful = undefined` reset in `beforeEach` | ## Cross-PR dependency Needs the sibling [`Comfy-Org/cloud` PR](https://github.com/Comfy-Org/cloud/pulls?q=is%3Apr+rewardful) (branch `glary/rewardful-affiliate-tracking`) to actually credit referrals. **This PR is safe to ship independently** — the field is just ignored by the existing comfy-api endpoint until that PR lands. ## Verification - `pnpm typecheck` — clean - `pnpm test:unit src/platform/telemetry/utils` — 14/14 passing (10 prior + 4 new) - `pnpm test:unit` (full repo) — passing - `pnpm lint` — 3 warnings, 0 errors (warnings pre-existing on `main`) - `pnpm format:check` — clean - `pnpm knip` — clean (1 pre-existing unrelated warning) - `pnpm exec vite build` — successful (7.85s) Related: FE-704 (Finish affiliate pages PRs) for context on the broader affiliate launch. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-12311-feat-telemetry-capture-Rewardful-referral-on-checkout-attribution-3626d73d365081beb03afb2e000c83a6) by [Unito](https://www.unito.io) --------- Co-authored-by: glary-bot <glary-bot@comfy.org> Co-authored-by: Benjamin Lu <benjaminlu1107@gmail.com>
93 lines
2.5 KiB
TypeScript
93 lines
2.5 KiB
TypeScript
declare const __COMFYUI_FRONTEND_VERSION__: string
|
|
declare const __COMFYUI_FRONTEND_COMMIT__: string
|
|
declare const __SENTRY_ENABLED__: boolean
|
|
declare const __SENTRY_DSN__: string
|
|
declare const __ALGOLIA_APP_ID__: string
|
|
declare const __ALGOLIA_API_KEY__: string
|
|
declare const __USE_PROD_CONFIG__: boolean
|
|
|
|
interface ImpactQueueFunction {
|
|
(...args: unknown[]): void
|
|
a?: unknown[][]
|
|
}
|
|
|
|
interface RewardfulGlobal {
|
|
referral?: string
|
|
affiliate?: { id?: string; token?: string; name?: string }
|
|
campaign?: { id?: string; name?: string }
|
|
}
|
|
|
|
interface RewardfulQueueFunction {
|
|
(method: 'ready', callback: () => void): void
|
|
(...args: unknown[]): void
|
|
q?: unknown[][]
|
|
}
|
|
|
|
type GtagGetFieldName = 'client_id' | 'session_id' | 'session_number'
|
|
|
|
interface GtagGetFieldValueMap {
|
|
client_id: string | number | undefined
|
|
session_id: string | number | undefined
|
|
session_number: string | number | undefined
|
|
}
|
|
|
|
interface GtagFunction {
|
|
<TField extends GtagGetFieldName>(
|
|
command: 'get',
|
|
targetId: string,
|
|
fieldName: TField,
|
|
callback: (value: GtagGetFieldValueMap[TField]) => void
|
|
): void
|
|
(...args: unknown[]): void
|
|
}
|
|
|
|
interface Window {
|
|
__CONFIG__: {
|
|
gtm_container_id?: string
|
|
ga_measurement_id?: string
|
|
mixpanel_token?: string
|
|
posthog_project_token?: string
|
|
posthog_api_host?: string
|
|
posthog_config?: Record<string, unknown>
|
|
require_whitelist?: boolean
|
|
subscription_required?: boolean
|
|
max_upload_size?: number
|
|
comfy_api_base_url?: string
|
|
comfy_platform_base_url?: string
|
|
firebase_config?: {
|
|
apiKey: string
|
|
authDomain: string
|
|
databaseURL?: string
|
|
projectId: string
|
|
storageBucket: string
|
|
messagingSenderId: string
|
|
appId: string
|
|
measurementId?: string
|
|
}
|
|
server_health_alert?: {
|
|
message: string
|
|
tooltip?: string
|
|
severity?: 'info' | 'warning' | 'error'
|
|
badge?: string
|
|
}
|
|
}
|
|
dataLayer?: Array<Record<string, unknown>>
|
|
gtag?: GtagFunction
|
|
ire_o?: string
|
|
ire?: ImpactQueueFunction
|
|
rewardful?: RewardfulQueueFunction
|
|
Rewardful?: RewardfulGlobal
|
|
}
|
|
|
|
interface Navigator {
|
|
/**
|
|
* Used by the electron API. This is a WICG non-standard API, but is guaranteed to exist in Electron.
|
|
* It is `undefined` in Firefox and older browsers.
|
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/Navigator/windowControlsOverlay
|
|
*/
|
|
windowControlsOverlay?: {
|
|
/** When `true`, the window is using custom window style. */
|
|
visible: boolean
|
|
}
|
|
}
|