♻️ Add shared eslint config
This commit is contained in:
@ -1,5 +1,11 @@
|
||||
import { TypebotViewer } from 'bot-engine'
|
||||
import { Answer, PublicTypebot, Typebot, VariableWithValue } from 'models'
|
||||
import {
|
||||
Answer,
|
||||
AnswerInput,
|
||||
PublicTypebot,
|
||||
Typebot,
|
||||
VariableWithValue,
|
||||
} from 'models'
|
||||
import { useRouter } from 'next/router'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { isDefined, isNotDefined } from 'utils'
|
||||
@ -106,7 +112,7 @@ export const TypebotPage = ({
|
||||
}
|
||||
|
||||
const handleNewAnswer = async (
|
||||
answer: Answer & { uploadedFiles: boolean }
|
||||
answer: AnswerInput & { uploadedFiles: boolean }
|
||||
) => {
|
||||
if (!resultId) return setError(new Error('Error: result was not created'))
|
||||
if (publishedTypebot.settings.general.isResultSavingEnabled !== false) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Answer } from 'models'
|
||||
import { Answer, AnswerInput } from 'models'
|
||||
import { sendRequest } from 'utils'
|
||||
|
||||
export const upsertAnswerQuery = async (
|
||||
answer: Answer & { resultId: string } & { uploadedFiles?: boolean }
|
||||
answer: AnswerInput & { resultId: string } & { uploadedFiles?: boolean }
|
||||
) =>
|
||||
sendRequest<Answer>({
|
||||
url: `/api/typebots/t/results/r/answers`,
|
||||
|
@ -151,22 +151,30 @@ test('Should correctly parse metadata', async ({ page }) => {
|
||||
).toBe(customMetadata.title)
|
||||
expect(
|
||||
await page.evaluate(
|
||||
() => (document.querySelector('meta[name="description"]') as any).content
|
||||
() =>
|
||||
(document.querySelector('meta[name="description"]') as HTMLMetaElement)
|
||||
.content
|
||||
)
|
||||
).toBe(customMetadata.description)
|
||||
expect(
|
||||
await page.evaluate(
|
||||
() => (document.querySelector('meta[property="og:image"]') as any).content
|
||||
() =>
|
||||
(document.querySelector('meta[property="og:image"]') as HTMLMetaElement)
|
||||
.content
|
||||
)
|
||||
).toBe(customMetadata.imageUrl)
|
||||
expect(
|
||||
await page.evaluate(() =>
|
||||
(document.querySelector('link[rel="icon"]') as any).getAttribute('href')
|
||||
(
|
||||
document.querySelector('link[rel="icon"]') as HTMLLinkElement
|
||||
).getAttribute('href')
|
||||
)
|
||||
).toBe(customMetadata.favIconUrl)
|
||||
expect(
|
||||
await page.evaluate(
|
||||
() => (document.querySelector('meta[name="author"]') as any).content
|
||||
() =>
|
||||
(document.querySelector('meta[name="author"]') as HTMLMetaElement)
|
||||
.content
|
||||
)
|
||||
).toBe('John Doe')
|
||||
await expect(
|
||||
|
@ -1,4 +1,4 @@
|
||||
import NextErrorComponent from 'next/error'
|
||||
import NextErrorComponent, { ErrorProps } from 'next/error'
|
||||
|
||||
import * as Sentry from '@sentry/nextjs'
|
||||
import { NextPageContext } from 'next'
|
||||
@ -24,14 +24,14 @@ const MyError = ({
|
||||
}
|
||||
|
||||
MyError.getInitialProps = async (context: NextPageContext) => {
|
||||
const errorInitialProps = await NextErrorComponent.getInitialProps(context)
|
||||
const errorInitialProps = (await NextErrorComponent.getInitialProps(
|
||||
context
|
||||
)) as ErrorProps & { hasGetInitialPropsRun: boolean }
|
||||
|
||||
const { res, err, asPath } = context
|
||||
|
||||
// Workaround for https://github.com/vercel/next.js/issues/8592, mark when
|
||||
// getInitialProps has run
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
errorInitialProps.hasGetInitialPropsRun = true
|
||||
|
||||
// Returning early because we don't want to log 404 errors to Sentry.
|
||||
|
@ -84,18 +84,19 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
}`,
|
||||
})
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const error = err as any
|
||||
return 'raw' in error
|
||||
? res.status(error.raw.statusCode).send({
|
||||
error: {
|
||||
name: `${error.raw.type} ${error.raw.param}`,
|
||||
message: error.raw.message,
|
||||
},
|
||||
})
|
||||
: res.status(500).send({
|
||||
error,
|
||||
})
|
||||
if (typeof err === 'object' && err && 'raw' in err) {
|
||||
const error = (err as { raw: Stripe.StripeRawError }).raw
|
||||
res.status(error.statusCode ?? 500).send({
|
||||
error: {
|
||||
name: `${error.type} ${error.param}`,
|
||||
message: error.message,
|
||||
},
|
||||
})
|
||||
} else {
|
||||
res.status(500).send({
|
||||
err,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return methodNotAllowed(res)
|
||||
|
@ -25,6 +25,7 @@ import { saveErrorLog, saveSuccessLog } from '@/features/logs/api'
|
||||
import { parseSampleResult } from '@/features/webhook/api'
|
||||
|
||||
const cors = initMiddleware(Cors())
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
await cors(req, res)
|
||||
if (req.method === 'POST') {
|
||||
@ -34,11 +35,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const { resultValues, variables } = (
|
||||
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
|
||||
) as {
|
||||
resultValues:
|
||||
| (Omit<ResultValues, 'createdAt'> & {
|
||||
createdAt: string
|
||||
})
|
||||
| undefined
|
||||
resultValues: ResultValues | undefined
|
||||
variables: Variable[]
|
||||
}
|
||||
const typebot = (await prisma.typebot.findUnique({
|
||||
@ -87,9 +84,7 @@ export const executeWebhook =
|
||||
webhook: Webhook,
|
||||
variables: Variable[],
|
||||
groupId: string,
|
||||
resultValues?: Omit<ResultValues, 'createdAt'> & {
|
||||
createdAt: string
|
||||
},
|
||||
resultValues?: ResultValues,
|
||||
resultId?: string
|
||||
): Promise<WebhookResponse> => {
|
||||
if (!webhook.url || !webhook.method)
|
||||
@ -199,9 +194,7 @@ const getBodyContent =
|
||||
groupId,
|
||||
}: {
|
||||
body?: string | null
|
||||
resultValues?: Omit<ResultValues, 'createdAt'> & {
|
||||
createdAt: string
|
||||
}
|
||||
resultValues?: ResultValues
|
||||
groupId: string
|
||||
}): Promise<string | undefined> => {
|
||||
if (!body) return
|
||||
@ -228,7 +221,6 @@ const convertKeyValueTableToObject = (
|
||||
}, {})
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const safeJsonParse = (json: string): { data: any; isJson: boolean } => {
|
||||
try {
|
||||
return { data: JSON.parse(json), isJson: true }
|
||||
|
@ -16,6 +16,7 @@ import Cors from 'cors'
|
||||
import { executeWebhook } from '../../executeWebhook'
|
||||
|
||||
const cors = initMiddleware(Cors())
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
await cors(req, res)
|
||||
if (req.method === 'POST') {
|
||||
@ -26,11 +27,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const { resultValues, variables } = (
|
||||
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
|
||||
) as {
|
||||
resultValues:
|
||||
| (Omit<ResultValues, 'createdAt'> & {
|
||||
createdAt: string
|
||||
})
|
||||
| undefined
|
||||
resultValues: ResultValues
|
||||
variables: Variable[]
|
||||
}
|
||||
const typebot = (await prisma.typebot.findUnique({
|
||||
|
@ -1,16 +1,11 @@
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
import { WorkspaceRole } from 'db'
|
||||
import prisma from '@/lib/prisma'
|
||||
import { InputBlockType, PublicTypebot } from 'models'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { badRequest, generatePresignedUrl, methodNotAllowed } from 'utils/api'
|
||||
import { byId, getStorageLimit, isDefined, env } from 'utils'
|
||||
import {
|
||||
sendAlmostReachedStorageLimitEmail,
|
||||
sendReachedStorageLimitEmail,
|
||||
} from 'emails'
|
||||
import { byId } from 'utils'
|
||||
|
||||
const LIMIT_EMAIL_TRIGGER_PERCENT = 0.8
|
||||
// const LIMIT_EMAIL_TRIGGER_PERCENT = 0.8
|
||||
|
||||
const handler = async (
|
||||
req: NextApiRequest,
|
||||
@ -57,112 +52,111 @@ const handler = async (
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const checkStorageLimit = async (typebotId: string) => {
|
||||
const typebot = await prisma.typebot.findFirst({
|
||||
where: { id: typebotId },
|
||||
include: {
|
||||
workspace: {
|
||||
select: {
|
||||
id: true,
|
||||
additionalStorageIndex: true,
|
||||
plan: true,
|
||||
storageLimitFirstEmailSentAt: true,
|
||||
storageLimitSecondEmailSentAt: true,
|
||||
customStorageLimit: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if (!typebot?.workspace) throw new Error('Workspace not found')
|
||||
const { workspace } = typebot
|
||||
const {
|
||||
_sum: { storageUsed: totalStorageUsed },
|
||||
} = await prisma.answer.aggregate({
|
||||
where: {
|
||||
storageUsed: { gt: 0 },
|
||||
result: {
|
||||
typebot: {
|
||||
workspace: {
|
||||
id: typebot?.workspaceId,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
_sum: { storageUsed: true },
|
||||
})
|
||||
if (!totalStorageUsed) return false
|
||||
const hasSentFirstEmail = workspace.storageLimitFirstEmailSentAt !== null
|
||||
const hasSentSecondEmail = workspace.storageLimitSecondEmailSentAt !== null
|
||||
const storageLimit = getStorageLimit(typebot.workspace)
|
||||
const storageLimitBytes = storageLimit * 1024 * 1024 * 1024
|
||||
if (
|
||||
totalStorageUsed >= storageLimitBytes * LIMIT_EMAIL_TRIGGER_PERCENT &&
|
||||
!hasSentFirstEmail &&
|
||||
env('E2E_TEST') !== 'true'
|
||||
)
|
||||
await sendAlmostReachStorageLimitNotification({
|
||||
workspaceId: workspace.id,
|
||||
storageLimit,
|
||||
})
|
||||
if (
|
||||
totalStorageUsed >= storageLimitBytes &&
|
||||
!hasSentSecondEmail &&
|
||||
env('E2E_TEST') !== 'true'
|
||||
)
|
||||
await sendReachStorageLimitNotification({
|
||||
workspaceId: workspace.id,
|
||||
storageLimit,
|
||||
})
|
||||
return totalStorageUsed >= storageLimitBytes
|
||||
}
|
||||
// const checkStorageLimit = async (typebotId: string) => {
|
||||
// const typebot = await prisma.typebot.findFirst({
|
||||
// where: { id: typebotId },
|
||||
// include: {
|
||||
// workspace: {
|
||||
// select: {
|
||||
// id: true,
|
||||
// additionalStorageIndex: true,
|
||||
// plan: true,
|
||||
// storageLimitFirstEmailSentAt: true,
|
||||
// storageLimitSecondEmailSentAt: true,
|
||||
// customStorageLimit: true,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
// if (!typebot?.workspace) throw new Error('Workspace not found')
|
||||
// const { workspace } = typebot
|
||||
// const {
|
||||
// _sum: { storageUsed: totalStorageUsed },
|
||||
// } = await prisma.answer.aggregate({
|
||||
// where: {
|
||||
// storageUsed: { gt: 0 },
|
||||
// result: {
|
||||
// typebot: {
|
||||
// workspace: {
|
||||
// id: typebot?.workspaceId,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// _sum: { storageUsed: true },
|
||||
// })
|
||||
// if (!totalStorageUsed) return false
|
||||
// const hasSentFirstEmail = workspace.storageLimitFirstEmailSentAt !== null
|
||||
// const hasSentSecondEmail = workspace.storageLimitSecondEmailSentAt !== null
|
||||
// const storageLimit = getStorageLimit(typebot.workspace)
|
||||
// const storageLimitBytes = storageLimit * 1024 * 1024 * 1024
|
||||
// if (
|
||||
// totalStorageUsed >= storageLimitBytes * LIMIT_EMAIL_TRIGGER_PERCENT &&
|
||||
// !hasSentFirstEmail &&
|
||||
// env('E2E_TEST') !== 'true'
|
||||
// )
|
||||
// await sendAlmostReachStorageLimitNotification({
|
||||
// workspaceId: workspace.id,
|
||||
// storageLimit,
|
||||
// })
|
||||
// if (
|
||||
// totalStorageUsed >= storageLimitBytes &&
|
||||
// !hasSentSecondEmail &&
|
||||
// env('E2E_TEST') !== 'true'
|
||||
// )
|
||||
// await sendReachStorageLimitNotification({
|
||||
// workspaceId: workspace.id,
|
||||
// storageLimit,
|
||||
// })
|
||||
// return totalStorageUsed >= storageLimitBytes
|
||||
// }
|
||||
|
||||
const sendAlmostReachStorageLimitNotification = async ({
|
||||
workspaceId,
|
||||
storageLimit,
|
||||
}: {
|
||||
workspaceId: string
|
||||
storageLimit: number
|
||||
}) => {
|
||||
const members = await prisma.memberInWorkspace.findMany({
|
||||
where: { role: WorkspaceRole.ADMIN, workspaceId },
|
||||
include: { user: { select: { email: true } } },
|
||||
})
|
||||
// const sendAlmostReachStorageLimitNotification = async ({
|
||||
// workspaceId,
|
||||
// storageLimit,
|
||||
// }: {
|
||||
// workspaceId: string
|
||||
// storageLimit: number
|
||||
// }) => {
|
||||
// const members = await prisma.memberInWorkspace.findMany({
|
||||
// where: { role: WorkspaceRole.ADMIN, workspaceId },
|
||||
// include: { user: { select: { email: true } } },
|
||||
// })
|
||||
|
||||
await sendAlmostReachedStorageLimitEmail({
|
||||
to: members.map((member) => member.user.email).filter(isDefined),
|
||||
storageLimit,
|
||||
url: `${process.env.NEXTAUTH_URL}/typebots?workspaceId=${workspaceId}`,
|
||||
})
|
||||
// await sendAlmostReachedStorageLimitEmail({
|
||||
// to: members.map((member) => member.user.email).filter(isDefined),
|
||||
// storageLimit,
|
||||
// url: `${process.env.NEXTAUTH_URL}/typebots?workspaceId=${workspaceId}`,
|
||||
// })
|
||||
|
||||
await prisma.workspace.update({
|
||||
where: { id: workspaceId },
|
||||
data: { storageLimitFirstEmailSentAt: new Date() },
|
||||
})
|
||||
}
|
||||
// await prisma.workspace.update({
|
||||
// where: { id: workspaceId },
|
||||
// data: { storageLimitFirstEmailSentAt: new Date() },
|
||||
// })
|
||||
// }
|
||||
|
||||
const sendReachStorageLimitNotification = async ({
|
||||
workspaceId,
|
||||
storageLimit,
|
||||
}: {
|
||||
workspaceId: string
|
||||
storageLimit: number
|
||||
}) => {
|
||||
const members = await prisma.memberInWorkspace.findMany({
|
||||
where: { role: WorkspaceRole.ADMIN, workspaceId },
|
||||
include: { user: { select: { email: true } } },
|
||||
})
|
||||
// const sendReachStorageLimitNotification = async ({
|
||||
// workspaceId,
|
||||
// storageLimit,
|
||||
// }: {
|
||||
// workspaceId: string
|
||||
// storageLimit: number
|
||||
// }) => {
|
||||
// const members = await prisma.memberInWorkspace.findMany({
|
||||
// where: { role: WorkspaceRole.ADMIN, workspaceId },
|
||||
// include: { user: { select: { email: true } } },
|
||||
// })
|
||||
|
||||
await sendReachedStorageLimitEmail({
|
||||
to: members.map((member) => member.user.email).filter(isDefined),
|
||||
storageLimit,
|
||||
url: `${process.env.NEXTAUTH_URL}/typebots?workspaceId=${workspaceId}`,
|
||||
})
|
||||
// await sendReachedStorageLimitEmail({
|
||||
// to: members.map((member) => member.user.email).filter(isDefined),
|
||||
// storageLimit,
|
||||
// url: `${process.env.NEXTAUTH_URL}/typebots?workspaceId=${workspaceId}`,
|
||||
// })
|
||||
|
||||
await prisma.workspace.update({
|
||||
where: { id: workspaceId },
|
||||
data: { storageLimitSecondEmailSentAt: new Date() },
|
||||
})
|
||||
}
|
||||
// await prisma.workspace.update({
|
||||
// where: { id: workspaceId },
|
||||
// data: { storageLimitSecondEmailSentAt: new Date() },
|
||||
// })
|
||||
// }
|
||||
|
||||
export default withSentry(handler)
|
||||
|
@ -31,7 +31,7 @@ const defaultTransportOptions = {
|
||||
|
||||
const defaultFrom = {
|
||||
name: process.env.SMTP_FROM?.split(' <')[0].replace(/"/g, ''),
|
||||
email: process.env.SMTP_FROM?.match(/\<(.*)\>/)?.pop(),
|
||||
email: process.env.SMTP_FROM?.match(/<(.*)>/)?.pop(),
|
||||
}
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
@ -54,9 +54,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
} = (
|
||||
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
|
||||
) as SendEmailOptions & {
|
||||
resultValues: Omit<ResultValues, 'createdAt'> & {
|
||||
createdAt: string
|
||||
}
|
||||
resultValues: ResultValues
|
||||
fileUrls?: string
|
||||
}
|
||||
const { name: replyToName } = parseEmailRecipient(replyTo)
|
||||
@ -166,9 +164,7 @@ const getEmailBody = async ({
|
||||
resultValues,
|
||||
}: {
|
||||
typebotId: string
|
||||
resultValues: Omit<ResultValues, 'createdAt'> & {
|
||||
createdAt: string
|
||||
}
|
||||
resultValues: ResultValues
|
||||
} & Pick<SendEmailOptions, 'isCustomBody' | 'isBodyCode' | 'body'>): Promise<
|
||||
{ html?: string; text?: string } | undefined
|
||||
> => {
|
||||
|
@ -1,16 +1,10 @@
|
||||
import { authenticateUser } from '@/features/auth/api'
|
||||
import prisma from '@/lib/prisma'
|
||||
import { Workspace, WorkspaceRole } from 'db'
|
||||
import {
|
||||
sendAlmostReachedChatsLimitEmail,
|
||||
sendReachedChatsLimitEmail,
|
||||
} from 'emails'
|
||||
import { ResultWithAnswers } from 'models'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { env, getChatsLimit, isDefined } from 'utils'
|
||||
import { methodNotAllowed } from 'utils/api'
|
||||
|
||||
const LIMIT_EMAIL_TRIGGER_PERCENT = 0.8
|
||||
// const LIMIT_EMAIL_TRIGGER_PERCENT = 0.8
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
if (req.method === 'GET') {
|
||||
@ -63,106 +57,105 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
methodNotAllowed(res)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const checkChatsUsage = async (
|
||||
workspace: Pick<
|
||||
Workspace,
|
||||
| 'id'
|
||||
| 'plan'
|
||||
| 'additionalChatsIndex'
|
||||
| 'chatsLimitFirstEmailSentAt'
|
||||
| 'chatsLimitSecondEmailSentAt'
|
||||
| 'customChatsLimit'
|
||||
>
|
||||
) => {
|
||||
const chatsLimit = getChatsLimit(workspace)
|
||||
if (chatsLimit === -1) return
|
||||
const now = new Date()
|
||||
const firstDayOfMonth = new Date(now.getFullYear(), now.getMonth(), 1)
|
||||
const lastDayOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0)
|
||||
const firstDayOfNextMonth = new Date(now.getFullYear(), now.getMonth() + 1, 1)
|
||||
const chatsCount = await prisma.result.count({
|
||||
where: {
|
||||
typebot: { workspaceId: workspace.id },
|
||||
hasStarted: true,
|
||||
createdAt: { gte: firstDayOfMonth, lte: lastDayOfMonth },
|
||||
},
|
||||
})
|
||||
const hasSentFirstEmail =
|
||||
workspace.chatsLimitFirstEmailSentAt !== null &&
|
||||
workspace.chatsLimitFirstEmailSentAt < firstDayOfNextMonth &&
|
||||
workspace.chatsLimitFirstEmailSentAt > firstDayOfMonth
|
||||
const hasSentSecondEmail =
|
||||
workspace.chatsLimitSecondEmailSentAt !== null &&
|
||||
workspace.chatsLimitSecondEmailSentAt < firstDayOfNextMonth &&
|
||||
workspace.chatsLimitSecondEmailSentAt > firstDayOfMonth
|
||||
if (
|
||||
chatsCount >= chatsLimit * LIMIT_EMAIL_TRIGGER_PERCENT &&
|
||||
!hasSentFirstEmail &&
|
||||
env('E2E_TEST') !== 'true'
|
||||
)
|
||||
await sendAlmostReachChatsLimitNotification({
|
||||
workspaceId: workspace.id,
|
||||
chatsLimit,
|
||||
})
|
||||
if (
|
||||
chatsCount >= chatsLimit &&
|
||||
!hasSentSecondEmail &&
|
||||
env('E2E_TEST') !== 'true'
|
||||
)
|
||||
await sendReachedAlertNotification({
|
||||
workspaceId: workspace.id,
|
||||
chatsLimit,
|
||||
})
|
||||
return chatsCount >= chatsLimit
|
||||
}
|
||||
// const checkChatsUsage = async (
|
||||
// workspace: Pick<
|
||||
// Workspace,
|
||||
// | 'id'
|
||||
// | 'plan'
|
||||
// | 'additionalChatsIndex'
|
||||
// | 'chatsLimitFirstEmailSentAt'
|
||||
// | 'chatsLimitSecondEmailSentAt'
|
||||
// | 'customChatsLimit'
|
||||
// >
|
||||
// ) => {
|
||||
// const chatsLimit = getChatsLimit(workspace)
|
||||
// if (chatsLimit === -1) return
|
||||
// const now = new Date()
|
||||
// const firstDayOfMonth = new Date(now.getFullYear(), now.getMonth(), 1)
|
||||
// const lastDayOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0)
|
||||
// const firstDayOfNextMonth = new Date(now.getFullYear(), now.getMonth() + 1, 1)
|
||||
// const chatsCount = await prisma.result.count({
|
||||
// where: {
|
||||
// typebot: { workspaceId: workspace.id },
|
||||
// hasStarted: true,
|
||||
// createdAt: { gte: firstDayOfMonth, lte: lastDayOfMonth },
|
||||
// },
|
||||
// })
|
||||
// const hasSentFirstEmail =
|
||||
// workspace.chatsLimitFirstEmailSentAt !== null &&
|
||||
// workspace.chatsLimitFirstEmailSentAt < firstDayOfNextMonth &&
|
||||
// workspace.chatsLimitFirstEmailSentAt > firstDayOfMonth
|
||||
// const hasSentSecondEmail =
|
||||
// workspace.chatsLimitSecondEmailSentAt !== null &&
|
||||
// workspace.chatsLimitSecondEmailSentAt < firstDayOfNextMonth &&
|
||||
// workspace.chatsLimitSecondEmailSentAt > firstDayOfMonth
|
||||
// if (
|
||||
// chatsCount >= chatsLimit * LIMIT_EMAIL_TRIGGER_PERCENT &&
|
||||
// !hasSentFirstEmail &&
|
||||
// env('E2E_TEST') !== 'true'
|
||||
// )
|
||||
// await sendAlmostReachChatsLimitNotification({
|
||||
// workspaceId: workspace.id,
|
||||
// chatsLimit,
|
||||
// })
|
||||
// if (
|
||||
// chatsCount >= chatsLimit &&
|
||||
// !hasSentSecondEmail &&
|
||||
// env('E2E_TEST') !== 'true'
|
||||
// )
|
||||
// await sendReachedAlertNotification({
|
||||
// workspaceId: workspace.id,
|
||||
// chatsLimit,
|
||||
// })
|
||||
// return chatsCount >= chatsLimit
|
||||
// }
|
||||
|
||||
const sendAlmostReachChatsLimitNotification = async ({
|
||||
workspaceId,
|
||||
chatsLimit,
|
||||
}: {
|
||||
workspaceId: string
|
||||
chatsLimit: number
|
||||
}) => {
|
||||
const members = await prisma.memberInWorkspace.findMany({
|
||||
where: { role: WorkspaceRole.ADMIN, workspaceId },
|
||||
include: { user: { select: { email: true } } },
|
||||
})
|
||||
// const sendAlmostReachChatsLimitNotification = async ({
|
||||
// workspaceId,
|
||||
// chatsLimit,
|
||||
// }: {
|
||||
// workspaceId: string
|
||||
// chatsLimit: number
|
||||
// }) => {
|
||||
// const members = await prisma.memberInWorkspace.findMany({
|
||||
// where: { role: WorkspaceRole.ADMIN, workspaceId },
|
||||
// include: { user: { select: { email: true } } },
|
||||
// })
|
||||
|
||||
await sendAlmostReachedChatsLimitEmail({
|
||||
to: members.map((member) => member.user.email).filter(isDefined),
|
||||
chatsLimit,
|
||||
url: `${process.env.NEXTAUTH_URL}/typebots?workspaceId=${workspaceId}`,
|
||||
})
|
||||
// await sendAlmostReachedChatsLimitEmail({
|
||||
// to: members.map((member) => member.user.email).filter(isDefined),
|
||||
// chatsLimit,
|
||||
// url: `${process.env.NEXTAUTH_URL}/typebots?workspaceId=${workspaceId}`,
|
||||
// })
|
||||
|
||||
await prisma.workspace.update({
|
||||
where: { id: workspaceId },
|
||||
data: { chatsLimitFirstEmailSentAt: new Date() },
|
||||
})
|
||||
}
|
||||
// await prisma.workspace.update({
|
||||
// where: { id: workspaceId },
|
||||
// data: { chatsLimitFirstEmailSentAt: new Date() },
|
||||
// })
|
||||
// }
|
||||
|
||||
const sendReachedAlertNotification = async ({
|
||||
workspaceId,
|
||||
chatsLimit,
|
||||
}: {
|
||||
workspaceId: string
|
||||
chatsLimit: number
|
||||
}) => {
|
||||
const members = await prisma.memberInWorkspace.findMany({
|
||||
where: { role: WorkspaceRole.ADMIN, workspaceId },
|
||||
include: { user: { select: { email: true } } },
|
||||
})
|
||||
// const sendReachedAlertNotification = async ({
|
||||
// workspaceId,
|
||||
// chatsLimit,
|
||||
// }: {
|
||||
// workspaceId: string
|
||||
// chatsLimit: number
|
||||
// }) => {
|
||||
// const members = await prisma.memberInWorkspace.findMany({
|
||||
// where: { role: WorkspaceRole.ADMIN, workspaceId },
|
||||
// include: { user: { select: { email: true } } },
|
||||
// })
|
||||
|
||||
await sendReachedChatsLimitEmail({
|
||||
to: members.map((member) => member.user.email).filter(isDefined),
|
||||
chatsLimit,
|
||||
url: `${process.env.NEXTAUTH_URL}/typebots?workspaceId=${workspaceId}`,
|
||||
})
|
||||
// await sendReachedChatsLimitEmail({
|
||||
// to: members.map((member) => member.user.email).filter(isDefined),
|
||||
// chatsLimit,
|
||||
// url: `${process.env.NEXTAUTH_URL}/typebots?workspaceId=${workspaceId}`,
|
||||
// })
|
||||
|
||||
await prisma.workspace.update({
|
||||
where: { id: workspaceId },
|
||||
data: { chatsLimitSecondEmailSentAt: new Date() },
|
||||
})
|
||||
}
|
||||
// await prisma.workspace.update({
|
||||
// where: { id: workspaceId },
|
||||
// data: { chatsLimitSecondEmailSentAt: new Date() },
|
||||
// })
|
||||
// }
|
||||
|
||||
export default handler
|
||||
|
Reference in New Issue
Block a user