diff --git a/flutter/lib/services/auth_notifier.dart b/flutter/lib/services/auth_notifier.dart index 48be1d5..315fc53 100644 --- a/flutter/lib/services/auth_notifier.dart +++ b/flutter/lib/services/auth_notifier.dart @@ -34,9 +34,6 @@ class Auth extends _$Auth { } else { await Posthog().reset(); } - await Posthog().capture(eventName: "user auth change", properties: { - "auth_change_event": authState.event.name, - }); }); ref.onDispose(() { diff --git a/supabase/functions/_shared/posthog.ts b/supabase/functions/_shared/posthog.ts new file mode 100644 index 0000000..18a4860 --- /dev/null +++ b/supabase/functions/_shared/posthog.ts @@ -0,0 +1,6 @@ +import { PostHog } from "npm:posthog-node@3.2.0"; + +export const posthog = new PostHog(Deno.env.get("POSTHOG_CLIENT_KEY") || "", { + flushAt: 1, + flushInterval: 0, +}); diff --git a/supabase/functions/get_stripe_url/index.ts b/supabase/functions/get_stripe_url/index.ts index 0a08e2d..6f9acc6 100644 --- a/supabase/functions/get_stripe_url/index.ts +++ b/supabase/functions/get_stripe_url/index.ts @@ -1,6 +1,7 @@ import { clientRequestHandler, corsHeaders } from "../_shared/request.ts"; import { supabase } from "../_shared/supabase.ts"; import { stripe } from "../_shared/stripe.ts"; +import { posthog } from "../_shared/posthog.ts"; clientRequestHandler(async (req, user) => { const { price, return_url } = await req.json(); @@ -30,13 +31,14 @@ clientRequestHandler(async (req, user) => { // get price based on product let redirect_url: string | undefined; + let event: string; // check if user paid for product const priceObj = price ? await stripe.prices.retrieve(price) : null; if (priceObj === null || activeProducts.includes(priceObj.product)) { // open billing portal if product/subscription has been purchased // or if price is null - console.log("open billing portal session"); + event = "user opens billing portal"; const session = await stripe.billingPortal.sessions.create({ customer: stripeCustomerId, return_url: return_url || undefined, @@ -44,7 +46,7 @@ clientRequestHandler(async (req, user) => { redirect_url = session?.url; } else { // open checkout session to purchase product - console.log("open checkout session"); + event = "user starts checkout"; const session = await stripe.checkout.sessions.create({ customer: stripeCustomerId, mode: (priceObj.type == "recurring") ? "subscription" : "payment", @@ -58,6 +60,17 @@ clientRequestHandler(async (req, user) => { }); redirect_url = session?.url; } + + posthog.capture({ + distinctId: user.id, + event, + properties: { + $set: { + "stripe_customer_id": stripeCustomerId, + }, + }, + }); + return new Response( JSON.stringify({ redirect_url }), { diff --git a/supabase/functions/on_user_modify/index.ts b/supabase/functions/on_user_modify/index.ts new file mode 100644 index 0000000..f65de5d --- /dev/null +++ b/supabase/functions/on_user_modify/index.ts @@ -0,0 +1,21 @@ +import { posthog } from "../_shared/posthog.ts"; + +Deno.serve(async (req) => { + let { record, old_record, type } = await req.json(); + record = record || old_record; + + // deno-lint-ignore no-explicit-any + const properties: Record = { type }; + properties["$set"] = properties["$set"] || {}; + properties["$set"].email = record.email || undefined; + properties["$set"].created_at = record.created_at; + properties["$set"].last_sign_in_at = record.last_sign_in_at; + + posthog.capture({ + distinctId: record.id, + event: "user modify auth table", + properties: properties, + }); + + return new Response(null); +}); diff --git a/supabase/functions/stripe_webhook/index.ts b/supabase/functions/stripe_webhook/index.ts index 3732eb1..bfd2537 100644 --- a/supabase/functions/stripe_webhook/index.ts +++ b/supabase/functions/stripe_webhook/index.ts @@ -2,6 +2,7 @@ import { processWebhookRequest } from "../_shared/stripe.ts"; import { supabase } from "../_shared/supabase.ts"; import { stripe } from "../_shared/stripe.ts"; import Stripe from "stripe"; +import { posthog } from "../_shared/posthog.ts"; Deno.serve(async (req) => { let receivedEvent; @@ -49,9 +50,27 @@ async function onSubscriptionUpdated( } } // updates purchased_products - await supabase.from("stripe").update({ + const { data } = await supabase.from("stripe").update({ active_products: prods, - }).eq("stripe_customer_id", subscription.customer); + }).eq("stripe_customer_id", subscription.customer).select(); + const row = data?.[0]; + + // posthog + if (row) { + const products = subscriptionItems.map(( + item: { plan: { product: string } }, + ) => item.plan.product); + posthog.capture({ + distinctId: row.user_id, + event: "user completes checkout", + properties: { + products, + $set: { + "stripe_customer_id": row.stripe_customer_id, + }, + }, + }); + } } async function onCheckoutComplete(session: Stripe.Session) {