Skip to content

Commit

Permalink
📈 (billing) Track when workspace subscription is cancelled
Browse files Browse the repository at this point in the history
  • Loading branch information
baptisteArno committed Jun 26, 2023
1 parent 6430d57 commit 6f7ef82
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ export const createCheckoutSessionUrl =
(stripe: Stripe) =>
async ({
customerId,
userId,
workspaceId,
currency,
plan,
Expand All @@ -158,7 +157,6 @@ export const createCheckoutSessionUrl =
plan,
additionalChats,
additionalStorage,
userId,
},
currency,
billing_address_collection: 'required',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ export const createCustomCheckoutSession = authenticatedProcedure
mode: 'subscription',
metadata: {
claimableCustomPlanId: workspace.claimableCustomPlan.id,
userId: user.id,
},
currency: workspace.claimableCustomPlan.currency,
billing_address_collection: 'required',
Expand Down
71 changes: 51 additions & 20 deletions apps/builder/src/pages/api/stripe/webhook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Stripe from 'stripe'
import Cors from 'micro-cors'
import { buffer } from 'micro'
import prisma from '@/lib/prisma'
import { Plan } from '@typebot.io/prisma'
import { Plan, WorkspaceRole } from '@typebot.io/prisma'
import { RequestHandler } from 'next/dist/server/next'
import { sendTelemetryEvents } from '@typebot.io/lib/telemetry/sendTelemetryEvent'
import { PublicTypebot, Typebot } from '@typebot.io/schemas'
Expand Down Expand Up @@ -52,18 +52,13 @@ const webhookHandler = async (req: NextApiRequest, res: NextApiResponse) => {
}
| { claimableCustomPlanId: string; userId: string }
if ('plan' in metadata) {
const {
workspaceId,
plan,
additionalChats,
additionalStorage,
userId,
} = metadata
const { workspaceId, plan, additionalChats, additionalStorage } =
metadata
if (!workspaceId || !plan || !additionalChats || !additionalStorage)
return res
.status(500)
.send({ message: `Couldn't retrieve valid metadata` })
await prisma.workspace.update({
const workspace = await prisma.workspace.update({
where: { id: workspaceId },
data: {
plan,
Expand All @@ -72,20 +67,31 @@ const webhookHandler = async (req: NextApiRequest, res: NextApiResponse) => {
additionalStorageIndex: parseInt(additionalStorage),
isQuarantined: false,
},
include: {
members: {
select: { user: { select: { id: true } } },
where: {
role: WorkspaceRole.ADMIN,
},
},
},
})

await sendTelemetryEvents([
{
name: 'Subscription updated',
workspaceId,
userId,
data: {
plan,
additionalChatsIndex: parseInt(additionalChats),
additionalStorageIndex: parseInt(additionalStorage),
for (const user of workspace.members.map((member) => member.user)) {
if (!user?.id) continue
await sendTelemetryEvents([
{
name: 'Subscription updated',
workspaceId,
userId: user.id,
data: {
plan,
additionalChatsIndex: parseInt(additionalChats),
additionalStorageIndex: parseInt(additionalStorage),
},
},
},
])
])
}
} else {
const { claimableCustomPlanId, userId } = metadata
if (!claimableCustomPlanId)
Expand Down Expand Up @@ -139,7 +145,32 @@ const webhookHandler = async (req: NextApiRequest, res: NextApiResponse) => {
customStorageLimit: null,
customSeatsLimit: null,
},
include: {
members: {
select: { user: { select: { id: true } } },
where: {
role: WorkspaceRole.ADMIN,
},
},
},
})

for (const user of workspace.members.map((member) => member.user)) {
if (!user?.id) continue
await sendTelemetryEvents([
{
name: 'Subscription updated',
workspaceId: workspace.id,
userId: user.id,
data: {
plan: Plan.FREE,
additionalChatsIndex: 0,
additionalStorageIndex: 0,
},
},
])
}

const typebots = (await prisma.typebot.findMany({
where: {
workspaceId: workspace.id,
Expand Down
6 changes: 3 additions & 3 deletions packages/scripts/checkSubscriptionsStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const checkSubscriptionsStatus = async () => {
apiVersion: '2022-11-15',
})

let activeSubscriptions = 0
let totalActiveSubscriptions = 0
for (const workspace of workspacesWithPaidPlan) {
if (!workspace.stripeId) {
console.log('No stripe ID', workspace.id)
Expand All @@ -35,12 +35,12 @@ const checkSubscriptionsStatus = async () => {
continue
}
if (subscription.status === 'active') {
activeSubscriptions++
totalActiveSubscriptions++
continue
}
console.log(`${workspace.id} - ${workspace.name} - ${subscription.status}`)
}
console.log('Active subscriptions', activeSubscriptions)
console.log('Active subscriptions', totalActiveSubscriptions)
}

checkSubscriptionsStatus()

4 comments on commit 6f7ef82

@vercel
Copy link

@vercel vercel bot commented on 6f7ef82 Jun 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

viewer-v2 – ./apps/viewer

bii.bj
1stop.au
wasap.nl
x.cr8.ai
yobot.me
klujo.com
me.cr8.ai
wachat.io
svhm.mprs.in
tiger.cr8.ai
video.cr8.ai
yoda.riku.ai
zebra.cr8.ai
bemestar.club
bergamo.store
bot.krdfy.com
bot.tvbeat.it
cgcassets.com
cnvhub.com.br
facelabko.com
filmylogy.com
goldorayo.com
rabbit.cr8.ai
shop.mexwa.my
signup.cr8.ai
start.taxt.co
turkey.cr8.ai
vhpage.cr8.ai
vitamyway.com
am.nigerias.io
an.nigerias.io
app.yvon.earth
ar.nigerias.io
bot.enreso.org
bot.mail2wa.me
bot.rslabs.pro
bots.bng.tools
bots.bridge.ai
chad.gocto.com
chat.hayuri.id
chat.uprize.hu
chatgpt.lam.ee
chicken.cr8.ai
gollum.riku.ai
gsbulletin.com
journey.cr8.ai
panther.cr7.ai
panther.cr8.ai
pay.sifuim.com
penguin.cr8.ai
talk.gocare.io
test.bot.gives
ticketfute.com
unicorn.cr8.ai
apo.nigerias.io
bot.marketingplusmindset.com
bot.seidibergamoseanchetu.it
desabafe.sergiolimajr.com.br
download.venturemarketing.in
open.campus.aalen.university
piazzatorre.barrettamario.it
poll.mosaicohairboutique.com
type.cookieacademyonline.com
upload.atlasoutfittersk9.com
bot.brigadeirosemdrama.com.br
mdb.eventoequipe.progenbr.com
tuttirecepcao.fratucci.com.br
forms.escoladeautomacao.com.br
onboarding.libertydreamcare.ie
recepcao.tutti.fratucci.com.br
type.talitasouzamarques.com.br
agendamento.sergiolimajr.com.br
anamnese.clinicamegasjdr.com.br
bookings.littlepartymonkeys.com
bot.comercializadoraomicron.com
elevateyourmind.groovepages.com
viewer-v2-typebot-io.vercel.app
yourfeedback.comebackreward.com
baleia.testeeventos.progenbr.com
bot.cabin-rentals-of-georgia.net
chat.portaloficialautorizado.com
open.campus.bot.aalen.university
sondaggio.mosaicohairboutique.it
baleia.testegabinete.progenbr.com
chat.alfabetizacaobilingue.com.br
gerador.verificadordehospedes.com
personal-trainer.barrettamario.it
sondaggio.mosaicohairboutique.com
preagendamento.sergiolimajr.com.br
studiotecnicoimmobiliaremerelli.it
download.thailandmicespecialist.com
register.thailandmicespecialist.com
mdb.evento.equipeinterna.progenbr.com
bot.studiotecnicoimmobiliaremerelli.it
pesquisa.escolamodacomproposito.com.br
anamnese.clinicaramosodontologia.com.br
gabinete.baleia.formulario.progenbr.com
chrome-os-inquiry-system.itschromeos.com
viewer-v2-git-main-typebot-io.vercel.app
main-menu-for-itschromeos.itschromeos.com

@vercel
Copy link

@vercel vercel bot commented on 6f7ef82 Jun 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 6f7ef82 Jun 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

builder-v2 – ./apps/builder

builder-v2-typebot-io.vercel.app
builder-v2-git-main-typebot-io.vercel.app
app.typebot.io

@vercel
Copy link

@vercel vercel bot commented on 6f7ef82 Jun 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

docs – ./apps/docs

docs-git-main-typebot-io.vercel.app
docs-typebot-io.vercel.app
docs.typebot.io

Please sign in to comment.