feat: add posthog events (#231)

* feat: add posthog events

* fix: workflow_duplicated event

* chore: add events to enum
This commit is contained in:
Sabiha Khan 2026-04-10 17:52:21 +05:30 committed by GitHub
parent bb5f56bfb7
commit 3f19a16e7f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 450 additions and 93 deletions

View file

@ -1,4 +1,5 @@
import { Loader2, Mic, Pause, Play, Square, Trash2Icon, Upload, X } from "lucide-react";
import posthog from "posthog-js";
import { useCallback, useEffect, useRef, useState } from "react";
import {
@ -28,6 +29,7 @@ import {
} from "@/components/ui/select";
import { Textarea } from "@/components/ui/textarea";
import { LANGUAGE_DISPLAY_NAMES } from "@/constants/languages";
import { PostHogEvent } from "@/constants/posthog-events";
import { useUserConfig } from "@/context/UserConfigContext";
import { useAudioPlayback } from "@/hooks/useAudioPlayback";
@ -357,6 +359,10 @@ export const RecordingsDialog = ({
const handlePlay = async (rec: RecordingResponseSchema) => {
try {
await togglePlayback(rec.recording_id, rec.storage_key, rec.storage_backend);
posthog.capture(PostHogEvent.RECORDING_PLAYED, {
recording_id: rec.recording_id,
source: 'recordings_dialog',
});
} catch {
setError("Failed to play recording");
}

View file

@ -3,6 +3,7 @@
import { ReactFlowInstance } from "@xyflow/react";
import { AlertCircle, ArrowLeft, ChevronDown, Copy, Download, Eye, History, LoaderCircle, MoreVertical, Phone, Rocket } from "lucide-react";
import { useRouter } from "next/navigation";
import posthog from "posthog-js";
import { useState } from "react";
import { toast } from "sonner";
@ -24,6 +25,7 @@ import {
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { PostHogEvent } from "@/constants/posthog-events";
import { WORKFLOW_RUN_MODES } from "@/constants/workflowRunModes";
interface WorkflowEditorHeaderProps {
@ -259,7 +261,13 @@ export const WorkflowEditorHeader = ({
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="bg-[#1a1a1a] border-[#3a3a3a]">
<DropdownMenuItem
onClick={() => onRun(WORKFLOW_RUN_MODES.SMALL_WEBRTC)}
onClick={() => {
posthog.capture(PostHogEvent.WEB_CALL_INITIATED, {
workflow_id: workflowId,
workflow_name: workflowName,
});
onRun(WORKFLOW_RUN_MODES.SMALL_WEBRTC);
}}
className="text-white hover:bg-[#2a2a2a] cursor-pointer"
>
<Phone className="w-4 h-4 mr-2" />

View file

@ -8,6 +8,7 @@ import {
} from "@xyflow/react";
import { EdgeChange, NodeChange } from "@xyflow/system";
import { useRouter } from "next/navigation";
import posthog from "posthog-js";
import { useCallback, useEffect, useRef } from "react";
import { useWorkflowStore } from "@/app/workflow/[workflowId]/stores/workflowStore";
@ -18,6 +19,7 @@ import {
} from "@/client";
import { WorkflowError } from "@/client/types.gen";
import { FlowEdge, FlowNode, NodeType } from "@/components/flow/types";
import { PostHogEvent } from "@/constants/posthog-events";
import logger from '@/lib/logger';
import { getNextNodeId, getRandomId } from "@/lib/utils";
import { DEFAULT_WORKFLOW_CONFIGURATIONS, WorkflowConfigurations } from "@/types/workflow-configurations";
@ -290,8 +292,12 @@ export const useWorkflowState = ({
// Use addNodes from ReactFlow instance
rfInstance.current.addNodes([newNode]);
posthog.capture(PostHogEvent.WORKFLOW_NODE_ADDED, {
node_type: nodeType,
workflow_id: workflowId,
});
setIsAddNodePanelOpen(false);
}, [nodes, setIsAddNodePanelOpen]);
}, [nodes, setIsAddNodePanelOpen, workflowId]);
const handleNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setWorkflowName(e.target.value);

View file

@ -1,6 +1,7 @@
'use client';
import { useParams } from 'next/navigation';
import posthog from 'posthog-js';
import { useEffect, useMemo, useState } from 'react';
import RenderWorkflow from '@/app/workflow/[workflowId]/RenderWorkflow';
@ -8,6 +9,7 @@ import { getWorkflowApiV1WorkflowFetchWorkflowIdGet } from '@/client/sdk.gen';
import type { WorkflowResponse } from '@/client/types.gen';
import { FlowEdge, FlowNode } from '@/components/flow/types';
import SpinLoader from '@/components/SpinLoader';
import { PostHogEvent } from '@/constants/posthog-events';
import { useAuth } from '@/lib/auth';
import logger from '@/lib/logger';
import { DEFAULT_WORKFLOW_CONFIGURATIONS, WorkflowConfigurations } from '@/types/workflow-configurations';
@ -39,6 +41,10 @@ export default function WorkflowDetailPage() {
});
const workflow = response.data;
setWorkflow(workflow);
posthog.capture(PostHogEvent.WORKFLOW_EDITOR_OPENED, {
workflow_id: workflow?.id,
workflow_name: workflow?.name,
});
} catch (err) {
setError('Failed to fetch workflow');
logger.error(`Error fetching workflow: ${err}`);

View file

@ -3,6 +3,7 @@
import { Check, Copy, ExternalLink, FileText, LoaderCircle, Phone, Video } from 'lucide-react';
import Link from 'next/link';
import { useParams, useRouter } from 'next/navigation';
import posthog from 'posthog-js';
import { useEffect, useRef, useState } from 'react';
import BrowserCall from '@/app/workflow/[workflowId]/run/[runId]/BrowserCall';
@ -17,6 +18,7 @@ import { OnboardingTooltip } from '@/components/onboarding/OnboardingTooltip';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
import { Skeleton } from '@/components/ui/skeleton';
import { PostHogEvent } from '@/constants/posthog-events';
import { WORKFLOW_RUN_MODES } from '@/constants/workflowRunModes';
import { useOnboarding } from '@/context/OnboardingContext';
import { useAuth } from '@/lib/auth';
@ -114,7 +116,7 @@ export default function WorkflowRunPage() {
},
});
setIsLoading(false);
setWorkflowRun({
const runData = {
is_completed: response.data?.is_completed ?? false,
transcript_url: response.data?.transcript_url ?? null,
recording_url: response.data?.recording_url ?? null,
@ -122,6 +124,14 @@ export default function WorkflowRunPage() {
gathered_context: response.data?.gathered_context as Record<string, string> | null ?? null,
logs: response.data?.logs as WorkflowRunLogs | null ?? null,
annotations: response.data?.annotations as Record<string, unknown> | null ?? null,
};
setWorkflowRun(runData);
posthog.capture(PostHogEvent.WORKFLOW_RUN_DETAILS_VIEWED, {
workflow_id: Number(workflowId),
run_id: Number(runId),
is_completed: runData.is_completed,
has_recording: !!runData.recording_url,
has_transcript: !!runData.transcript_url,
});
};
fetchWorkflowRun();