Skip to content

Commit

Permalink
feat: add Openpanel integration (#1014)
Browse files Browse the repository at this point in the history
* refactor: remove posthog to op

Signed-off-by: Innei <tukon479@gmail.com>

* update

Signed-off-by: Innei <tukon479@gmail.com>

* fix: $pageview

Signed-off-by: Innei <tukon479@gmail.com>

* fix: type

Signed-off-by: Innei <tukon479@gmail.com>

---------

Signed-off-by: Innei <tukon479@gmail.com>
  • Loading branch information
Innei authored Oct 18, 2024
1 parent f690e6e commit 727ba56
Show file tree
Hide file tree
Showing 35 changed files with 901 additions and 267 deletions.
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ VITE_API_URL=http://localhost:3000
VITE_IMGPROXY_URL=http://localhost:2873
VITE_SENTRY_DSN=
VITE_BUILD_TYPE=production
VITE_POSTHOG_KEY=
VITE_INBOXES_EMAIL=@follow.re
VITE_OPENPANEL_CLIENT_ID=
VITE_OPENPANEL_API_URL=
3 changes: 2 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ env:
VITE_API_URL: ${{ vars.VITE_API_URL }}
VITE_IMGPROXY_URL: ${{ vars.VITE_IMGPROXY_URL }}
VITE_SENTRY_DSN: ${{ vars.VITE_SENTRY_DSN }}
VITE_POSTHOG_KEY: ${{ vars.VITE_POSTHOG_KEY }}
VITE_OPENPANEL_CLIENT_ID: ${{ vars.VITE_OPENPANEL_CLIENT_ID }}
VITE_OPENPANEL_API_URL: ${{ vars.VITE_OPENPANEL_API_URL }}
VITE_FIREBASE_CONFIG: ${{ vars.VITE_FIREBASE_CONFIG }}
NODE_OPTIONS: --max-old-space-size=8192

Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ env:
VITE_API_URL: ${{ vars.VITE_API_URL }}
VITE_IMGPROXY_URL: ${{ vars.VITE_IMGPROXY_URL }}
VITE_SENTRY_DSN: ${{ vars.VITE_SENTRY_DSN }}
VITE_POSTHOG_KEY: ${{ vars.VITE_POSTHOG_KEY }}
VITE_OPENPANEL_CLIENT_ID: ${{ vars.VITE_OPENPANEL_CLIENT_ID }}
VITE_OPENPANEL_API_URL: ${{ vars.VITE_OPENPANEL_API_URL }}
VITE_FIREBASE_CONFIG: ${{ vars.VITE_FIREBASE_CONFIG }}
NODE_OPTIONS: --max-old-space-size=8192

Expand Down
2 changes: 0 additions & 2 deletions apps/main/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@
"msedge-tts": "1.3.4",
"nanoid": "5.0.7",
"ofetch": "1.4.0",
"posthog-js": "1.165.0",
"posthog-node": "4.2.0",
"semver": "7.6.3",
"vscode-languagedetection": "npm:@vscode/vscode-languagedetection@^1.0.22"
},
Expand Down
17 changes: 0 additions & 17 deletions apps/main/src/lib/posthog.ts

This file was deleted.

9 changes: 0 additions & 9 deletions apps/main/src/tipc/tracker.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { User } from "@auth/core/types"

import { posthog } from "../lib/posthog"
import { setUser } from "../lib/user"
import { t } from "./_instance"

Expand All @@ -13,13 +12,5 @@ export const trackerRoute = {
const { user } = input

setUser(user)
posthog?.capture({
event: "login",
distinctId: user.id ?? "",
properties: {
name: user.name,
handle: user.handle ?? "",
},
})
}),
}
7 changes: 1 addition & 6 deletions apps/main/src/updater/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { getRendererHandlers } from "@egoist/tipc/main"
import { autoUpdater } from "electron-updater"

import { channel, isDev } from "../env"
import { trackEvent } from "../lib/posthog"
import { logger } from "../logger"
import type { RendererHandlers } from "../renderer-handlers"
import { destroyMainWindow, getMainWindow } from "../window"
Expand Down Expand Up @@ -112,18 +111,14 @@ export const registerUpdater = async () => {
autoUpdater.on("download-progress", (e) => {
logger.info(`Download progress: ${e.percent}`)
})
autoUpdater.on("update-downloaded", (e) => {
autoUpdater.on("update-downloaded", () => {
downloading = false
logger.info("Update downloaded, ready to install")

const mainWindow = getMainWindow()
if (!mainWindow) return
const handlers = getRendererHandlers<RendererHandlers>(mainWindow.webContents)

trackEvent("update_ready_to_install", {
version: e.version,
releaseVersion: e.releaseName,
})
handlers.updateDownloaded.send()
})
autoUpdater.on("error", (e) => {
Expand Down
4 changes: 3 additions & 1 deletion apps/renderer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@lottiefiles/dotlottie-react": "0.9.0",
"@microflash/remark-callout-directives": "4.3.1",
"@mozilla/readability": "^0.5.0",
"@openpanel/web": "1.0.1",
"@radix-ui/react-avatar": "1.1.0",
"@radix-ui/react-checkbox": "1.1.1",
"@radix-ui/react-context-menu": "2.2.1",
Expand Down Expand Up @@ -55,6 +56,7 @@
"dexie": "4.0.8",
"dnum": "^2.14.0",
"electron-log": "5.2.0",
"firebase": "10.14.1",
"foxact": "0.2.38",
"framer-motion": "11.9.0",
"franc-min": "6.2.0",
Expand All @@ -72,7 +74,7 @@
"nanoid": "5.0.7",
"ofetch": "1.4.0",
"path-to-regexp": "8.2.0",
"posthog-js": "1.165.0",
"posthog-js": "1.169.1",
"re-resizable": "6.10.0",
"react-blurhash": "^0.3.0",
"react-error-boundary": "4.0.13",
Expand Down
2 changes: 1 addition & 1 deletion apps/renderer/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const AppLayer = () => {

useEffect(() => {
const doneTime = Math.trunc(performance.now())
window.posthog?.capture("ui_render_init", {
window.analytics?.capture("ui_render_init", {
time: doneTime,
})
appLog("App is ready", `${doneTime}ms`)
Expand Down
2 changes: 1 addition & 1 deletion apps/renderer/src/components/common/ImpressionTracker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const ImpressionViewImpl: Component<ImpressionProps> = memo((props) => {
}
setImpression(true)

window.posthog?.capture(props.event, {
window.analytics?.capture(props.event, {
impression: 1,
...props.properties,
})
Expand Down
56 changes: 29 additions & 27 deletions apps/renderer/src/hooks/biz/useAb.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,39 @@
import { useAtomValue } from "jotai"
import PostHog from "posthog-js"
import { useFeatureFlagEnabled } from "posthog-js/react"
// import { useAtomValue } from "jotai"
// import PostHog from "posthog-js"
// import { useFeatureFlagEnabled } from "posthog-js/react"

import { jotaiStore } from "~/lib/jotai"
import type { FeatureKeys } from "~/modules/ab/atoms"
import { debugFeaturesAtom, enableDebugOverrideAtom, IS_DEBUG_ENV } from "~/modules/ab/atoms"
import { abPayloadFallback } from "~/modules/ab/fallback"
// import { jotaiStore } from "~/lib/jotai"
// import type { FeatureKeys } from "~/modules/ab/atoms"
// import { debugFeaturesAtom, enableDebugOverrideAtom, IS_DEBUG_ENV } from "~/modules/ab/atoms"
// import { abPayloadFallback } from "~/modules/ab/fallback"

export const useAb = (feature: FeatureKeys) => {
const isEnableDebugOverrides = useAtomValue(enableDebugOverrideAtom)
const debugFeatureOverrides = useAtomValue(debugFeaturesAtom)
// export const useAb = (feature: FeatureKeys) => {
// const isEnableDebugOverrides = useAtomValue(enableDebugOverrideAtom)
// const debugFeatureOverrides = useAtomValue(debugFeaturesAtom)

const isEnabled = useFeatureFlagEnabled(feature)
// const isEnabled = useFeatureFlagEnabled(feature)

if (IS_DEBUG_ENV && isEnableDebugOverrides) return debugFeatureOverrides[feature]
// if (IS_DEBUG_ENV && isEnableDebugOverrides) return debugFeatureOverrides[feature]

return isEnabled
}
// return isEnabled
// }

export const isAbEnabled = (feature: FeatureKeys) => {
const featureFlag = PostHog.getFeatureFlag(feature)
const enabled = typeof featureFlag === "boolean" ? featureFlag : featureFlag === "enabled"
const debugOverride = jotaiStore.get(debugFeaturesAtom)
// export const isAbEnabled = (feature: FeatureKeys) => {
// const featureFlag = PostHog.getFeatureFlag(feature)
// const enabled = typeof featureFlag === "boolean" ? featureFlag : featureFlag === "enabled"
// const debugOverride = jotaiStore.get(debugFeaturesAtom)

const isEnableOverride = jotaiStore.get(enableDebugOverrideAtom)
// const isEnableOverride = jotaiStore.get(enableDebugOverrideAtom)

if (isEnableOverride) {
return debugOverride[feature]
}
// if (isEnableOverride) {
// return debugOverride[feature]
// }

return enabled
}
// return enabled
// }

export const getAbValue = (feature: FeatureKeys) => {
return PostHog.getFeatureFlagPayload(feature) || abPayloadFallback[feature]
}
// export const getAbValue = (feature: FeatureKeys) => {
// return PostHog.getFeatureFlagPayload(feature) || abPayloadFallback[feature]
// }

export {}
4 changes: 2 additions & 2 deletions apps/renderer/src/hooks/biz/useNavigateEntry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ export const navigateEntry = (options: NavigateEntryOptions) => {

const finalView = nextSearchParams.get("view")

if (window.posthog) {
window.posthog.capture("Navigate Entry", {
if (window.analytics) {
window.analytics.capture("Navigate Entry", {
feedId: finalFeedId,
entryId,
view: finalView ? Number.parseInt(finalView, 10) : FeedViewType.Articles,
Expand Down
2 changes: 1 addition & 1 deletion apps/renderer/src/hooks/biz/useSignOut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const useSignOut = () =>

// Clear local storage
clearStorage()
window.posthog?.reset()
window.analytics?.reset()
// clear local store data
await Promise.allSettled([clearLocalPersistStoreData(), tipcClient?.cleanAuthSessionToken()])
// Sign out
Expand Down
45 changes: 45 additions & 0 deletions apps/renderer/src/initialize/analytics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { env } from "@follow/shared/env"
import type { TrackProperties } from "@openpanel/web"

import { getGeneralSettings } from "~/atoms/settings/general"

import { op } from "./op"
import { initPostHog } from "./posthog"

declare global {
interface Window {
analytics?: {
capture: (event_name: string, properties?: TrackProperties | null) => void
reset: () => void
}
}
}
export const initAnalytics = () => {
// TODO remove this
initPostHog()
if (env.VITE_OPENPANEL_CLIENT_ID === undefined) return

op.setGlobalProperties({
build: ELECTRON ? "electron" : "web",
version: APP_VERSION,
hash: GIT_COMMIT_SHA,
})

window.analytics = {
reset: () => {
// op.clear()

// TODO remove this if op ready
window.posthog?.reset()
},
capture(event_name: string, properties?: TrackProperties | null) {
if (import.meta.env.DEV) return
if (!getGeneralSettings().sendAnonymousData) {
return
}
// TODO remove this if op ready
window.posthog?.capture(event_name, properties as TrackProperties)
op.track(event_name, properties as TrackProperties)
},
}
}
19 changes: 19 additions & 0 deletions apps/renderer/src/initialize/firebase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { getAnalytics } from "firebase/analytics"
import { initializeApp } from "firebase/app"

// See: https://firebase.google.com/docs/web/learn-more#config-object
// For Firebase JavaScript SDK v7.20.0 and later, `measurementId` is an optional field
const firebaseConfig = {
apiKey: "AIzaSyDuM93019tp8VI7wsszJv8ChOs7b1EE5Hk",
authDomain: "follow-428106.firebaseapp.com",
projectId: "follow-428106",
storageBucket: "follow-428106.appspot.com",
messagingSenderId: "194977404578",
appId: "1:194977404578:web:1920bb0c9ea5e2373669fb",
measurementId: "G-SJE57D4F14",
}
// Initialize Firebase
const app = initializeApp(firebaseConfig)

// Initialize Analytics and get a reference to the service
export const analytics = getAnalytics(app)
31 changes: 18 additions & 13 deletions apps/renderer/src/initialize/helper.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import type { User } from "@auth/core/types"

export const setIntegrationIdentify = (user: User) =>
Promise.all([
import("@sentry/react").then(({ setTag }) => {
setTag("user_id", user.id)
setTag("user_name", user.name)
}),
import("posthog-js").then(({ default: posthog }) => {
posthog.identify(user.id, {
name: user.name,
handle: user.handle,
})
}),
])
import { op } from "./op"

export const setIntegrationIdentify = async (user: User) => {
op.identify({
profileId: user.id,
email: user.email,
avatar: user.image,
lastName: user.name,
properties: {
handle: user.handle,
name: user.name,
},
})
await import("@sentry/react").then(({ setTag }) => {
setTag("user_id", user.id)
setTag("user_name", user.name)
})
}
6 changes: 3 additions & 3 deletions apps/renderer/src/initialize/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ import { CleanerService } from "~/services/cleaner"
import { subscribeNetworkStatus } from "../atoms/network"
import { getGeneralSettings, subscribeShouldUseIndexedDB } from "../atoms/settings/general"
import { appLog } from "../lib/log"
import { initAnalytics } from "./analytics"
import { hydrateDatabaseToStore, hydrateSettings, setHydrated } from "./hydrate"
import { doMigration } from "./migrates"
import { initPostHog } from "./posthog"
import { initSentry } from "./sentry"

const cleanup = subscribeShouldUseIndexedDB((value) => {
Expand Down Expand Up @@ -93,7 +93,7 @@ export const initializeApp = async () => {
const { dataPersist: enabledDataPersist } = getGeneralSettings()

initSentry()
initPostHog()
initAnalytics()
await apm("i18n", initI18n)

let dataHydratedTime: undefined | number
Expand All @@ -106,7 +106,7 @@ export const initializeApp = async () => {
const loadingTime = Date.now() - now
appLog(`Initialize ${APP_NAME} done,`, `${loadingTime}ms`)

window.posthog?.capture("app_init", {
window.analytics?.capture("app_init", {
electron: IN_ELECTRON,
loading_time: loadingTime,
using_indexed_db: enabledDataPersist,
Expand Down
10 changes: 10 additions & 0 deletions apps/renderer/src/initialize/op.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { env } from "@follow/shared/env"
import { OpenPanel } from "@openpanel/web"

export const op = new OpenPanel({
clientId: env.VITE_OPENPANEL_CLIENT_ID,
trackScreenViews: true,
trackOutgoingLinks: true,
trackAttributes: true,
apiUrl: env.VITE_OPENPANEL_API_URL,
})
11 changes: 1 addition & 10 deletions apps/renderer/src/initialize/sentry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ import { SentryConfig } from "../configs"
export const initSentry = async () => {
if (!window.SENTRY_RELEASE) return
if (import.meta.env.DEV) return
const [Sentry, posthog] = await Promise.all([
import("@sentry/react"),
import("posthog-js").then((module) => module.default),
])
const Sentry = await import("@sentry/react")
Sentry.init({
dsn: env.VITE_SENTRY_DSN,
environment: RELEASE_CHANNEL,
Expand All @@ -35,12 +32,6 @@ export const initSentry = async () => {
Sentry.captureConsoleIntegration({
levels: ["error"],
}),
posthog.sentryIntegration({
organization: "follow-rg",

projectId: 4507570439979008,
severityAllowList: ["error", "info"], // optional: here is set to handle captureMessage (info) and captureException (error)
}),
],
...SentryConfig,
})
Expand Down
Loading

0 comments on commit 727ba56

Please sign in to comment.