Subscription
diff --git a/src/app/api/lemon-squeezy/webhook/route.tsx b/src/app/api/lemon-squeezy/webhook/route.tsx
index d80dfda..937fd7e 100644
--- a/src/app/api/lemon-squeezy/webhook/route.tsx
+++ b/src/app/api/lemon-squeezy/webhook/route.tsx
@@ -7,6 +7,8 @@ import {
type LemonsqueezySubscriptionAttributes,
type LemonsqueezyWebhookPayload,
} from "~/types/lemonsqueezy";
+import { isTriggerEnabled } from "~/lib/trigger";
+import { slackNewChurnNotification, slackNewPaymentNotification } from "~/jobs";
export async function POST(request: Request) {
if (!env.LEMON_SQUEEZY_WEBHOOK_SECRET) {
@@ -51,6 +53,31 @@ export async function POST(request: Request) {
where: { lemonSqueezyId: lemonSqueezySubscriptionId },
});
+ if (isTriggerEnabled) {
+ if (event === "subscription_created") {
+ await slackNewPaymentNotification.invoke({
+ user: {
+ email: subscriptionData.user_email,
+ id: userIdInDatabase,
+ },
+ productName: subscriptionData.product_name,
+ });
+ }
+ if (
+ event === "subscription_cancelled" ||
+ (event === "subscription_updated" &&
+ subscriptionData.status === "cancelled")
+ ) {
+ await slackNewChurnNotification.invoke({
+ user: {
+ email: subscriptionData.user_email,
+ id: userIdInDatabase,
+ },
+ productName: subscriptionData.product_name,
+ });
+ }
+ }
+
switch (event) {
case "subscription_created":
case "subscription_updated":
@@ -61,9 +88,10 @@ export async function POST(request: Request) {
renewsAt: subscriptionData.renews_at
? new Date(subscriptionData.renews_at)
: null,
- endsAt: subscriptionData.ends_at
- ? new Date(subscriptionData.ends_at)
- : null,
+ endsAt:
+ subscriptionData.status === "cancelled"
+ ? new Date(existingSubscription?.renewsAt ?? new Date())
+ : subscriptionData.ends_at ?? null,
trialEndsAt: subscriptionData.trial_ends_at
? new Date(subscriptionData.trial_ends_at)
: null,
diff --git a/src/jobs/jobs.ts b/src/jobs/jobs.ts
index 9ad1a63..9b1cff0 100644
--- a/src/jobs/jobs.ts
+++ b/src/jobs/jobs.ts
@@ -34,3 +34,51 @@ export const slackNewUserNotification = triggerClient.defineJob({
});
},
});
+export const slackNewPaymentNotification = triggerClient.defineJob({
+ id: "cascade-new-payment",
+ name: "Cascade new payment",
+ version: "0.0.1",
+ trigger: eventTrigger({
+ name: "cascade.new.payment",
+ schema: z.object({
+ user: z.object({
+ email: z.string().email(),
+ id: z.string(),
+ }),
+ productName: z.string(),
+ }),
+ }),
+ integrations: {
+ slack,
+ },
+ run: async (payload, io) => {
+ await io.slack.postMessage("post message", {
+ channel: "C06RZ0QNP6W",
+ text: `🔥 *New payment*\n\nEmail: ${payload.user.email}\nID:${payload.user.id}`,
+ });
+ },
+});
+export const slackNewChurnNotification = triggerClient.defineJob({
+ id: "cascade-new-churn",
+ name: "Cascade new churn",
+ version: "0.0.1",
+ trigger: eventTrigger({
+ name: "cascade.new.churn",
+ schema: z.object({
+ user: z.object({
+ email: z.string().email(),
+ id: z.string(),
+ }),
+ productName: z.string(),
+ }),
+ }),
+ integrations: {
+ slack,
+ },
+ run: async (payload, io) => {
+ await io.slack.postMessage("post message", {
+ channel: "C06RZ0QNP6W",
+ text: `👋🏼 *User churned*\n\nEmail: ${payload.user.email}`,
+ });
+ },
+});