Implement posthog

This commit is contained in:
2025-07-06 14:02:22 +03:00
parent f7d994d02e
commit 1e099d88ae
13 changed files with 209 additions and 41 deletions

View File

@@ -1,8 +1,11 @@
import { get } from "radash";
import { createActivityContent } from "~~/server/utils/create-content";
export default defineEventHandler(async (event) => {
await validateHookdeck(event);
const posthog = event.context.posthog;
const body = await readBody(event);
const db = useDrizzle();
@@ -40,11 +43,33 @@ export default defineEventHandler(async (event) => {
await strava!(`activities/${body.object_id}`, {
method: "PUT",
body: stravaRequestBody,
body: {
name: stravaRequestBody.name,
description: stravaRequestBody.description,
},
}).catch((error) => {
throw createError({
statusCode: 500,
message: `Strava API: ${error.message}`,
});
});
posthog.identify({
distinctId: String(user.id),
properties: {
name: user.name,
country: user.country,
},
});
posthog.capture({
distinctId: String(user.id),
event: "content generated",
properties: {
activity: currentActivity.id,
activityType: get(currentActivity, "sport_type", "unknown"),
highlight: stravaRequestBody.meta.highlight,
tone: stravaRequestBody.meta.tone,
},
});
});

View File

@@ -4,6 +4,8 @@ import { eq } from "drizzle-orm";
export default defineEventHandler(async (event) => {
await validateHookdeck(event);
const posthog = event.context.posthog;
const body = await readBody(event);
const db = useDrizzle();
@@ -11,9 +13,29 @@ export default defineEventHandler(async (event) => {
return;
}
const user = await db.query.users.findFirst({
where: (f, o) => o.eq(f.id, get(body, "object_id")),
with: {
preferences: true,
},
});
posthog.identify({
distinctId: String(user!.id),
properties: {
name: user!.name,
country: user!.country,
},
});
await db
.delete(tables.users)
.where(eq(tables.users.id, get(body, "object_id")));
posthog.capture({
distinctId: get(body, "object_id"),
event: "user deleted",
});
sendNoContent(event);
});

28
server/plugins/posthog.ts Normal file
View File

@@ -0,0 +1,28 @@
import { PostHog } from "posthog-node";
export default defineNitroPlugin((nitroApp) => {
const runtimeConfig = useRuntimeConfig();
const posthog = new PostHog(runtimeConfig.public.posthogPublicKey, {
host: runtimeConfig.public.posthogHost,
defaults: runtimeConfig.public.posthogDefaults,
});
nitroApp.hooks.hook("request", (event) => {
event.context.posthog = posthog;
});
nitroApp.hooks.hook("beforeResponse", async () => {
await posthog.shutdown();
});
nitroApp.hooks.hook("close", async () => {
await posthog.shutdown();
});
});
declare module "h3" {
interface H3EventContext {
posthog: PostHog;
}
}

View File

@@ -24,6 +24,8 @@ export default defineOAuthStravaEventHandler({
});
}
const posthog = event.context.posthog;
const userPayload = {
id: auth.user.id,
name: `${auth.user.firstname} ${auth.user.lastname}`,
@@ -80,6 +82,19 @@ export default defineOAuthStravaEventHandler({
user: userPayload,
});
posthog.identify({
distinctId: String(user!.id),
properties: {
name: user!.name,
country: user!.country,
},
});
posthog.capture({
distinctId: String(user!.id),
event: "user logged in",
});
sendRedirect(event, "/");
},
});

View File

@@ -1,4 +1,4 @@
import { chain, draw, get, isEmpty, omit, pick, tryit } from "radash";
import { chain, draw, get, isEmpty, omit, tryit } from "radash";
import { safeDestr } from "destr";
import { match } from "ts-pattern";
import { User } from "./drizzle";
@@ -191,6 +191,10 @@ export const createActivityContent = async ({
const stravaRequestBody = {
name: responseObject!.title,
description: responseObject!.description,
meta: {
highlight,
tone,
},
};
return [aiError || parseError, stravaRequestBody] as const;

View File

@@ -0,0 +1,20 @@
import { PostHog } from "posthog-node";
let client: PostHog;
export const usePosthog = () => {
const runtimeConfig = useRuntimeConfig();
client =
client ??
new PostHog(runtimeConfig.public.posthogPublicKey, {
host: runtimeConfig.public.posthogHost,
defaults: runtimeConfig.public.posthogDefaults,
});
if (process.dev) {
client.debug();
}
return client;
};