From d7fa06b945eb4070a694c08b826c0cca92b0d68a Mon Sep 17 00:00:00 2001 From: Kevin Schaaf Date: Fri, 27 Feb 2026 17:53:41 -0800 Subject: [PATCH 1/2] Add call to backend TrackAction RPC --- .../src/ui/utils/oauth-based-opal-shell.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/packages/visual-editor/src/ui/utils/oauth-based-opal-shell.ts b/packages/visual-editor/src/ui/utils/oauth-based-opal-shell.ts index 06c72778369..a665d4ac9cc 100644 --- a/packages/visual-editor/src/ui/utils/oauth-based-opal-shell.ts +++ b/packages/visual-editor/src/ui/utils/oauth-based-opal-shell.ts @@ -927,8 +927,27 @@ export class OAuthBasedOpalShell implements OpalShellHostProtocol { ); trackAction = async (action: string, payload: Record) => { this.actionEventSender.sendEvent(action, payload); + + // Also send to the appcatalyst backend for server-side analytics. + this.#trackActionViaAppCatalyst(action, payload); }; + #trackActionViaAppCatalyst(event: string, payload: Record) { + this.fetchWithCreds( + new URL( + "/v1beta1/trackAction", + CLIENT_DEPLOYMENT_CONFIG.BACKEND_API_ENDPOINT + ), + { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ event, payload }), + } + ).catch((error) => { + console.warn("[shell host] trackAction RPC failed", error); + }); + } + trackProperties = async (payload: Record) => { this.actionEventSender.setProperties(payload); }; From 32e8d7dc404d2fa7bcb0f0af52d059c20f7847af Mon Sep 17 00:00:00 2001 From: Kevin Schaaf Date: Fri, 27 Feb 2026 18:03:05 -0800 Subject: [PATCH 2/2] Add client deployment flag --- packages/types/src/deployment-configuration.ts | 1 + packages/unified-server/src/config.ts | 1 + packages/unified-server/src/flags.ts | 4 ++++ packages/visual-editor/src/ui/utils/oauth-based-opal-shell.ts | 3 +++ 4 files changed, 9 insertions(+) diff --git a/packages/types/src/deployment-configuration.ts b/packages/types/src/deployment-configuration.ts index 0ce1eac5d1c..2dddd587660 100644 --- a/packages/types/src/deployment-configuration.ts +++ b/packages/types/src/deployment-configuration.ts @@ -37,6 +37,7 @@ export type ClientDeploymentConfiguration = { */ ALLOW_3P_MODULES?: boolean; ENABLE_EMAIL_OPT_IN?: boolean; + ENABLE_BACKEND_TRACK_ACTION?: boolean; FAKE_MODE?: boolean; DEV_BACKEND_MODE?: boolean; SHARE_SURFACE_URL_TEMPLATES: Record; diff --git a/packages/unified-server/src/config.ts b/packages/unified-server/src/config.ts index a2ba0cd2875..91f38923a8a 100644 --- a/packages/unified-server/src/config.ts +++ b/packages/unified-server/src/config.ts @@ -59,6 +59,7 @@ export async function createClientConfig(opts: { SHELL_HOST_ORIGINS: flags.SHELL_HOST_ORIGINS, SHELL_PREFIX: flags.SHELL_PREFIX, ENABLE_EMAIL_OPT_IN: flags.ENABLE_EMAIL_OPT_IN, + ENABLE_BACKEND_TRACK_ACTION: flags.ENABLE_BACKEND_TRACK_ACTION, SHARE_SURFACE_URL_TEMPLATES: flags.SHARE_SURFACE_URL_TEMPLATES, ENABLE_NEW_URL_SCHEME: flags.ENABLE_NEW_URL_SCHEME, ENABLE_SHARING_2: flags.ENABLE_SHARING_2, diff --git a/packages/unified-server/src/flags.ts b/packages/unified-server/src/flags.ts index d7159e40652..f8fc2558130 100644 --- a/packages/unified-server/src/flags.ts +++ b/packages/unified-server/src/flags.ts @@ -127,6 +127,10 @@ export const SHELL_PREFIX = getString("SHELL_PREFIX"); export const ENABLE_EMAIL_OPT_IN = getBoolean("ENABLE_EMAIL_OPT_IN"); +export const ENABLE_BACKEND_TRACK_ACTION = getBoolean( + "ENABLE_BACKEND_TRACK_ACTION" +); + export const ENABLE_OPAL_ADK = getBoolean("ENABLE_OPAL_ADK"); export const ENABLE_OUTPUT_TEMPLATES = getBoolean("ENABLE_OUTPUT_TEMPLATES"); diff --git a/packages/visual-editor/src/ui/utils/oauth-based-opal-shell.ts b/packages/visual-editor/src/ui/utils/oauth-based-opal-shell.ts index a665d4ac9cc..928fb082e4d 100644 --- a/packages/visual-editor/src/ui/utils/oauth-based-opal-shell.ts +++ b/packages/visual-editor/src/ui/utils/oauth-based-opal-shell.ts @@ -933,6 +933,9 @@ export class OAuthBasedOpalShell implements OpalShellHostProtocol { }; #trackActionViaAppCatalyst(event: string, payload: Record) { + if (!CLIENT_DEPLOYMENT_CONFIG.ENABLE_BACKEND_TRACK_ACTION) { + return; + } this.fetchWithCreds( new URL( "/v1beta1/trackAction",