Skip to content
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added PostHog events for chat UI interactions (details card expand/collapse, copy answer, table of contents toggle) and repo tracking in `wa_chat_message_sent`. [#922](https://github.com/sourcebot-dev/sourcebot/pull/922)
- Added Bitbucket Cloud OAuth identity provider support (`provider: "bitbucket-cloud"`) for SSO and account-linked permission syncing. [#924](https://github.com/sourcebot-dev/sourcebot/pull/924)
- Added permission syncing support for Bitbucket Cloud. [#925](https://github.com/sourcebot-dev/sourcebot/pull/925)
- Added `wa_user_created` PostHog event fired on successful user sign-up. [#933](https://github.com/sourcebot-dev/sourcebot/pull/933)
- Added `wa_askgh_login_wall_prompted` PostHog event fired when an unauthenticated user attempts to ask a question on Ask GitHub. [#933](https://github.com/sourcebot-dev/sourcebot/pull/933)

### Changed
- Hide version upgrade toast for askgithub deployment (`EXPERIMENT_ASK_GH_ENABLED`). [#931](https://github.com/sourcebot-dev/sourcebot/pull/931)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import type { IdentityProviderMetadata } from "@/lib/identityProviders";
import { Descendant, Transforms } from "slate";
import { useSlate } from "slate-react";
import { useCallback, useEffect, useMemo, useState, useRef } from "react";
import { captureEvent } from "@/hooks/useCaptureEvent";

const PENDING_MESSAGE_KEY = "askgh_pending_message";

Expand Down Expand Up @@ -55,6 +56,7 @@ export const LandingPage = ({
// Intercept submit to check auth status
const handleSubmit = useCallback((children: Descendant[]) => {
if (!isAuthenticated) {
captureEvent('wa_askgh_login_wall_prompted', {});
Comment thread
msukkari marked this conversation as resolved.
// Store message in sessionStorage to survive OAuth redirect
sessionStorage.setItem(PENDING_MESSAGE_KEY, JSON.stringify(children));
setIsLoginModalOpen(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Loader2 } from "lucide-react";
import { usePrevious } from "@uidotdev/usehooks";
import { useEffect } from "react";
import { useBrowserNotification } from "@/hooks/useBrowserNotification";
import { captureEvent } from "@/hooks/useCaptureEvent";
import { RepoInfo } from "../types";

const REINDEX_INTERVAL_MS = 2000;
Expand Down Expand Up @@ -45,9 +46,10 @@ export function RepoIndexedGuard({ initialRepoInfo, children }: Props) {
}
}, [initialRepoInfo.isIndexed, requestPermission]);

// Show notification when indexing completes
// Show notification and fire event when indexing completes
useEffect(() => {
if (previousIsIndexed === false && repoInfo.isIndexed === true) {
captureEvent('wa_askgh_repo_indexed', { repoName: repoInfo.name });
const displayName = repoInfo.displayName ?? repoInfo.name;
showNotification({
title: "Repository Ready",
Expand Down
6 changes: 5 additions & 1 deletion packages/web/src/lib/authUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export const onCreateUser = async ({ user }: { user: AuthJsUser }) => {
type: "org"
}
});
} else if (!defaultOrg.memberApprovalRequired) {
} else if (!defaultOrg.memberApprovalRequired) {
const hasAvailability = await orgHasAvailability(defaultOrg.domain);
if (!hasAvailability) {
logger.warn(`onCreateUser: org ${SINGLE_TENANT_ORG_ID} has reached max capacity. User ${user.id} was not added to the org.`);
Expand All @@ -123,6 +123,10 @@ export const onCreateUser = async ({ user }: { user: AuthJsUser }) => {
});
}

// Dynamic import to avoid circular dependency:
// authUtils -> posthog -> auth -> authUtils
const { captureEvent } = await import("@/lib/posthog");
await captureEvent('wa_user_created', { userId: user.id });
};


Expand Down
6 changes: 5 additions & 1 deletion packages/web/src/lib/posthog.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { PostHog } from 'posthog-node'
import { env, SOURCEBOT_VERSION } from '@sourcebot/shared'
import { createLogger, env, SOURCEBOT_VERSION } from '@sourcebot/shared'
import { RequestCookies } from 'next/dist/compiled/@edge-runtime/cookies';
import * as Sentry from "@sentry/nextjs";
import { PosthogEvent, PosthogEventMap } from './posthogEvents';
import { cookies, headers } from 'next/headers';
import { auth } from '@/auth';
import { getVerifiedApiObject } from '@/withAuthV2';

const logger = createLogger('posthog');

/**
* @note: This is a subset of the properties stored in the
* ph_phc_<id>_posthog cookie.
Expand Down Expand Up @@ -93,6 +95,8 @@ export async function captureEvent<E extends PosthogEvent>(event: E, properties:
flushInterval: 0
})

logger.debug(`Capturing event: ${event}`, { distinctId, host, ...properties });

Comment thread
msukkari marked this conversation as resolved.
Outdated
posthog.capture({
event,
properties: {
Expand Down
8 changes: 8 additions & 0 deletions packages/web/src/lib/posthogEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,14 @@ export type PosthogEventMap = {
chatId: string,
isExpanded: boolean,
},
wa_user_created: {
userId: string,
},
//////////////////////////////////////////////////////////////////
wa_askgh_login_wall_prompted: {},
wa_askgh_repo_indexed: {
repoName: string,
},
Comment thread
msukkari marked this conversation as resolved.
Outdated
//////////////////////////////////////////////////////////////////
wa_demo_docs_link_pressed: {},
wa_demo_search_example_card_pressed: {
Expand Down