diff --git a/src/scripts/api.ts b/src/scripts/api.ts index 8e2d4f81e1..39d79589fc 100644 --- a/src/scripts/api.ts +++ b/src/scripts/api.ts @@ -1275,6 +1275,28 @@ export class ComfyApi extends EventTarget { getServerFeatures(): Record { return { ...this.serverFeatureFlags } } + + /** + * Posts analytics event to cloud analytics service + * @param eventName The name of the analytics event + * @param eventData The event data (any JSON-serializable object) + * @returns Promise resolving to the response + */ + async postCloudAnalytics( + eventName: string, + eventData: any + ): Promise { + return this.fetchApi(this.internalURL('/cloud_analytics'), { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + event_name: eventName, + event_data: eventData + }) + }) + } } export const api = new ComfyApi() diff --git a/src/scripts/app.ts b/src/scripts/app.ts index e77f7842fd..24ef7d220f 100644 --- a/src/scripts/app.ts +++ b/src/scripts/app.ts @@ -997,6 +997,10 @@ export class ComfyApp { if (!templateData?.templates) { return } + api.postCloudAnalytics('load_workflow', { + source: 'template', + sourceData: { templateData } + }) const old = localStorage.getItem('litegrapheditor_clipboard') @@ -1277,6 +1281,12 @@ export class ComfyApp { const paths = await api.getFolderPaths() this.#showMissingModelsError(missingModels, paths) } + api.postCloudAnalytics('load_workflow', { + source: 'graph', + graph: this.graph.asSerialisable(), + missingNodeTypes, + missingModels + }) await useExtensionService().invokeExtensionsAsync( 'afterConfigureGraph', missingNodeTypes @@ -1585,6 +1595,11 @@ export class ComfyApp { const missingNodeTypes = Object.values(apiData).filter( (n) => !LiteGraph.registered_node_types[n.class_type] ) + api.postCloudAnalytics('load_workflow', { + source: 'api_json', + missingNodeTypes, + apiJson: apiData + }) if (missingNodeTypes.length) { this.#showMissingNodesError(missingNodeTypes.map((t) => t.class_type)) return