From 271575f3a39a394d8fe3a71260198ebabcdce9a0 Mon Sep 17 00:00:00 2001 From: Ben Reinhart Date: Tue, 20 Aug 2024 11:31:22 -0700 Subject: [PATCH] Support disabling analytics through env var --- README.md | 5 ++- packages/api/dev-server.mts | 3 -- packages/api/posthog-client.mts | 65 +++++++++++++-------------------- packages/api/server/http.mts | 5 +++ srcbook/src/server.mjs | 1 - 5 files changed, 34 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 97d5854b..ed324cbe 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,10 @@ rm -rf ~/.srcbook In order to improve Srcbook, we collect some behavioral analytics. We don't collect anything personal or identifiable, our goals are simply to improve the application. The code is open source so you don't have to trust us, you can verify! You can find more information in our [privacy policy](./PRIVACY-POLICY.md). -If you want to disable tracking, you can do so in the settings page of the application. +If you want to disable tracking, you have two options: + +1. Run Srcbook with `SRCBOOK_DISABLE_ANALYTICS=true` set in the environment +2. Disable inside the application's settings page ## Development diff --git a/packages/api/dev-server.mts b/packages/api/dev-server.mts index 2d90af8d..19006c4e 100644 --- a/packages/api/dev-server.mts +++ b/packages/api/dev-server.mts @@ -4,8 +4,6 @@ import { WebSocketServer as WsWebSocketServer } from 'ws'; import app from './server/http.mjs'; import webSocketServer from './server/ws.mjs'; -import { posthog } from './posthog-client.mjs'; - export { SRCBOOK_DIR } from './constants.mjs'; const server = http.createServer(app); @@ -19,7 +17,6 @@ server.listen(port, () => { }); process.on('SIGINT', async function () { - await posthog.shutdown(); server.close(); process.exit(); }); diff --git a/packages/api/posthog-client.mts b/packages/api/posthog-client.mts index a21ea393..851eff05 100644 --- a/packages/api/posthog-client.mts +++ b/packages/api/posthog-client.mts @@ -2,63 +2,48 @@ import { PostHog } from 'posthog-node'; import { getConfig } from './config.mjs'; import { IS_PRODUCTION } from './constants.mjs'; -type QueuedEvent = { +const POSTHOG_API_KEY = 'phc_bQjmPYXmbl76j8gW289Qj9XILuu1STRnIfgCSKlxdgu'; +const POSTHOG_HOST = 'https://us.i.posthog.com'; + +type EventType = { event: string; properties?: Record; }; class PostHogClient { private installId: string; - private client: PostHog | null = null; - private isEnabled: boolean = false; - private eventQueue: QueuedEvent[] = []; + private configAnalyticsEnabled: boolean; + private client: PostHog; constructor(config: { enabledAnalytics: boolean; installId: string }) { - this.isEnabled = config.enabledAnalytics; + this.configAnalyticsEnabled = config.enabledAnalytics; this.installId = config.installId; - - if (this.isEnabled) { - this.client = new PostHog( - // We're sending over API key to GitHub and clients, but it's the only way. - 'phc_bQjmPYXmbl76j8gW289Qj9XILuu1STRnIfgCSKlxdgu', - { host: 'https://us.i.posthog.com' }, - ); - } - - this.flushQueue(); + this.client = new PostHog(POSTHOG_API_KEY, { host: POSTHOG_HOST }); } - private flushQueue(): void { - if (!this.isEnabled || !this.client) { - this.eventQueue = []; // Clear the queue if analytics are disabled - return; - } + private get envAnalyticsEnabled(): boolean { + const disabled = process.env.SRCBOOK_DISABLE_ANALYTICS || ''; + return disabled.toLowerCase() !== 'true'; + } - while (this.eventQueue.length > 0) { - const event = this.eventQueue.shift(); - if (event) { - this.client.capture({ ...event, distinctId: this.installId }); - } - } + private get isEnabled(): boolean { + return this.configAnalyticsEnabled && this.envAnalyticsEnabled && IS_PRODUCTION; } - public capture(event: QueuedEvent): void { - if (this.isEnabled && IS_PRODUCTION) { - if (this.client) { - this.client.capture({ ...event, distinctId: this.installId }); - } - } else { - this.eventQueue.push(event); - } + // If the config for analytics is changed at run time + // in settings, use this accessor to update the value + public setConfigAnalyticsEnabled(value: boolean) { + console.log('Setting analytics updated:', value); + this.configAnalyticsEnabled = value; } - public async shutdown(): Promise { - this.flushQueue(); - if (this.client) { - await this.client.shutdown(); + public capture(event: EventType): void { + if (!this.isEnabled) { + return; } + + this.client.capture({ ...event, distinctId: this.installId }); } } -const config = await getConfig(); -export const posthog = new PostHogClient(config); +export const posthog = new PostHogClient(await getConfig()); diff --git a/packages/api/server/http.mts b/packages/api/server/http.mts index 444599af..38573369 100644 --- a/packages/api/server/http.mts +++ b/packages/api/server/http.mts @@ -242,10 +242,15 @@ router.get('/settings', cors(), async (_req, res) => { router.post('/settings', cors(), async (req, res) => { try { const updated = await updateConfig(req.body); + + // Ensure analytics always reflects the user's settings + posthog.setConfigAnalyticsEnabled(Boolean(updated[0] && updated[0].enabledAnalytics)); + posthog.capture({ event: 'user updated settings', properties: { setting_changed: Object.keys(req.body) }, }); + return res.json({ result: updated }); } catch (e) { const error = e as unknown as Error; diff --git a/srcbook/src/server.mjs b/srcbook/src/server.mjs index 424d247f..1474b3b3 100644 --- a/srcbook/src/server.mjs +++ b/srcbook/src/server.mjs @@ -64,7 +64,6 @@ server.listen(port, () => { }); process.on('SIGINT', async () => { - await posthog.shutdown(); server.close(); process.exit(); });