⚡ (engine) Improve engine overall robustness
This commit is contained in:
@@ -11,7 +11,8 @@ import {
|
||||
import { AlertIcon } from '@/components/icons'
|
||||
import { Plan, Workspace } from 'db'
|
||||
import React from 'react'
|
||||
import { getChatsLimit, getStorageLimit, parseNumberWithCommas } from 'utils'
|
||||
import { parseNumberWithCommas } from 'utils'
|
||||
import { getChatsLimit, getStorageLimit } from 'utils/pricing'
|
||||
import { storageToReadable } from './helpers'
|
||||
import { useUsage } from '../../../hooks/useUsage'
|
||||
|
||||
|
||||
@@ -18,15 +18,15 @@ import { ChevronLeftIcon } from '@/components/icons'
|
||||
import { useWorkspace } from '@/features/workspace'
|
||||
import { Plan } from 'db'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { parseNumberWithCommas } from 'utils'
|
||||
import {
|
||||
chatsLimit,
|
||||
computePrice,
|
||||
formatPrice,
|
||||
getChatsLimit,
|
||||
getStorageLimit,
|
||||
storageLimit,
|
||||
parseNumberWithCommas,
|
||||
formatPrice,
|
||||
computePrice,
|
||||
} from 'utils'
|
||||
} from 'utils/pricing'
|
||||
import { FeaturesList } from './components/FeaturesList'
|
||||
import { MoreInfoTooltip } from '@/components/MoreInfoTooltip'
|
||||
|
||||
|
||||
@@ -14,15 +14,15 @@ import { ChevronLeftIcon } from '@/components/icons'
|
||||
import { useWorkspace } from '@/features/workspace'
|
||||
import { Plan } from 'db'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { parseNumberWithCommas } from 'utils'
|
||||
import {
|
||||
chatsLimit,
|
||||
computePrice,
|
||||
formatPrice,
|
||||
getChatsLimit,
|
||||
getStorageLimit,
|
||||
storageLimit,
|
||||
parseNumberWithCommas,
|
||||
computePrice,
|
||||
formatPrice,
|
||||
} from 'utils'
|
||||
} from 'utils/pricing'
|
||||
import { FeaturesList } from './components/FeaturesList'
|
||||
import { MoreInfoTooltip } from '@/components/MoreInfoTooltip'
|
||||
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
import { loadStripe } from '@stripe/stripe-js/pure'
|
||||
import { Plan, User } from 'db'
|
||||
import {
|
||||
env,
|
||||
guessIfUserIsEuropean,
|
||||
isDefined,
|
||||
isEmpty,
|
||||
sendRequest,
|
||||
} from 'utils'
|
||||
import { env, isDefined, isEmpty, sendRequest } from 'utils'
|
||||
import { guessIfUserIsEuropean } from 'utils/pricing'
|
||||
|
||||
type UpgradeProps = {
|
||||
user: User
|
||||
|
||||
@@ -7,9 +7,7 @@ export const executeWebhook = (
|
||||
{ blockId }: { blockId: string }
|
||||
) =>
|
||||
sendRequest<WebhookResponse>({
|
||||
url: `${getViewerUrl({
|
||||
isBuilder: true,
|
||||
})}/api/typebots/${typebotId}/blocks/${blockId}/executeWebhook`,
|
||||
url: `${getViewerUrl()}/api/typebots/${typebotId}/blocks/${blockId}/executeWebhook`,
|
||||
method: 'POST',
|
||||
body: {
|
||||
variables,
|
||||
|
||||
@@ -118,8 +118,7 @@ export const CustomDomainModal = ({
|
||||
<Stack>
|
||||
<Text fontWeight="bold">Value</Text>
|
||||
<Text>
|
||||
{env('VIEWER_INTERNAL_URL') ??
|
||||
getViewerUrl({ isBuilder: true })}
|
||||
{env('VIEWER_INTERNAL_URL') ?? getViewerUrl()}
|
||||
</Text>
|
||||
</Stack>
|
||||
</HStack>
|
||||
|
||||
@@ -123,7 +123,7 @@ export const OnboardingModal = ({ totalTypebots }: Props) => {
|
||||
<ModalBody p="10">
|
||||
{typebot && (
|
||||
<TypebotViewer
|
||||
apiHost={getViewerUrl({ isBuilder: true })}
|
||||
apiHost={getViewerUrl()}
|
||||
typebot={parseTypebotToPublicTypebot(typebot)}
|
||||
predefinedVariables={{
|
||||
Name: user?.name?.split(' ')[0] ?? undefined,
|
||||
|
||||
@@ -106,7 +106,7 @@ export const PreviewDrawer = () => {
|
||||
pointerEvents={isResizing ? 'none' : 'auto'}
|
||||
>
|
||||
<TypebotViewer
|
||||
apiHost={getViewerUrl({ isBuilder: true })}
|
||||
apiHost={getViewerUrl()}
|
||||
typebot={publicTypebot}
|
||||
onNewGroupVisible={setPreviewingEdge}
|
||||
onNewLog={handleNewLog}
|
||||
|
||||
@@ -98,9 +98,7 @@ export const SharePage = () => {
|
||||
</Heading>
|
||||
{typebot && (
|
||||
<EditableUrl
|
||||
hostname={
|
||||
getViewerUrl({ isBuilder: true }) ?? 'https://typebot.io'
|
||||
}
|
||||
hostname={getViewerUrl() ?? 'https://typebot.io'}
|
||||
pathname={publicId}
|
||||
isValid={checkIfPublicIdIsValid}
|
||||
onPathnameChange={handlePublicIdChange}
|
||||
|
||||
@@ -20,9 +20,9 @@ export const ChatEmbedCode = ({
|
||||
|
||||
const snippet = prettier.format(
|
||||
createSnippet({
|
||||
url: `${
|
||||
env('VIEWER_INTERNAL_URL') ?? getViewerUrl({ isBuilder: true })
|
||||
}/${typebot?.publicId}`,
|
||||
url: `${env('VIEWER_INTERNAL_URL') ?? getViewerUrl()}/${
|
||||
typebot?.publicId
|
||||
}`,
|
||||
button,
|
||||
proactiveMessage,
|
||||
}),
|
||||
|
||||
@@ -22,9 +22,9 @@ export const ContainerEmbedCode = ({
|
||||
|
||||
const snippet = prettier.format(
|
||||
parseSnippet({
|
||||
url: `${
|
||||
env('VIEWER_INTERNAL_URL') ?? getViewerUrl({ isBuilder: true })
|
||||
}/${typebot?.publicId}`,
|
||||
url: `${env('VIEWER_INTERNAL_URL') ?? getViewerUrl()}/${
|
||||
typebot?.publicId
|
||||
}`,
|
||||
heightLabel,
|
||||
widthLabel,
|
||||
}),
|
||||
|
||||
@@ -13,9 +13,9 @@ export const IframeEmbedCode = ({
|
||||
heightLabel,
|
||||
}: Props & FlexProps) => {
|
||||
const { typebot } = useTypebot()
|
||||
const src = `${
|
||||
env('VIEWER_INTERNAL_URL') ?? getViewerUrl({ isBuilder: true })
|
||||
}/${typebot?.publicId}`
|
||||
const src = `${env('VIEWER_INTERNAL_URL') ?? getViewerUrl()}/${
|
||||
typebot?.publicId
|
||||
}`
|
||||
const code = `<iframe src="${src}" width="${widthLabel}" height="${heightLabel}" style="border: none"></iframe>`
|
||||
|
||||
return <CodeEditor value={code} lang="html" isReadOnly />
|
||||
|
||||
@@ -17,9 +17,9 @@ export const PopupEmbedCode = ({ delay }: PopupEmbedCodeProps & FlexProps) => {
|
||||
const { typebot } = useTypebot()
|
||||
const snippet = prettier.format(
|
||||
createSnippet({
|
||||
url: `${
|
||||
env('VIEWER_INTERNAL_URL') ?? getViewerUrl({ isBuilder: true })
|
||||
}/${typebot?.publicId}`,
|
||||
url: `${env('VIEWER_INTERNAL_URL') ?? getViewerUrl()}/${
|
||||
typebot?.publicId
|
||||
}`,
|
||||
delay,
|
||||
}),
|
||||
{
|
||||
|
||||
@@ -20,9 +20,9 @@ export const StandardReactDiv = ({
|
||||
const { typebot } = useTypebot()
|
||||
const snippet = prettier.format(
|
||||
parseContainerSnippet({
|
||||
url: `${
|
||||
env('VIEWER_INTERNAL_URL') ?? getViewerUrl({ isBuilder: true })
|
||||
}/${typebot?.publicId}`,
|
||||
url: `${env('VIEWER_INTERNAL_URL') ?? getViewerUrl()}/${
|
||||
typebot?.publicId
|
||||
}`,
|
||||
heightLabel,
|
||||
widthLabel,
|
||||
}),
|
||||
@@ -70,9 +70,9 @@ export const PopupReactCode = ({ delay }: PopupEmbedCodeProps & FlexProps) => {
|
||||
const { typebot } = useTypebot()
|
||||
const snippet = prettier.format(
|
||||
parsePopupSnippet({
|
||||
url: `${
|
||||
env('VIEWER_INTERNAL_URL') ?? getViewerUrl({ isBuilder: true })
|
||||
}/${typebot?.publicId}`,
|
||||
url: `${env('VIEWER_INTERNAL_URL') ?? getViewerUrl()}/${
|
||||
typebot?.publicId
|
||||
}`,
|
||||
delay,
|
||||
}),
|
||||
{
|
||||
@@ -119,9 +119,9 @@ export const ChatReactCode = ({
|
||||
const { typebot } = useTypebot()
|
||||
const snippet = prettier.format(
|
||||
parseBubbleSnippet({
|
||||
url: `${
|
||||
env('VIEWER_INTERNAL_URL') ?? getViewerUrl({ isBuilder: true })
|
||||
}/${typebot?.publicId}`,
|
||||
url: `${env('VIEWER_INTERNAL_URL') ?? getViewerUrl()}/${
|
||||
typebot?.publicId
|
||||
}`,
|
||||
button,
|
||||
proactiveMessage,
|
||||
}),
|
||||
|
||||
@@ -40,9 +40,7 @@ const StandardInstructions = ({ publicId }: Pick<ModalProps, 'publicId'>) => {
|
||||
})
|
||||
|
||||
const jsCode = parseInitContainerCode({
|
||||
url: `${
|
||||
env('VIEWER_INTERNAL_URL') ?? getViewerUrl({ isBuilder: true })
|
||||
}/${publicId}`,
|
||||
url: `${env('VIEWER_INTERNAL_URL') ?? getViewerUrl()}/${publicId}`,
|
||||
})
|
||||
const headCode = `${typebotJsHtml}
|
||||
<script>
|
||||
|
||||
@@ -48,15 +48,13 @@ export const NotionModal = ({
|
||||
pr="4.5rem"
|
||||
type={'text'}
|
||||
defaultValue={`${
|
||||
env('VIEWER_INTERNAL_URL') ??
|
||||
getViewerUrl({ isBuilder: true })
|
||||
env('VIEWER_INTERNAL_URL') ?? getViewerUrl()
|
||||
}/${publicId}`}
|
||||
/>
|
||||
<InputRightElement width="4.5rem">
|
||||
<CopyButton
|
||||
textToCopy={`${
|
||||
env('VIEWER_INTERNAL_URL') ??
|
||||
getViewerUrl({ isBuilder: true })
|
||||
env('VIEWER_INTERNAL_URL') ?? getViewerUrl()
|
||||
}/${publicId}`}
|
||||
/>
|
||||
</InputRightElement>
|
||||
|
||||
@@ -45,9 +45,7 @@ const StandardInstructions = ({ publicId }: Pick<ModalProps, 'publicId'>) => {
|
||||
})
|
||||
|
||||
const jsCode = parseInitContainerCode({
|
||||
url: `${
|
||||
env('VIEWER_INTERNAL_URL') ?? getViewerUrl({ isBuilder: true })
|
||||
}/${publicId}`,
|
||||
url: `${env('VIEWER_INTERNAL_URL') ?? getViewerUrl()}/${publicId}`,
|
||||
})
|
||||
const headCode = prettier.format(
|
||||
`${typebotJsHtml}<script>${jsCode}</script>`,
|
||||
|
||||
@@ -58,15 +58,13 @@ export const WordpressModal = ({
|
||||
pr="4.5rem"
|
||||
type={'text'}
|
||||
defaultValue={`${
|
||||
env('VIEWER_INTERNAL_URL') ??
|
||||
getViewerUrl({ isBuilder: true })
|
||||
env('VIEWER_INTERNAL_URL') ?? getViewerUrl()
|
||||
}/${publicId}`}
|
||||
/>
|
||||
<InputRightElement width="4.5rem">
|
||||
<CopyButton
|
||||
textToCopy={`${
|
||||
env('VIEWER_INTERNAL_URL') ??
|
||||
getViewerUrl({ isBuilder: true })
|
||||
env('VIEWER_INTERNAL_URL') ?? getViewerUrl()
|
||||
}/${publicId}`}
|
||||
/>
|
||||
</InputRightElement>
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useMemo } from 'react'
|
||||
import { getChatsLimit, getStorageLimit } from 'utils'
|
||||
import { getChatsLimit, getStorageLimit } from 'utils/pricing'
|
||||
import { useStats } from '../hooks/useStats'
|
||||
import { ResultsProvider } from '../ResultsProvider'
|
||||
import { ResultsTableContainer } from './ResultsTableContainer'
|
||||
|
||||
@@ -23,10 +23,7 @@ export const SettingsPage = () => {
|
||||
<SettingsSideMenu />
|
||||
<Flex flex="1">
|
||||
{publicTypebot && (
|
||||
<TypebotViewer
|
||||
apiHost={getViewerUrl({ isBuilder: true })}
|
||||
typebot={publicTypebot}
|
||||
/>
|
||||
<TypebotViewer apiHost={getViewerUrl()} typebot={publicTypebot} />
|
||||
)}
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
@@ -76,7 +76,7 @@ export const TemplatesModal = ({ isOpen, onClose, onTypebotChoose }: Props) => {
|
||||
</Heading>
|
||||
{typebot && (
|
||||
<TypebotViewer
|
||||
apiHost={getViewerUrl({ isBuilder: true })}
|
||||
apiHost={getViewerUrl()}
|
||||
typebot={parseTypebotToPublicTypebot(typebot)}
|
||||
key={typebot.id}
|
||||
style={{ borderRadius: '0.25rem' }}
|
||||
|
||||
@@ -18,10 +18,7 @@ export const ThemePage = () => {
|
||||
<ThemeSideMenu />
|
||||
<Flex flex="1">
|
||||
{publicTypebot && (
|
||||
<TypebotViewer
|
||||
apiHost={getViewerUrl({ isBuilder: true })}
|
||||
typebot={publicTypebot}
|
||||
/>
|
||||
<TypebotViewer apiHost={getViewerUrl()} typebot={publicTypebot} />
|
||||
)}
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
import { UnlockPlanAlertInfo } from '@/components/UnlockPlanAlertInfo'
|
||||
import { WorkspaceInvitation, WorkspaceRole } from 'db'
|
||||
import React from 'react'
|
||||
import { getSeatsLimit } from 'utils'
|
||||
import { getSeatsLimit } from 'utils/pricing'
|
||||
import { AddMemberForm } from './AddMemberForm'
|
||||
import { checkCanInviteMember } from './helpers'
|
||||
import { MemberItem } from './MemberItem'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Plan } from 'db'
|
||||
import { getSeatsLimit } from 'utils'
|
||||
import { getSeatsLimit } from 'utils/pricing'
|
||||
|
||||
export function checkCanInviteMember({
|
||||
plan,
|
||||
|
||||
@@ -3,8 +3,9 @@ import prisma from '@/lib/prisma'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { forbidden, methodNotAllowed, notAuthenticated } from 'utils/api'
|
||||
import { getAuthenticatedUser } from '@/features/auth/api'
|
||||
import { env, getSeatsLimit } from 'utils'
|
||||
import { getSeatsLimit } from 'utils/pricing'
|
||||
import { sendWorkspaceMemberInvitationEmail } from 'emails'
|
||||
import { env } from 'utils'
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const user = await getAuthenticatedUser(req)
|
||||
|
||||
@@ -1851,21 +1851,6 @@
|
||||
"anyOf": [
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"credentialsId": {
|
||||
"type": "string"
|
||||
},
|
||||
"sheetId": {
|
||||
"type": "string"
|
||||
},
|
||||
"spreadsheetId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
@@ -1989,6 +1974,62 @@
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"credentialsId": {
|
||||
"type": "string"
|
||||
},
|
||||
"sheetId": {
|
||||
"type": "string"
|
||||
},
|
||||
"spreadsheetId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Insert a row"
|
||||
]
|
||||
},
|
||||
"cellsToInsert": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"column": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action",
|
||||
"cellsToInsert"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -2015,10 +2056,10 @@
|
||||
"action": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Insert a row"
|
||||
"Update a row"
|
||||
]
|
||||
},
|
||||
"cellsToInsert": {
|
||||
"cellsToUpsert": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
@@ -2038,11 +2079,29 @@
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"referenceCell": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"column": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action",
|
||||
"cellsToInsert"
|
||||
"cellsToUpsert"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -2051,78 +2110,19 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"credentialsId": {
|
||||
"type": "string"
|
||||
},
|
||||
"sheetId": {
|
||||
"type": "string"
|
||||
},
|
||||
"spreadsheetId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"credentialsId": {
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Update a row"
|
||||
]
|
||||
},
|
||||
"cellsToUpsert": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"column": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"referenceCell": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"column": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action",
|
||||
"cellsToUpsert"
|
||||
],
|
||||
"additionalProperties": false
|
||||
"sheetId": {
|
||||
"type": "string"
|
||||
},
|
||||
"spreadsheetId": {
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -4850,6 +4850,36 @@
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"logs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"allOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status",
|
||||
"description"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"details": {}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
||||
@@ -20,7 +20,7 @@ import { HelpCircleIcon } from 'assets/icons/HelpCircleIcon'
|
||||
import { Plan } from 'db'
|
||||
import Link from 'next/link'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { chatsLimit, formatPrice, storageLimit } from 'utils'
|
||||
import { chatsLimit, formatPrice, storageLimit } from 'utils/pricing'
|
||||
|
||||
type Props = {
|
||||
starterPrice: string
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
} from '@chakra-ui/react'
|
||||
import * as React from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { formatPrice } from 'utils'
|
||||
import { formatPrice } from 'utils/pricing'
|
||||
import { CheckCircleIcon } from '../../../assets/icons/CheckCircleIcon'
|
||||
import { Card, CardProps } from './Card'
|
||||
|
||||
|
||||
@@ -14,12 +14,8 @@ import { HelpCircleIcon } from 'assets/icons/HelpCircleIcon'
|
||||
import { Plan } from 'db'
|
||||
import Link from 'next/link'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import {
|
||||
chatsLimit,
|
||||
computePrice,
|
||||
parseNumberWithCommas,
|
||||
storageLimit,
|
||||
} from 'utils'
|
||||
import { parseNumberWithCommas } from 'utils'
|
||||
import { chatsLimit, computePrice, storageLimit } from 'utils/pricing'
|
||||
import { PricingCard } from './PricingCard'
|
||||
|
||||
export const ProPlanCard = () => {
|
||||
|
||||
@@ -14,12 +14,8 @@ import { HelpCircleIcon } from 'assets/icons/HelpCircleIcon'
|
||||
import { Plan } from 'db'
|
||||
import Link from 'next/link'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import {
|
||||
chatsLimit,
|
||||
computePrice,
|
||||
parseNumberWithCommas,
|
||||
storageLimit,
|
||||
} from 'utils'
|
||||
import { parseNumberWithCommas } from 'utils'
|
||||
import { chatsLimit, computePrice, storageLimit } from 'utils/pricing'
|
||||
import { PricingCard } from './PricingCard'
|
||||
|
||||
export const StarterPlanCard = () => {
|
||||
|
||||
@@ -19,7 +19,7 @@ import { SocialMetaTags } from 'components/common/SocialMetaTags'
|
||||
import { BackgroundPolygons } from 'components/Homepage/Hero/BackgroundPolygons'
|
||||
import { PlanComparisonTables } from 'components/PricingPage/PlanComparisonTables'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { formatPrice, prices } from 'utils'
|
||||
import { formatPrice, prices } from 'utils/pricing'
|
||||
import { StripeClimateLogo } from 'assets/logos/StripeClimateLogo'
|
||||
import { FreePlanCard } from 'components/PricingPage/FreePlanCard'
|
||||
import { StarterPlanCard } from 'components/PricingPage/StarterPlanCard'
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
"dependencies": {
|
||||
"@sentry/nextjs": "7.31.1",
|
||||
"@trpc/server": "10.9.0",
|
||||
"@typebot.io/js": "workspace:*",
|
||||
"@typebot.io/react": "workspace:*",
|
||||
"aws-sdk": "2.1299.0",
|
||||
"bot-engine": "workspace:*",
|
||||
|
||||
@@ -3,24 +3,21 @@ import { BackgroundType, Typebot } from 'models'
|
||||
import { useRouter } from 'next/router'
|
||||
import { SEO } from './Seo'
|
||||
|
||||
export type TypebotPageV2Props = {
|
||||
export type TypebotPageProps = {
|
||||
url: string
|
||||
typebot: Pick<
|
||||
Typebot,
|
||||
'settings' | 'theme' | 'name' | 'isClosed' | 'isArchived' | 'publicId'
|
||||
>
|
||||
typebot?: Pick<Typebot, 'settings' | 'theme' | 'name' | 'publicId'>
|
||||
}
|
||||
|
||||
export const TypebotPageV2 = ({ url, typebot }: TypebotPageV2Props) => {
|
||||
const { asPath, push } = useRouter()
|
||||
export const TypebotPage = ({ url, typebot }: TypebotPageProps) => {
|
||||
const { asPath, push, query } = useRouter()
|
||||
|
||||
const background = typebot.theme.general.background
|
||||
const background = typebot?.theme.general.background
|
||||
|
||||
const clearQueryParamsIfNecessary = () => {
|
||||
const hasQueryParams = asPath.includes('?')
|
||||
if (
|
||||
!hasQueryParams ||
|
||||
!(typebot.settings.general.isHideQueryParamsEnabled ?? true)
|
||||
!(typebot?.settings.general.isHideQueryParamsEnabled ?? true)
|
||||
)
|
||||
return
|
||||
push(asPath.split('?')[0], undefined, { shallow: true })
|
||||
@@ -32,22 +29,22 @@ export const TypebotPageV2 = ({ url, typebot }: TypebotPageV2Props) => {
|
||||
height: '100vh',
|
||||
// Set background color to avoid SSR flash
|
||||
backgroundColor:
|
||||
background.type === BackgroundType.COLOR
|
||||
? background.content
|
||||
background?.type === BackgroundType.COLOR
|
||||
? background?.content
|
||||
: 'white',
|
||||
}}
|
||||
>
|
||||
<SEO
|
||||
url={url}
|
||||
typebotName={typebot.name}
|
||||
metadata={typebot.settings.metadata}
|
||||
/>
|
||||
{typebot.publicId && (
|
||||
<Standard
|
||||
typebot={typebot.publicId}
|
||||
onInit={clearQueryParamsIfNecessary}
|
||||
{typebot && (
|
||||
<SEO
|
||||
url={url}
|
||||
typebotName={typebot.name}
|
||||
metadata={typebot.settings.metadata}
|
||||
/>
|
||||
)}
|
||||
<Standard
|
||||
typebot={typebot?.publicId ?? query.publicId?.toString() ?? 'n'}
|
||||
onInit={clearQueryParamsIfNecessary}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ if (window.$chatwoot) {
|
||||
}`
|
||||
|
||||
export const executeChatwootBlock = (
|
||||
{ typebot: { variables } }: SessionState,
|
||||
{ typebot: { variables }, isPreview }: SessionState,
|
||||
block: ChatwootBlock
|
||||
): ExecuteIntegrationResponse => {
|
||||
const chatwootCode = parseChatwootOpenCode(block.options)
|
||||
@@ -71,5 +71,14 @@ export const executeChatwootBlock = (
|
||||
},
|
||||
},
|
||||
},
|
||||
logs: isPreview
|
||||
? [
|
||||
{
|
||||
status: 'info',
|
||||
description: 'Chatwoot block is not supported in preview',
|
||||
details: null,
|
||||
},
|
||||
]
|
||||
: undefined,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
VariableWithValue,
|
||||
ComparisonOperators,
|
||||
LogicalOperator,
|
||||
ReplyLog,
|
||||
} from 'models'
|
||||
import { saveErrorLog } from '@/features/logs/api'
|
||||
import { getAuthenticatedGoogleDoc } from './helpers'
|
||||
@@ -20,7 +21,9 @@ export const getRow = async (
|
||||
}: { outgoingEdgeId?: string; options: GoogleSheetsGetOptions }
|
||||
): Promise<ExecuteIntegrationResponse> => {
|
||||
const { sheetId, cellsToExtract, referenceCell, filter } = options
|
||||
if (!cellsToExtract || !sheetId || !referenceCell) return { outgoingEdgeId }
|
||||
if (!sheetId) return { outgoingEdgeId }
|
||||
|
||||
let log: ReplyLog | undefined
|
||||
|
||||
const variables = state.typebot.variables
|
||||
const resultId = state.result?.id
|
||||
@@ -40,11 +43,15 @@ export const getRow = async (
|
||||
: matchFilter(row, filter)
|
||||
)
|
||||
if (filteredRows.length === 0) {
|
||||
log = {
|
||||
status: 'error',
|
||||
description: `Couldn't find any rows matching the filter`,
|
||||
}
|
||||
await saveErrorLog({
|
||||
resultId,
|
||||
message: "Couldn't find reference cell",
|
||||
message: log.description,
|
||||
})
|
||||
return { outgoingEdgeId }
|
||||
return { outgoingEdgeId, logs: log ? [log] : undefined }
|
||||
}
|
||||
const randomIndex = Math.floor(Math.random() * filteredRows.length)
|
||||
const extractingColumns = cellsToExtract
|
||||
@@ -81,13 +88,18 @@ export const getRow = async (
|
||||
newSessionState,
|
||||
}
|
||||
} catch (err) {
|
||||
log = {
|
||||
status: 'error',
|
||||
description: `An error occurred while fetching the spreadsheet data`,
|
||||
details: err,
|
||||
}
|
||||
await saveErrorLog({
|
||||
resultId,
|
||||
message: "Couldn't fetch spreadsheet data",
|
||||
message: log.description,
|
||||
details: err,
|
||||
})
|
||||
}
|
||||
return { outgoingEdgeId }
|
||||
return { outgoingEdgeId, logs: log ? [log] : undefined }
|
||||
}
|
||||
|
||||
const matchFilter = (
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { SessionState, GoogleSheetsInsertRowOptions } from 'models'
|
||||
import { SessionState, GoogleSheetsInsertRowOptions, ReplyLog } from 'models'
|
||||
import { saveErrorLog, saveSuccessLog } from '@/features/logs/api'
|
||||
import { getAuthenticatedGoogleDoc, parseCellValues } from './helpers'
|
||||
import { ExecuteIntegrationResponse } from '@/features/chat'
|
||||
@@ -10,8 +10,11 @@ export const insertRow = async (
|
||||
options,
|
||||
}: { outgoingEdgeId?: string; options: GoogleSheetsInsertRowOptions }
|
||||
): Promise<ExecuteIntegrationResponse> => {
|
||||
console.log('insertRow', options)
|
||||
if (!options.cellsToInsert || !options.sheetId) return { outgoingEdgeId }
|
||||
|
||||
let log: ReplyLog | undefined
|
||||
|
||||
const doc = await getAuthenticatedGoogleDoc({
|
||||
credentialsId: options.credentialsId,
|
||||
spreadsheetId: options.spreadsheetId,
|
||||
@@ -23,18 +26,27 @@ export const insertRow = async (
|
||||
await doc.loadInfo()
|
||||
const sheet = doc.sheetsById[options.sheetId]
|
||||
await sheet.addRow(parsedValues)
|
||||
log = {
|
||||
status: 'success',
|
||||
description: `Succesfully inserted row in ${doc.title} > ${sheet.title}`,
|
||||
}
|
||||
result &&
|
||||
(await saveSuccessLog({
|
||||
resultId: result.id,
|
||||
message: 'Succesfully inserted row',
|
||||
message: log?.description,
|
||||
}))
|
||||
} catch (err) {
|
||||
log = {
|
||||
status: 'error',
|
||||
description: `An error occured while inserting the row`,
|
||||
details: err,
|
||||
}
|
||||
result &&
|
||||
(await saveErrorLog({
|
||||
resultId: result.id,
|
||||
message: "Couldn't fetch spreadsheet data",
|
||||
message: log.description,
|
||||
details: err,
|
||||
}))
|
||||
}
|
||||
return { outgoingEdgeId }
|
||||
return { outgoingEdgeId, logs: log ? [log] : undefined }
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { SessionState, GoogleSheetsUpdateRowOptions } from 'models'
|
||||
import { SessionState, GoogleSheetsUpdateRowOptions, ReplyLog } from 'models'
|
||||
import { saveErrorLog, saveSuccessLog } from '@/features/logs/api'
|
||||
import { getAuthenticatedGoogleDoc, parseCellValues } from './helpers'
|
||||
import { TRPCError } from '@trpc/server'
|
||||
@@ -16,6 +16,8 @@ export const updateRow = async (
|
||||
if (!options.cellsToUpsert || !sheetId || !referenceCell)
|
||||
return { outgoingEdgeId }
|
||||
|
||||
let log: ReplyLog | undefined
|
||||
|
||||
const doc = await getAuthenticatedGoogleDoc({
|
||||
credentialsId: options.credentialsId,
|
||||
spreadsheetId: options.spreadsheetId,
|
||||
@@ -45,18 +47,27 @@ export const updateRow = async (
|
||||
rows[updatingRowIndex][key] = parsedValues[key]
|
||||
}
|
||||
await rows[updatingRowIndex].save()
|
||||
log = log = {
|
||||
status: 'success',
|
||||
description: `Succesfully updated row in ${doc.title} > ${sheet.title}`,
|
||||
}
|
||||
result &&
|
||||
(await saveSuccessLog({
|
||||
resultId: result.id,
|
||||
message: 'Succesfully updated row',
|
||||
message: log.description,
|
||||
}))
|
||||
} catch (err) {
|
||||
log = {
|
||||
status: 'error',
|
||||
description: `An error occured while updating the row`,
|
||||
details: err,
|
||||
}
|
||||
result &&
|
||||
(await saveErrorLog({
|
||||
resultId: result.id,
|
||||
message: "Couldn't fetch spreadsheet data",
|
||||
message: log.description,
|
||||
details: err,
|
||||
}))
|
||||
}
|
||||
return { outgoingEdgeId }
|
||||
return { outgoingEdgeId, logs: log ? [log] : undefined }
|
||||
}
|
||||
|
||||
@@ -19,11 +19,21 @@ import { decrypt } from 'utils/api'
|
||||
import { defaultFrom, defaultTransportOptions } from '../constants'
|
||||
|
||||
export const executeSendEmailBlock = async (
|
||||
{ result, typebot }: SessionState,
|
||||
{ result, typebot, isPreview }: SessionState,
|
||||
block: SendEmailBlock
|
||||
): Promise<ExecuteIntegrationResponse> => {
|
||||
const { options } = block
|
||||
const { variables } = typebot
|
||||
if (isPreview)
|
||||
return {
|
||||
outgoingEdgeId: block.outgoingEdgeId,
|
||||
logs: [
|
||||
{
|
||||
status: 'info',
|
||||
description: 'Emails are not sent in preview mode',
|
||||
},
|
||||
],
|
||||
}
|
||||
await sendEmail({
|
||||
typebotId: typebot.id,
|
||||
resultId: result?.id,
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
ResultValues,
|
||||
PublicTypebot,
|
||||
KeyValue,
|
||||
ReplyLog,
|
||||
} from 'models'
|
||||
import { stringify } from 'qs'
|
||||
import { byId, omit, parseAnswers } from 'utils'
|
||||
@@ -31,6 +32,7 @@ export const executeWebhookBlock = async (
|
||||
block: WebhookBlock | ZapierBlock | MakeComBlock | PabblyConnectBlock
|
||||
): Promise<ExecuteIntegrationResponse> => {
|
||||
const { typebot, result } = state
|
||||
let log: ReplyLog | undefined
|
||||
const webhook = (await prisma.webhook.findUnique({
|
||||
where: { id: block.webhookId },
|
||||
})) as Webhook | null
|
||||
@@ -56,20 +58,27 @@ export const executeWebhookBlock = async (
|
||||
const isError = status.startsWith('4') || status.startsWith('5')
|
||||
|
||||
if (isError) {
|
||||
log = {
|
||||
status: 'error',
|
||||
description: `Webhook returned error: ${webhookResponse.data}`,
|
||||
details: JSON.stringify(webhookResponse.data, null, 2).substring(0, 1000),
|
||||
}
|
||||
result &&
|
||||
(await saveErrorLog({
|
||||
resultId: result.id,
|
||||
message: `Webhook returned error: ${webhookResponse.data}`,
|
||||
details: JSON.stringify(webhookResponse.data, null, 2).substring(
|
||||
0,
|
||||
1000
|
||||
),
|
||||
message: log.description,
|
||||
details: log.details,
|
||||
}))
|
||||
} else {
|
||||
log = {
|
||||
status: 'success',
|
||||
description: `Webhook executed successfully!`,
|
||||
details: JSON.stringify(webhookResponse.data, null, 2).substring(0, 1000),
|
||||
}
|
||||
result &&
|
||||
(await saveSuccessLog({
|
||||
resultId: result.id,
|
||||
message: `Webhook returned success: ${webhookResponse.data}`,
|
||||
message: log.description,
|
||||
details: JSON.stringify(webhookResponse.data, null, 2).substring(
|
||||
0,
|
||||
1000
|
||||
@@ -102,7 +111,7 @@ export const executeWebhookBlock = async (
|
||||
}
|
||||
}
|
||||
|
||||
return { outgoingEdgeId: block.outgoingEdgeId }
|
||||
return { outgoingEdgeId: block.outgoingEdgeId, logs: log ? [log] : undefined }
|
||||
}
|
||||
|
||||
const prepareWebhookAttributes = (
|
||||
|
||||
@@ -40,8 +40,15 @@ export const sendMessageProcedure = publicProcedure
|
||||
const session = sessionId ? await getSession(sessionId) : null
|
||||
|
||||
if (!session) {
|
||||
const { sessionId, typebot, messages, input, resultId, dynamicTheme } =
|
||||
await startSession(startParams)
|
||||
const {
|
||||
sessionId,
|
||||
typebot,
|
||||
messages,
|
||||
input,
|
||||
resultId,
|
||||
dynamicTheme,
|
||||
logs,
|
||||
} = await startSession(startParams)
|
||||
return {
|
||||
sessionId,
|
||||
typebot: typebot
|
||||
@@ -55,9 +62,10 @@ export const sendMessageProcedure = publicProcedure
|
||||
input,
|
||||
resultId,
|
||||
dynamicTheme,
|
||||
logs,
|
||||
}
|
||||
} else {
|
||||
const { messages, input, logic, newSessionState, integrations } =
|
||||
const { messages, input, logic, newSessionState, integrations, logs } =
|
||||
await continueBotFlow(session.state)(message)
|
||||
|
||||
await prisma.chatSession.updateMany({
|
||||
@@ -73,6 +81,7 @@ export const sendMessageProcedure = publicProcedure
|
||||
logic,
|
||||
integrations,
|
||||
dynamicTheme: parseDynamicThemeReply(newSessionState),
|
||||
logs,
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -84,6 +93,9 @@ const startSession = async (startParams?: StartParams) => {
|
||||
message: 'No typebot provided in startParams',
|
||||
})
|
||||
|
||||
const isPreview =
|
||||
startParams?.isPreview || typeof startParams?.typebot !== 'string'
|
||||
|
||||
const typebot = await getTypebot(startParams)
|
||||
|
||||
const startVariables = startParams.prefilledVariables
|
||||
@@ -92,6 +104,7 @@ const startSession = async (startParams?: StartParams) => {
|
||||
|
||||
const result = await getResult({
|
||||
...startParams,
|
||||
isPreview,
|
||||
typebot: typebot.id,
|
||||
startVariables,
|
||||
isNewResultOnRefreshEnabled:
|
||||
@@ -112,7 +125,7 @@ const startSession = async (startParams?: StartParams) => {
|
||||
result: result
|
||||
? { id: result.id, variables: result.variables, hasStarted: false }
|
||||
: undefined,
|
||||
isPreview: startParams.isPreview || typeof startParams.typebot !== 'string',
|
||||
isPreview,
|
||||
currentTypebotId: typebot.id,
|
||||
dynamicTheme: parseDynamicThemeInState(typebot.theme),
|
||||
}
|
||||
@@ -122,6 +135,7 @@ const startSession = async (startParams?: StartParams) => {
|
||||
input,
|
||||
logic,
|
||||
newSessionState: newInitialState,
|
||||
logs,
|
||||
} = await startBotFlow(initialState, startParams.startGroupId)
|
||||
|
||||
if (!input)
|
||||
@@ -138,6 +152,7 @@ const startSession = async (startParams?: StartParams) => {
|
||||
),
|
||||
},
|
||||
dynamicTheme: parseDynamicThemeReply(newInitialState),
|
||||
logs,
|
||||
}
|
||||
|
||||
const sessionState: ChatSession['state'] = {
|
||||
@@ -170,6 +185,7 @@ const startSession = async (startParams?: StartParams) => {
|
||||
input,
|
||||
logic,
|
||||
dynamicTheme: parseDynamicThemeReply(newInitialState),
|
||||
logs,
|
||||
} satisfies ChatReply
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ export const executeGroup =
|
||||
const messages: ChatReply['messages'] = currentReply?.messages ?? []
|
||||
let logic: ChatReply['logic'] = currentReply?.logic
|
||||
let integrations: ChatReply['integrations'] = currentReply?.integrations
|
||||
let logs: ChatReply['logs'] = currentReply?.logs
|
||||
let nextEdgeId = null
|
||||
|
||||
let newSessionState = state
|
||||
@@ -58,6 +59,9 @@ export const executeGroup =
|
||||
blockId: block.id,
|
||||
},
|
||||
},
|
||||
logic,
|
||||
integrations,
|
||||
logs,
|
||||
}
|
||||
const executionResponse = isLogicBlock(block)
|
||||
? await executeLogic(newSessionState)(block)
|
||||
@@ -67,9 +71,11 @@ export const executeGroup =
|
||||
|
||||
if (!executionResponse) continue
|
||||
if ('logic' in executionResponse && executionResponse.logic)
|
||||
logic = executionResponse.logic
|
||||
logic = { ...logic, ...executionResponse.logic }
|
||||
if ('integrations' in executionResponse && executionResponse.integrations)
|
||||
integrations = executionResponse.integrations
|
||||
integrations = { ...integrations, ...executionResponse.integrations }
|
||||
if (executionResponse.logs)
|
||||
logs = [...(logs ?? []), ...executionResponse.logs]
|
||||
if (executionResponse.newSessionState)
|
||||
newSessionState = executionResponse.newSessionState
|
||||
if (executionResponse.outgoingEdgeId) {
|
||||
@@ -78,19 +84,23 @@ export const executeGroup =
|
||||
}
|
||||
}
|
||||
|
||||
if (!nextEdgeId) return { messages, newSessionState, logic, integrations }
|
||||
if (!nextEdgeId)
|
||||
return { messages, newSessionState, logic, integrations, logs }
|
||||
|
||||
const nextGroup = getNextGroup(newSessionState)(nextEdgeId)
|
||||
|
||||
if (nextGroup?.updatedContext) newSessionState = nextGroup.updatedContext
|
||||
|
||||
if (!nextGroup) {
|
||||
return { messages, newSessionState, logic, integrations }
|
||||
return { messages, newSessionState, logic, integrations, logs }
|
||||
}
|
||||
|
||||
return executeGroup(newSessionState, { messages, logic, integrations })(
|
||||
nextGroup.group
|
||||
)
|
||||
return executeGroup(newSessionState, {
|
||||
messages,
|
||||
logic,
|
||||
integrations,
|
||||
logs,
|
||||
})(nextGroup.group)
|
||||
}
|
||||
|
||||
const computeRuntimeOptions =
|
||||
|
||||
@@ -5,9 +5,9 @@ export type EdgeId = string
|
||||
export type ExecuteLogicResponse = {
|
||||
outgoingEdgeId: EdgeId | undefined
|
||||
newSessionState?: SessionState
|
||||
} & Pick<ChatReply, 'logic'>
|
||||
} & Pick<ChatReply, 'logic' | 'logs'>
|
||||
|
||||
export type ExecuteIntegrationResponse = {
|
||||
outgoingEdgeId: EdgeId | undefined
|
||||
newSessionState?: SessionState
|
||||
} & Pick<ChatReply, 'integrations'>
|
||||
} & Pick<ChatReply, 'integrations' | 'logs'>
|
||||
|
||||
@@ -5,7 +5,8 @@ import {
|
||||
sendReachedChatsLimitEmail,
|
||||
} from 'emails'
|
||||
import { Workspace } from 'models'
|
||||
import { env, getChatsLimit, isDefined } from 'utils'
|
||||
import { env, isDefined } from 'utils'
|
||||
import { getChatsLimit } from 'utils/pricing'
|
||||
|
||||
const LIMIT_EMAIL_TRIGGER_PERCENT = 0.8
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import Stripe from 'stripe'
|
||||
import Cors from 'cors'
|
||||
import { PaymentInputOptions, StripeCredentialsData, Variable } from 'models'
|
||||
import prisma from '@/lib/prisma'
|
||||
import { parseVariables } from 'bot-engine'
|
||||
import { parseVariables } from '@/features/variables'
|
||||
|
||||
const cors = initMiddleware(Cors())
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
WebhookBlock,
|
||||
HttpMethod,
|
||||
} from 'models'
|
||||
import { parseVariables } from 'bot-engine'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import got, { Method, Headers, HTTPError } from 'got'
|
||||
import { byId, omit, parseAnswers } from 'utils'
|
||||
@@ -25,6 +24,7 @@ import {
|
||||
getLinkedTypebots,
|
||||
getLinkedTypebotsChildren,
|
||||
} from '@/features/blocks/logic/typebotLink/api'
|
||||
import { parseVariables } from '@/features/variables'
|
||||
|
||||
const cors = initMiddleware(Cors())
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@ import prisma from '@/lib/prisma'
|
||||
import { InputBlockType, PublicTypebot } from 'models'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { badRequest, generatePresignedUrl, methodNotAllowed } from 'utils/api'
|
||||
import { byId, env, getStorageLimit, isDefined } from 'utils'
|
||||
import { byId, env, isDefined } from 'utils'
|
||||
import { getStorageLimit } from 'utils/pricing'
|
||||
import {
|
||||
sendAlmostReachedStorageLimitEmail,
|
||||
sendReachedStorageLimitEmail,
|
||||
|
||||
@@ -5,15 +5,7 @@ import cors from 'nextjs-cors'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
await cors(req, res, {
|
||||
origin: [
|
||||
'https://docs.typebot.io',
|
||||
'https://app.typebot.io',
|
||||
'http://localhost:3005',
|
||||
'http://localhost:3006',
|
||||
'http://localhost:3000',
|
||||
],
|
||||
})
|
||||
await cors(req, res)
|
||||
|
||||
return createOpenApiNextHandler({
|
||||
router: appRouter,
|
||||
@@ -25,4 +17,5 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
},
|
||||
})(req, res)
|
||||
}
|
||||
|
||||
export default handler
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import { IncomingMessage } from 'http'
|
||||
import { NotFoundPage } from '@/components/NotFoundPage'
|
||||
import { GetServerSideProps, GetServerSidePropsContext } from 'next'
|
||||
import { env, getViewerUrl, isNotDefined } from 'utils'
|
||||
import prisma from '@/lib/prisma'
|
||||
import { TypebotPageV2, TypebotPageV2Props } from '@/components/TypebotPageV2'
|
||||
import { ErrorPage } from '@/components/ErrorPage'
|
||||
import { TypebotPage, TypebotPageProps } from '@/components/TypebotPageV2'
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async (
|
||||
context: GetServerSidePropsContext
|
||||
@@ -51,18 +49,16 @@ export const getServerSideProps: GetServerSideProps = async (
|
||||
|
||||
const getTypebotFromPublicId = async (
|
||||
publicId?: string
|
||||
): Promise<TypebotPageV2Props['typebot'] | null> => {
|
||||
): Promise<TypebotPageProps['typebot'] | null> => {
|
||||
const typebot = (await prisma.typebot.findUnique({
|
||||
where: { publicId: publicId ?? '' },
|
||||
select: {
|
||||
theme: true,
|
||||
name: true,
|
||||
settings: true,
|
||||
isArchived: true,
|
||||
isClosed: true,
|
||||
publicId: true,
|
||||
},
|
||||
})) as TypebotPageV2Props['typebot'] | null
|
||||
})) as TypebotPageProps['typebot'] | null
|
||||
if (isNotDefined(typebot)) return null
|
||||
return typebot
|
||||
}
|
||||
@@ -74,11 +70,8 @@ const getHost = (
|
||||
forwardedHost: req?.headers['x-forwarded-host'] as string | undefined,
|
||||
})
|
||||
|
||||
const App = ({ typebot, url }: TypebotPageV2Props) => {
|
||||
if (!typebot || typebot.isArchived) return <NotFoundPage />
|
||||
if (typebot.isClosed)
|
||||
return <ErrorPage error={new Error('This bot is now closed')} />
|
||||
return <TypebotPageV2 typebot={typebot} url={url} />
|
||||
}
|
||||
const App = ({ typebot, url }: TypebotPageProps) => (
|
||||
<TypebotPage typebot={typebot} url={url} />
|
||||
)
|
||||
|
||||
export default App
|
||||
|
||||
Reference in New Issue
Block a user