diff --git a/apps/server/src/v1/middleware.ts b/apps/server/src/v1/middleware.ts index 2a8b7bf6d5..129138f863 100644 --- a/apps/server/src/v1/middleware.ts +++ b/apps/server/src/v1/middleware.ts @@ -55,7 +55,9 @@ export function trackMiddleware(event: EventProps, eventProps?: string[]) { await next(); // REMINDER: only track the event if the request was successful - if (!c.error) { + const isValid = c.res.status.toString().startsWith("2") && !c.error; + + if (isValid) { // We have checked the request to be valid already let json: unknown; if (c.req.raw.bodyUsed) { diff --git a/apps/web/src/components/forms/monitor/form.tsx b/apps/web/src/components/forms/monitor/form.tsx index 8e36ef06a2..4c212344fb 100644 --- a/apps/web/src/components/forms/monitor/form.tsx +++ b/apps/web/src/components/forms/monitor/form.tsx @@ -111,7 +111,6 @@ export function MonitorForm({ const handleDataUpdateOrInsertion = async (props: InsertMonitor) => { if (defaultValues) { - console.log(props); await api.monitor.update.mutate(props); } else { await api.monitor.create.mutate(props); diff --git a/apps/web/src/content/posts/event-analytics-implementation.mdx b/apps/web/src/content/posts/event-analytics-implementation.mdx index 50e7bc9b56..9a8eee3126 100644 --- a/apps/web/src/content/posts/event-analytics-implementation.mdx +++ b/apps/web/src/content/posts/event-analytics-implementation.mdx @@ -148,8 +148,10 @@ import type { User } from "@openstatus/auth"; export function trackMiddleware(event: EventProps) { return async (c: Context<{ Variables: { user?: User } }, "/*">, next: Next) => { await next(); + + const isValid = c.res.status.toString().startsWith("2") && !c.error; - if (!c.error) { + if (isValid) { setTimeout(async () => { const analytics = await setupAnalytics({ profileId: c.get("user")?.id, diff --git a/packages/analytics/package.json b/packages/analytics/package.json index 9c011b0aee..2774bd4ccd 100644 --- a/packages/analytics/package.json +++ b/packages/analytics/package.json @@ -4,8 +4,7 @@ "description": "", "main": "src/index.ts", "dependencies": { - "@jitsu/js": "1.9.2", - "@openpanel/sdk": "^1.0.0", + "@openpanel/sdk": "1.0.0", "@t3-oss/env-core": "0.7.0", "zod": "3.23.8" }, diff --git a/packages/analytics/src/server.ts b/packages/analytics/src/server.ts index 4f3710347e..8f87b2dcc7 100644 --- a/packages/analytics/src/server.ts +++ b/packages/analytics/src/server.ts @@ -18,6 +18,9 @@ export type IdentifyProps = { email?: string; workspaceId?: string; plan?: string; + // headers from the request + location?: string; + userAgent?: string; }; export async function setupAnalytics(props: IdentifyProps) { @@ -25,6 +28,14 @@ export async function setupAnalytics(props: IdentifyProps) { return noop(); } + if (props.location) { + op.api.addHeader("x-client-ip", props.location); + } + + if (props.userAgent) { + op.api.addHeader("user-agent", props.userAgent); + } + if (props.userId) { const [firstName, lastName] = props.fullName?.split(" ") || []; await op.identify({ diff --git a/packages/api/src/trpc.ts b/packages/api/src/trpc.ts index e09637b2b8..df7912493a 100644 --- a/packages/api/src/trpc.ts +++ b/packages/api/src/trpc.ts @@ -32,6 +32,10 @@ type CreateContextOptions = { workspace?: Workspace | null; user?: User | null; req?: NextRequest; + metadata?: { + userAgent?: string; + location?: string; + }; }; type Meta = { @@ -73,6 +77,13 @@ export const createTRPCContext = async (opts: { workspace, user, req: opts.req, + metadata: { + userAgent: opts.req.headers.get("user-agent") ?? undefined, + location: + opts.req.headers.get("x-forwarded-for") ?? + process.env.VERCEL_REGION ?? + undefined, + }, }); }; @@ -202,9 +213,13 @@ const enforceUserIsAuthed = t.middleware(async (opts) => { // REMINDER: We only track the event if the request was successful // REMINDER: We are not blocking the request after(async () => { - const { meta, getRawInput } = opts; + const { ctx, meta, getRawInput } = opts; + if (meta?.track) { - let identify: IdentifyProps = {}; + let identify: IdentifyProps = { + userAgent: ctx.metadata?.userAgent, + location: ctx.metadata?.location, + }; if (user && workspace) { identify = { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 36104bd5a2..79ec42e219 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -499,11 +499,8 @@ importers: packages/analytics: dependencies: - '@jitsu/js': - specifier: 1.9.2 - version: 1.9.2(@types/dlv@1.1.5) '@openpanel/sdk': - specifier: ^1.0.0 + specifier: 1.0.0 version: 1.0.0 '@t3-oss/env-core': specifier: 0.7.0 @@ -1134,27 +1131,6 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@analytics/cookie-utils@0.2.12': - resolution: {integrity: sha512-2h/yuIu3kmu+ZJlKmlT6GoRvUEY2k1BbQBezEv5kGhnn9KpmzPz715Y3GmM2i+m7Y0QmBdVUoA260dQZkofs2A==} - - '@analytics/core@0.12.7': - resolution: {integrity: sha512-etmIPCoxWLoUZ/o1o2zvIk4cdVHa8I1xUQtTuLA+YXQ4SsFbm75ZoMXJBqWrNSENpqCJgoL6hizl5uTbkNN+1Q==} - - '@analytics/global-storage-utils@0.1.7': - resolution: {integrity: sha512-V+spzGLZYm4biZT4uefaylm80SrLXf8WOTv9hCgA46cLcyxx3LD4GCpssp1lj+RcWLl/uXJQBRO4Mnn/o1x6Gw==} - - '@analytics/localstorage-utils@0.1.10': - resolution: {integrity: sha512-uJS+Jp1yLG5VFCgA5T82ZODYBS0xuDQx0NtAZrgbqt9j51BX3TcgmOez5LVkrUNu/lpbxjCLq35I4TKj78VmOQ==} - - '@analytics/session-storage-utils@0.0.7': - resolution: {integrity: sha512-PSv40UxG96HVcjY15e3zOqU2n8IqXnH8XvTkg1X43uXNTKVSebiI2kUjA3Q7ESFbw5DPwcLbJhV7GforpuBLDw==} - - '@analytics/storage-utils@0.4.2': - resolution: {integrity: sha512-AXObwyVQw9h2uJh1t2hUgabtVxzYpW+7uKVbdHQK80vr3Td5rrmCxrCxarh7HUuAgSDZ0bZWqmYxVgmwKceaLg==} - - '@analytics/type-utils@0.6.2': - resolution: {integrity: sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg==} - '@antfu/install-pkg@0.4.1': resolution: {integrity: sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==} @@ -2762,9 +2738,6 @@ packages: resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@jitsu/js@1.9.2': - resolution: {integrity: sha512-IFwVJczP/c9Lp5BFQZP5ebHgepbr5N1A+bE5m/CG1Sjekcr/oHuVtw1hjZFHJBa3eK6Gbn0Ax8Ih0LSPZkxiUg==} - '@jridgewell/gen-mapping@0.3.5': resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} @@ -4980,9 +4953,6 @@ packages: '@types/debug@4.1.10': resolution: {integrity: sha512-tOSCru6s732pofZ+sMv9o4o3Zc+Sa8l3bxd/tweTQudFn06vAzb13ZX46Zi6m6EJ+RUbRTHvgQJ1gBtSgkaUYA==} - '@types/dlv@1.1.5': - resolution: {integrity: sha512-JHOWNfiWepAhfwlSw17kiWrWrk6od2dEQgHltJw9AS0JPFoLZJBge5+Dnil2NfdjAvJ/+vGSX60/BRW20PpUXw==} - '@types/eslint-scope@3.7.7': resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} @@ -5422,14 +5392,6 @@ packages: ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} - analytics-utils@1.0.12: - resolution: {integrity: sha512-WvV2YWgsnXLxaY0QYux0crpBAg/0JA763NmbMVz22jKhMPo7dpTBet8G2IlF7ixTjLDzGlkHk1ZaKqqQmjJ+4w==} - peerDependencies: - '@types/dlv': ^1.0.0 - - analytics@0.8.9: - resolution: {integrity: sha512-oTbUzQpncMTslakqfK70GgB6bopk5hY+uuekwnadMkDyqNLgcD02KRzteTnO7q5Ko6wDECVtT8xi/6OuAMZykA==} - ansi-align@3.0.1: resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} @@ -10344,40 +10306,6 @@ snapshots: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 - '@analytics/cookie-utils@0.2.12': - dependencies: - '@analytics/global-storage-utils': 0.1.7 - - '@analytics/core@0.12.7(@types/dlv@1.1.5)': - dependencies: - '@analytics/global-storage-utils': 0.1.7 - '@analytics/type-utils': 0.6.2 - analytics-utils: 1.0.12(@types/dlv@1.1.5) - transitivePeerDependencies: - - '@types/dlv' - - '@analytics/global-storage-utils@0.1.7': - dependencies: - '@analytics/type-utils': 0.6.2 - - '@analytics/localstorage-utils@0.1.10': - dependencies: - '@analytics/global-storage-utils': 0.1.7 - - '@analytics/session-storage-utils@0.0.7': - dependencies: - '@analytics/global-storage-utils': 0.1.7 - - '@analytics/storage-utils@0.4.2': - dependencies: - '@analytics/cookie-utils': 0.2.12 - '@analytics/global-storage-utils': 0.1.7 - '@analytics/localstorage-utils': 0.1.10 - '@analytics/session-storage-utils': 0.0.7 - '@analytics/type-utils': 0.6.2 - - '@analytics/type-utils@0.6.2': {} - '@antfu/install-pkg@0.4.1': dependencies: package-manager-detector: 0.2.4 @@ -12197,12 +12125,6 @@ snapshots: dependencies: '@sinclair/typebox': 0.27.8 - '@jitsu/js@1.9.2(@types/dlv@1.1.5)': - dependencies: - analytics: 0.8.9(@types/dlv@1.1.5) - transitivePeerDependencies: - - '@types/dlv' - '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 @@ -14863,8 +14785,6 @@ snapshots: dependencies: '@types/ms': 0.7.33 - '@types/dlv@1.1.5': {} - '@types/eslint-scope@3.7.7': dependencies: '@types/eslint': 9.6.1 @@ -15459,19 +15379,6 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - analytics-utils@1.0.12(@types/dlv@1.1.5): - dependencies: - '@analytics/type-utils': 0.6.2 - '@types/dlv': 1.1.5 - dlv: 1.1.3 - - analytics@0.8.9(@types/dlv@1.1.5): - dependencies: - '@analytics/core': 0.12.7(@types/dlv@1.1.5) - '@analytics/storage-utils': 0.4.2 - transitivePeerDependencies: - - '@types/dlv' - ansi-align@3.0.1: dependencies: string-width: 4.2.3