Skip to content

Commit 122c030

Browse files
authored
ENG-1094 allow people to opt-out of postHog (#625)
1 parent 5acbf6d commit 122c030

5 files changed

Lines changed: 126 additions & 44 deletions

File tree

apps/roam/src/components/settings/HomePersonalSettings.tsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ import {
2020
DISCOURSE_CONTEXT_OVERLAY_IN_CANVAS_KEY,
2121
DISCOURSE_TOOL_SHORTCUT_KEY,
2222
STREAMLINE_STYLING_KEY,
23+
DISALLOW_DIAGNOSTICS,
2324
} from "~/data/userSettings";
25+
import { enablePostHog, disablePostHog } from "~/utils/posthog";
26+
import internalError from "~/utils/internalError";
2427
import KeyboardShortcutInput from "./KeyboardShortcutInput";
2528
import { getSetting, setSetting } from "~/utils/extensionSettings";
2629
import streamlineStyling from "~/styles/streamlineStyling";
@@ -263,6 +266,38 @@ const HomePersonalSettings = ({ onloadArgs }: { onloadArgs: OnloadArgs }) => {
263266
</>
264267
}
265268
/>
269+
<Checkbox
270+
defaultChecked={getSetting(DISALLOW_DIAGNOSTICS, false)}
271+
onChange={(e) => {
272+
const target = e.target as HTMLInputElement;
273+
const disallow = target.checked;
274+
void setSetting(DISALLOW_DIAGNOSTICS, disallow)
275+
.then(() => {
276+
if (disallow) {
277+
disablePostHog();
278+
} else {
279+
enablePostHog();
280+
}
281+
})
282+
.catch((error) => {
283+
target.checked = !disallow;
284+
internalError({
285+
error,
286+
userMessage: "Could not change settings",
287+
});
288+
});
289+
}}
290+
labelElement={
291+
<>
292+
Disable product diagnostics
293+
<Description
294+
description={
295+
"Disable sending usage signals and error reports that help us improve the product."
296+
}
297+
/>
298+
</>
299+
}
300+
/>
266301
</div>
267302
);
268303
};

apps/roam/src/data/userSettings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ export const DISCOURSE_TOOL_SHORTCUT_KEY = "discourse-tool-shortcut";
88
export const DISCOURSE_CONTEXT_OVERLAY_IN_CANVAS_KEY =
99
"discourse-context-overlay-in-canvas";
1010
export const STREAMLINE_STYLING_KEY = "streamline-styling";
11+
export const DISALLOW_DIAGNOSTICS = "disallow-diagnostics";

apps/roam/src/index.ts

Lines changed: 7 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { addStyle } from "roamjs-components/dom";
22
import { render as renderToast } from "roamjs-components/components/Toast";
3-
import getCurrentUserUid from "roamjs-components/queries/getCurrentUserUid";
43
import { runExtension } from "roamjs-components/util";
54
import { queryBuilderLoadedToast } from "./data/toastMessages";
65
import runQuery from "./utils/runQuery";
@@ -21,7 +20,6 @@ import discourseFloatingMenuStyles from "./styles/discourseFloatingMenuStyles.cs
2120
import settingsStyles from "./styles/settingsStyles.css";
2221
import discourseGraphStyles from "./styles/discourseGraphStyles.css";
2322
import streamlineStyling from "./styles/streamlineStyling";
24-
import posthog from "posthog-js";
2523
import getDiscourseNodes from "./utils/getDiscourseNodes";
2624
import { initFeedbackWidget } from "./components/BirdEatsBugs";
2725
import {
@@ -38,53 +36,19 @@ import getBasicTreeByParentUid from "roamjs-components/queries/getBasicTreeByPar
3836
import getPageUidByPageTitle from "roamjs-components/queries/getPageUidByPageTitle";
3937
import { DISCOURSE_CONFIG_PAGE_TITLE } from "./utils/renderNodeConfigPage";
4038
import { getSetting } from "./utils/extensionSettings";
41-
import { STREAMLINE_STYLING_KEY } from "./data/userSettings";
42-
import { getVersionWithDate } from "~/utils/getVersion";
43-
44-
const initPostHog = () => {
45-
posthog.init("phc_SNMmBqwNfcEpNduQ41dBUjtGNEUEKAy6jTn63Fzsrax", {
46-
api_host: "https://us.i.posthog.com",
47-
person_profiles: "identified_only",
48-
capture_pageview: false,
49-
autocapture: false,
50-
loaded: (posthog) => {
51-
const { version, buildDate } = getVersionWithDate();
52-
const userUid = getCurrentUserUid();
53-
const graphName = window.roamAlphaAPI.graph.name;
54-
posthog.identify(userUid, {
55-
graphName,
56-
});
57-
posthog.register({
58-
version: version || "-",
59-
buildDate: buildDate || "-",
60-
graphName,
61-
});
62-
posthog.capture("Extension Loaded");
63-
},
64-
property_denylist: [
65-
"$ip", // Still seeing ip in the event
66-
"$device_id",
67-
"$geoip_city_name",
68-
"$geoip_latitude",
69-
"$geoip_longitude",
70-
"$geoip_postal_code",
71-
"$geoip_subdivision_1_name",
72-
"$raw_user_agent",
73-
"$current_url",
74-
"$referrer",
75-
"$referring_domain",
76-
"$initial_current_url",
77-
"$pathname",
78-
],
79-
});
80-
};
39+
import { initPostHog } from "./utils/posthog";
40+
import {
41+
STREAMLINE_STYLING_KEY,
42+
DISALLOW_DIAGNOSTICS,
43+
} from "./data/userSettings";
8144

8245
export const DEFAULT_CANVAS_PAGE_FORMAT = "Canvas/*";
8346

8447
export default runExtension(async (onloadArgs) => {
8548
const isEncrypted = window.roamAlphaAPI.graph.isEncrypted;
8649
const isOffline = window.roamAlphaAPI.graph.type === "offline";
87-
if (!isEncrypted && !isOffline) {
50+
const disallowDiagnostics = getSetting(DISALLOW_DIAGNOSTICS, false);
51+
if (!isEncrypted && !isOffline && !disallowDiagnostics) {
8852
initPostHog();
8953
}
9054

apps/roam/src/utils/internalError.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import posthog from "posthog-js";
22
import type { Properties } from "posthog-js";
33
import renderToast from "roamjs-components/components/Toast";
44
import sendErrorEmail from "~/utils/sendErrorEmail";
5+
import { getSetting } from "~/utils/extensionSettings";
6+
import { DISALLOW_DIAGNOSTICS } from "~/data/userSettings";
57

68
const NON_WORD = /\W+/g;
79

@@ -20,7 +22,10 @@ const internalError = ({
2022
sendEmail?: boolean;
2123
forceSendInDev?: boolean;
2224
}): void => {
23-
if (process.env.NODE_ENV === "development" && forceSendInDev !== true) {
25+
if (
26+
getSetting(DISALLOW_DIAGNOSTICS, false) ||
27+
(process.env.NODE_ENV === "development" && forceSendInDev !== true)
28+
) {
2429
console.error(error, context);
2530
} else {
2631
type = type || "Internal Error";

apps/roam/src/utils/posthog.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import getCurrentUserUid from "roamjs-components/queries/getCurrentUserUid";
2+
import { getVersionWithDate } from "./getVersion";
3+
import posthog from "posthog-js";
4+
import type { CaptureResult } from "posthog-js";
5+
import { getSetting } from "./extensionSettings";
6+
import { DISALLOW_DIAGNOSTICS } from "~/data/userSettings";
7+
8+
let initialized = false;
9+
10+
const doInitPostHog = (): void => {
11+
if (initialized) return;
12+
const propertyDenylist = new Set([
13+
"$ip",
14+
"$device_id",
15+
"$geoip_city_name",
16+
"$geoip_latitude",
17+
"$geoip_longitude",
18+
"$geoip_postal_code",
19+
"$geoip_subdivision_1_name",
20+
"$raw_user_agent",
21+
"$current_url",
22+
"$referrer",
23+
"$referring_domain",
24+
"$initial_current_url",
25+
"$pathname",
26+
]);
27+
posthog.init("phc_SNMmBqwNfcEpNduQ41dBUjtGNEUEKAy6jTn63Fzsrax", {
28+
/* eslint-disable @typescript-eslint/naming-convention */
29+
api_host: "https://us.i.posthog.com",
30+
person_profiles: "identified_only",
31+
capture_pageview: false,
32+
property_denylist: [...propertyDenylist],
33+
before_send: (result: CaptureResult | null) => {
34+
if (result !== null) {
35+
result.properties = Object.fromEntries(
36+
Object.entries(result.properties).filter(
37+
([k]) => !propertyDenylist.has(k),
38+
),
39+
);
40+
}
41+
return result;
42+
},
43+
/* eslint-enable @typescript-eslint/naming-convention */
44+
autocapture: false,
45+
loaded: (posthog) => {
46+
const { version, buildDate } = getVersionWithDate();
47+
const userUid = getCurrentUserUid();
48+
const graphName = window.roamAlphaAPI.graph.name;
49+
posthog.identify(userUid, {
50+
graphName,
51+
});
52+
posthog.register({
53+
version: version || "-",
54+
buildDate: buildDate || "-",
55+
graphName,
56+
});
57+
posthog.capture("Extension Loaded");
58+
initialized = true;
59+
},
60+
});
61+
};
62+
63+
export const enablePostHog = (): void => {
64+
doInitPostHog();
65+
posthog.opt_in_capturing();
66+
};
67+
68+
export const disablePostHog = (): void => {
69+
if (initialized) posthog.opt_out_capturing();
70+
};
71+
72+
export const initPostHog = (): void => {
73+
const disabled = getSetting(DISALLOW_DIAGNOSTICS, false);
74+
if (!disabled) {
75+
doInitPostHog();
76+
}
77+
};

0 commit comments

Comments
 (0)