import { randomUUID } from 'node:crypto'; import { app } from 'electron'; import axios from 'axios'; import logManager from '@electron/service/logger'; import configManager from '@electron/service/config-service'; const POSTHOG_API_KEY = 'phc_aGNegeJQP5FzNiF2rEoKqQbkuCpiiETMttplibXpB0n'; const POSTHOG_HOST = 'https://us.i.posthog.com'; const TELEMETRY_REQUEST_TIMEOUT_MS = 2_500; const TELEMETRY_SHUTDOWN_TIMEOUT_MS = 1_500; let telemetryEnabled = false; let distinctId = ''; const pendingCaptures = new Set>(); function getCommonProperties(): Record { return { $app_version: app.getVersion(), $os: process.platform, os_tag: process.platform, arch: process.arch, }; } function queueCapture(event: string, properties: Record): void { let capturePromise: Promise; const request = axios.post( `${POSTHOG_HOST}/capture/`, { api_key: POSTHOG_API_KEY, event, properties: { distinct_id: distinctId, ...properties, }, }, { headers: { 'Content-Type': 'application/json', }, timeout: TELEMETRY_REQUEST_TIMEOUT_MS, validateStatus: () => true, }, ).then((response) => { if (response.status >= 400) { logManager.debug(`Telemetry backend rejected event "${event}" with status ${response.status}`); } }).catch((error) => { logManager.debug(`Failed to capture telemetry event "${event}":`, error); }).finally(() => { pendingCaptures.delete(capturePromise); }); capturePromise = request.then(() => {}); pendingCaptures.add(capturePromise); } export async function initTelemetry(): Promise { telemetryEnabled = Boolean(configManager.get('telemetryEnabled' as never)); if (!telemetryEnabled) { logManager.info('Telemetry is disabled; observability stays local-only'); return; } const storedDistinctId = configManager.get('machineId' as never); distinctId = storedDistinctId && storedDistinctId.trim() ? storedDistinctId : randomUUID(); if (!storedDistinctId) { configManager.set('machineId' as never, distinctId); } const hasReportedInstall = Boolean(configManager.get('hasReportedInstall' as never)); if (!hasReportedInstall) { captureTelemetryEvent('app_installed'); configManager.set('hasReportedInstall' as never, true); } captureTelemetryEvent('app_opened'); } export function trackMetric(event: string, properties: Record = {}): void { logManager.info(`[metric] ${event}`, properties); } export function captureTelemetryEvent( event: string, properties: Record = {}, ): void { if (!telemetryEnabled || !distinctId) { return; } const mergedProperties = { ...getCommonProperties(), ...properties, }; queueCapture(event, mergedProperties); } export async function shutdownTelemetry(): Promise { telemetryEnabled = false; if (pendingCaptures.size === 0) { distinctId = ''; return; } const captures = Array.from(pendingCaptures); await Promise.race([ Promise.allSettled(captures).then(() => undefined), new Promise((resolve) => { setTimeout(resolve, TELEMETRY_SHUTDOWN_TIMEOUT_MS); }), ]); distinctId = ''; }