diff --git a/packages/features/auth/lib/next-auth-options.ts b/packages/features/auth/lib/next-auth-options.ts index 90cae9c711..9c69c37c14 100644 --- a/packages/features/auth/lib/next-auth-options.ts +++ b/packages/features/auth/lib/next-auth-options.ts @@ -14,7 +14,6 @@ import { updateProfilePhotoGoogle } from "@calcom/app-store/_utils/oauth/updateP import GoogleCalendarService from "@calcom/app-store/googlecalendar/lib/CalendarService"; import { LicenseKeySingleton } from "@calcom/ee/common/server/LicenseKeyService"; import createUsersAndConnectToOrg from "@calcom/features/ee/dsync/lib/users/createUsersAndConnectToOrg"; -import postHogClient from "@calcom/features/ee/event-tracking/lib/posthog/postHogClient"; import ImpersonationProvider from "@calcom/features/ee/impersonation/lib/ImpersonationProvider"; import { getOrgFullOrigin, subdomainSuffix } from "@calcom/features/ee/organizations/lib/orgDomains"; import { clientSecretVerifier, hostedCal, isSAMLLoginEnabled } from "@calcom/features/ee/sso/lib/saml"; @@ -1041,12 +1040,6 @@ export const getOptions = ({ ); } } - - postHogClient().capture(user.id.toString(), "Sign Up", { - email: user.email, - name: user.name, - username: user.username, - }); } }, }, diff --git a/packages/features/ee/event-tracking/lib/posthog/postHogClient.ts b/packages/features/ee/event-tracking/lib/posthog/postHogClient.ts deleted file mode 100644 index f85d1e23b6..0000000000 --- a/packages/features/ee/event-tracking/lib/posthog/postHogClient.ts +++ /dev/null @@ -1,40 +0,0 @@ -// eslint-disable-next-line no-restricted-imports -import { noop } from "lodash"; -import { PostHog, type PostHog as PostHogType } from "posthog-node"; - -let postHog: { - capture: PostHogType["capture"]; - identify: PostHogType["identify"]; -}; - -// eslint-disable-next-line turbo/no-undeclared-env-vars -if (process.env.NEXT_PUBLIC_POSTHOG_KEY) { - // eslint-disable-next-line turbo/no-undeclared-env-vars - postHog = new PostHog(process.env.NEXT_PUBLIC_POSTHOG_KEY, { - // eslint-disable-next-line turbo/no-undeclared-env-vars - host: process.env.NEXT_PUBLIC_POSTHOG_HOST, - flushAt: 1, - }); -} else { - postHog = { - capture: noop, - identify: noop, - }; -} - -export function postHogClient() { - function capture(distinctId: string, event: string, properties?: Record) { - postHog?.capture({ distinctId, event, properties }); - } - - function identify(distinctId: string, properties?: Record) { - postHog?.identify({ distinctId, properties }); - } - - return { - capture, - identify, - }; -} - -export default postHogClient; diff --git a/packages/features/ee/event-tracking/lib/posthog/provider.tsx b/packages/features/ee/event-tracking/lib/posthog/provider.tsx index 2cb6e29c8f..fe27dfd8f8 100644 --- a/packages/features/ee/event-tracking/lib/posthog/provider.tsx +++ b/packages/features/ee/event-tracking/lib/posthog/provider.tsx @@ -15,6 +15,7 @@ function Provider({ children }: { children: React.ReactNode }) { posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, { api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST || "https://us.i.posthog.com", autocapture: false, + person_profiles: "never", persistence: "memory", request_batching: true, capture_pageview: false, diff --git a/packages/features/ee/event-tracking/lib/posthog/userPostHog.tsx b/packages/features/ee/event-tracking/lib/posthog/userPostHog.tsx deleted file mode 100644 index ab9111d0d3..0000000000 --- a/packages/features/ee/event-tracking/lib/posthog/userPostHog.tsx +++ /dev/null @@ -1,109 +0,0 @@ -// eslint-disable-next-line no-restricted-imports -import type { PostHog } from "posthog-js"; -import { usePostHog as usePostHogLib } from "posthog-js/react"; -import { useEffect, useRef } from "react"; -import { z } from "zod"; - -import dayjs from "@calcom/dayjs"; -import { WEBSITE_URL } from "@calcom/lib/constants"; -import { useHasTeamPlan, useHasPaidPlan } from "@calcom/lib/hooks/useHasPaidPlan"; -import { trpc } from "@calcom/trpc/react"; - -export const isPostHogEnabled = z.string().min(1).safeParse(process.env.NEXT_PUBLIC_POSTHOG_KEY).success; - -// Define the return type for our hook -type PostHogMethods = { - capture: (event: string, properties?: Record) => void; - identify: (distinctId?: string, properties?: Record) => void; - reset: () => void; -}; - -// Internal hook type that includes the methods we need -type InternalPostHogHook = Pick; - -const usePostHogHook: () => InternalPostHogHook = isPostHogEnabled - ? usePostHogLib - : () => ({ - identify: () => undefined, - capture: () => undefined, - reset: () => undefined, - register: () => undefined, - get_distinct_id: () => "", - }); - -const usePostHog = (): PostHogMethods => { - const posthog = usePostHogHook(); - const { data: userData } = trpc.viewer.me.useQuery(); - const { data: statsData } = trpc.viewer.myStats.useQuery(undefined, { - trpc: { - context: { - skipBatch: true, - }, - }, - }); - const { hasPaidPlan } = useHasPaidPlan(); - const { hasTeamPlan } = useHasTeamPlan(); - const lastPropertiesString = useRef(null); - - useEffect(() => { - if (!userData || !statsData) return; - - const properties = { - name: userData.name, - email: userData.email, - created_at: String(dayjs(userData.createdDate).unix()), - user_name: userData.username, - link: `${WEBSITE_URL}/${userData.username}`, - identity_provider: userData.identityProvider, - timezone: userData.timeZone, - locale: userData.locale, - has_paid_plan: hasPaidPlan, - has_team_plan: hasTeamPlan, - completed_onboarding: userData.completedOnboarding, - has_orgs_plan: !!userData.organizationId, - organization: userData.organization?.slug, - is_premium: userData.isPremium, - sum_of_bookings: statsData?.sumOfBookings, - sum_of_calendars: statsData?.sumOfCalendars, - sum_of_teams: statsData?.sumOfTeams, - sum_of_event_types: statsData?.sumOfEventTypes, - sum_of_team_event_types: statsData?.sumOfTeamEventTypes, - }; - - // Clean properties - const cleanProperties = Object.fromEntries(Object.entries(properties).filter(([_, v]) => v != null)); - - // Create a string representation of the properties for comparison - const propertiesString = JSON.stringify(cleanProperties); - - // Only set properties if they've changed - if (propertiesString !== lastPropertiesString.current) { - lastPropertiesString.current = propertiesString; - // Use register instead of identify to avoid duplicate calls - posthog.register(cleanProperties); - // Only identify once - if (!posthog.get_distinct_id()) { - posthog.identify(String(userData.id)); - } - } - }, [userData, statsData, hasPaidPlan, hasTeamPlan, posthog]); - - return { - capture: (event: string, properties?: Record) => { - if (posthog.get_distinct_id()) { - posthog.capture(event, properties); - } - }, - identify: (distinctId?: string, properties?: Record) => { - if (distinctId) { - posthog.identify(distinctId, properties); - } - }, - reset: () => { - lastPropertiesString.current = null; - posthog.reset(); - }, - }; -}; - -export default usePostHog; diff --git a/packages/features/eventtypes/components/CreateEventTypeDialog.tsx b/packages/features/eventtypes/components/CreateEventTypeDialog.tsx index 42b40b4c18..50c9f8b618 100644 --- a/packages/features/eventtypes/components/CreateEventTypeDialog.tsx +++ b/packages/features/eventtypes/components/CreateEventTypeDialog.tsx @@ -12,7 +12,6 @@ import { MembershipRole, SchedulingType } from "@calcom/prisma/enums"; import { trpc } from "@calcom/trpc/react"; import { Button, Dialog, DialogClose, DialogContent, DialogFooter, showToast } from "@calcom/ui"; -import usePostHog from "../../ee/event-tracking/lib/posthog/userPostHog"; import CreateEventTypeForm from "./CreateEventTypeForm"; // this describes the uniform data needed to create a new event type on Profile or Team @@ -61,7 +60,6 @@ export default function CreateEventTypeDialog({ membershipRole: MembershipRole | null | undefined; }[]; }) { - const postHog = usePostHog(); const { t } = useLocale(); const router = useRouter(); const orgBranding = useOrgBranding(); @@ -130,7 +128,6 @@ export default function CreateEventTypeDialog({ form={form} isManagedEventType={isManagedEventType} handleSubmit={(values) => { - postHog.capture("Event Created Frontend"); createMutation.mutate(values); }} SubmitButton={SubmitButton} diff --git a/packages/features/shell/Shell.tsx b/packages/features/shell/Shell.tsx index 9c389c59a0..ea3985d66e 100644 --- a/packages/features/shell/Shell.tsx +++ b/packages/features/shell/Shell.tsx @@ -1,7 +1,7 @@ import { useSession } from "next-auth/react"; import { usePathname, useRouter } from "next/navigation"; import type { Dispatch, ReactElement, ReactNode, SetStateAction } from "react"; -import React, { cloneElement, useEffect } from "react"; +import React, { cloneElement } from "react"; import { Toaster } from "react-hot-toast"; import { useRedirectToLoginIfUnauthenticated } from "@calcom/features/auth/lib/hooks/useRedirectToLoginIfUnauthenticated"; @@ -16,7 +16,6 @@ import { useLocale } from "@calcom/lib/hooks/useLocale"; import { useNotifications } from "@calcom/lib/hooks/useNotifications"; import { Button, ErrorBoundary, HeadSeo, SkeletonText } from "@calcom/ui"; -import usePostHog from "../ee/event-tracking/lib/posthog/userPostHog"; import { SideBarContainer } from "./SideBar"; import { TopNavContainer } from "./TopNav"; import { BannerContainer } from "./banners/LayoutBanner"; @@ -27,19 +26,12 @@ import { useAppTheme } from "./useAppTheme"; const Layout = (props: LayoutProps) => { const { banners, bannersHeight } = useBanners(); const pathname = usePathname(); - const postHog = usePostHog(); const isFullPageWithoutSidebar = pathname?.startsWith("/apps/routing-forms/reporting/"); const pageTitle = typeof props.heading === "string" && !props.title ? props.heading : props.title; const withoutSeo = props.withoutSeo ?? props.withoutMain ?? false; useBootIntercom(); useFormbricks(); - useEffect(() => { - if (!props.isPublic) { - postHog.identify(); - } - }, [props.isPublic, postHog]); - return ( <> {!withoutSeo && ( diff --git a/packages/features/shell/user-dropdown/UserDropdown.tsx b/packages/features/shell/user-dropdown/UserDropdown.tsx index dfdb070a66..561ed65e1e 100644 --- a/packages/features/shell/user-dropdown/UserDropdown.tsx +++ b/packages/features/shell/user-dropdown/UserDropdown.tsx @@ -21,7 +21,6 @@ import { // TODO (Platform): we shouldnt be importing from web here import { useGetUserAttributes } from "@calcom/web/components/settings/platform/hooks/useGetUserAttributes"; -import usePostHog from "../../ee/event-tracking/lib/posthog/userPostHog"; import FreshChatProvider from "../../ee/support/lib/freshchat/FreshChatProvider"; interface UserDropdownProps { @@ -32,7 +31,6 @@ export function UserDropdown({ small }: UserDropdownProps) { const { t } = useLocale(); const { data: user } = useMeQuery(); const pathname = usePathname(); - const posthog = usePostHog(); const isPlatformPages = pathname?.startsWith("/settings/platform"); useEffect(() => { // eslint-disable-next-line @typescript-eslint/ban-ts-comment @@ -207,8 +205,6 @@ export function UserDropdown({ small }: UserDropdownProps) { StartIcon="log-out" aria-hidden="true" onClick={() => { - posthog.capture("sign_out"); - posthog.reset(); signOut({ callbackUrl: "/auth/logout" }); }}> {t("sign_out")}