Skip to content

Commit

Permalink
🐛 (sendMessage) Correctly preprocess and parse fetched bot
Browse files Browse the repository at this point in the history
  • Loading branch information
baptisteArno committed Aug 24, 2023
1 parent ee3b94c commit 06ecdf0
Show file tree
Hide file tree
Showing 15 changed files with 63 additions and 45 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { useToast } from '@/hooks/useToast'
import { Button, ButtonProps, chakra } from '@chakra-ui/react'
import { Typebot, typebotCreateSchema } from '@typebot.io/schemas'
import { preprocessTypebot } from '@typebot.io/schemas/features/typebot/helpers/preprocessTypebot'
import React, { ChangeEvent } from 'react'
import { z } from 'zod'

type Props = {
onNewTypebot: (typebot: Typebot) => void
Expand All @@ -18,7 +20,9 @@ export const ImportTypebotFromFileButton = ({
const file = e.target.files[0]
const fileContent = await readFile(file)
try {
const typebot = typebotCreateSchema.parse(JSON.parse(fileContent))
const typebot = z
.preprocess(preprocessTypebot, typebotCreateSchema)
.parse(JSON.parse(fileContent))
onNewTypebot(typebot as Typebot)
} catch (err) {
console.error(err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import {
SessionState,
Variable,
ReplyLog,
Typebot,
VariableWithValue,
Edge,
typebotInSessionStateSchema,
TypebotInSession,
} from '@typebot.io/schemas'
import { ExecuteLogicResponse } from '@/features/chat/types'
import { createId } from '@paralleldrive/cuid2'
Expand Down Expand Up @@ -73,7 +74,7 @@ export const executeTypebotLink = async (
const addLinkedTypebotToState = async (
state: SessionState,
block: TypebotLinkBlock,
linkedTypebot: Pick<Typebot, 'id' | 'edges' | 'groups' | 'variables'>
linkedTypebot: TypebotInSession
): Promise<SessionState> => {
const currentTypebotInQueue = state.typebotsQueue[0]
const isPreview = isNotDefined(currentTypebotInQueue.resultId)
Expand Down Expand Up @@ -191,26 +192,28 @@ const fetchTypebot = async (state: SessionState, typebotId: string) => {
const typebot = await prisma.typebot.findUnique({
where: { id: typebotId },
select: {
version: true,
id: true,
edges: true,
groups: true,
variables: true,
},
})
return typebot as Pick<Typebot, 'id' | 'edges' | 'groups' | 'variables'>
return typebotInSessionStateSchema.parse(typebot)
}
const typebot = await prisma.publicTypebot.findUnique({
where: { typebotId },
select: {
version: true,
id: true,
edges: true,
groups: true,
variables: true,
},
})
if (!typebot) return null
return {
return typebotInSessionStateSchema.parse({
...typebot,
id: typebotId,
} as Pick<Typebot, 'id' | 'edges' | 'groups' | 'variables'>
})
}
16 changes: 7 additions & 9 deletions apps/viewer/src/features/chat/api/sendMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import {
SessionState,
StartParams,
StartTypebot,
startTypebotSchema,
Theme,
Typebot,
Variable,
VariableWithValue,
} from '@typebot.io/schemas'
Expand Down Expand Up @@ -152,6 +152,7 @@ const startSession = async (
{
resultId: result?.id,
typebot: {
version: typebot.version,
id: typebot.id,
groups: typebot.groups,
edges: typebot.edges,
Expand Down Expand Up @@ -268,17 +269,14 @@ const getTypebot = async (

const parsedTypebot =
typebotQuery && 'typebot' in typebotQuery
? ({
? {
id: typebotQuery.typebotId,
...omit(typebotQuery.typebot, 'workspace'),
...omit(typebotQuery, 'typebot', 'typebotId'),
} as StartTypebot & Pick<Typebot, 'isArchived' | 'isClosed'>)
: (typebotQuery as StartTypebot & Pick<Typebot, 'isArchived'>)
}
: typebotQuery

if (
!parsedTypebot ||
('isArchived' in parsedTypebot && parsedTypebot.isArchived)
)
if (!parsedTypebot || parsedTypebot.isArchived)
throw new TRPCError({
code: 'NOT_FOUND',
message: 'Typebot not found',
Expand All @@ -299,7 +297,7 @@ const getTypebot = async (
message: 'Typebot is closed',
})

return parsedTypebot
return startTypebotSchema.parse(parsedTypebot)
}

const getResult = async ({
Expand Down
1 change: 1 addition & 0 deletions apps/viewer/src/features/chat/chat.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ test('API chat execution should work on published bot', async ({ request }) => {
data: { message: '8', sessionId: chatSessionId },
})
).json()
console.log(messages, input)
expect(messages[0].content.richText).toStrictEqual([
{
children: [{ text: "I'm gonna shoot multiple inputs now..." }],
Expand Down
2 changes: 1 addition & 1 deletion apps/viewer/src/features/chat/helpers/continueBotFlow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export const continueBotFlow =
formattedReply !== reply ? formattedReply : undefined,
}

const nextGroup = getNextGroup(newSessionState)(nextEdgeId)
const nextGroup = await getNextGroup(newSessionState)(nextEdgeId)

newSessionState = nextGroup.newSessionState

Expand Down
4 changes: 3 additions & 1 deletion apps/viewer/src/features/chat/helpers/executeGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,9 @@ export const executeGroup =
if (!nextEdgeId && state.typebotsQueue.length === 1)
return { messages, newSessionState, clientSideActions, logs }

const nextGroup = getNextGroup(newSessionState)(nextEdgeId ?? undefined)
const nextGroup = await getNextGroup(newSessionState)(
nextEdgeId ?? undefined
)

newSessionState = nextGroup.newSessionState

Expand Down
13 changes: 11 additions & 2 deletions apps/viewer/src/features/chat/helpers/getNextGroup.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { byId } from '@typebot.io/lib'
import { Group, SessionState } from '@typebot.io/schemas'
import { upsertResult } from '../queries/upsertResult'

export type NextGroup = {
group?: Group
Expand All @@ -8,12 +9,20 @@ export type NextGroup = {

export const getNextGroup =
(state: SessionState) =>
(edgeId?: string): NextGroup => {
async (edgeId?: string): Promise<NextGroup> => {
const nextEdge = state.typebotsQueue[0].typebot.edges.find(byId(edgeId))
if (!nextEdge) {
if (state.typebotsQueue.length > 1) {
const nextEdgeId = state.typebotsQueue[0].edgeIdToTriggerWhenDone
const isMergingWithParent = state.typebotsQueue[0].isMergingWithParent
const currentResultId = state.typebotsQueue[0].resultId
if (!isMergingWithParent && currentResultId)
await upsertResult({
resultId: currentResultId,
typebot: state.typebotsQueue[0].typebot,
isCompleted: true,
hasStarted: state.typebotsQueue[0].answers.length > 0,
})
const newSessionState = {
...state,
typebotsQueue: [
Expand Down Expand Up @@ -48,7 +57,7 @@ export const getNextGroup =
...state.typebotsQueue.slice(2),
],
} satisfies SessionState
const nextGroup = getNextGroup(newSessionState)(nextEdgeId)
const nextGroup = await getNextGroup(newSessionState)(nextEdgeId)
if (!nextGroup)
return {
newSessionState,
Expand Down
2 changes: 1 addition & 1 deletion apps/viewer/src/features/chat/helpers/startBotFlow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const startBotFlow = async (
const firstEdgeId =
state.typebotsQueue[0].typebot.groups[0].blocks[0].outgoingEdgeId
if (!firstEdgeId) return { messages: [], newSessionState: state }
const nextGroup = getNextGroup(state)(firstEdgeId)
const nextGroup = await getNextGroup(state)(firstEdgeId)
if (!nextGroup.group) return { messages: [], newSessionState: state }
return executeGroup(state)(nextGroup.group)
}
1 change: 1 addition & 0 deletions apps/viewer/src/features/chat/queries/findPublicTypebot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const findPublicTypebot = ({ publicId }: Props) =>
prisma.publicTypebot.findFirst({
where: { typebot: { publicId } },
select: {
version: true,
groups: true,
edges: true,
settings: true,
Expand Down
1 change: 1 addition & 0 deletions apps/viewer/src/features/chat/queries/findTypebot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const findTypebot = ({ id, userId }: Props) =>
prisma.typebot.findFirst({
where: { id, workspace: { members: { some: { userId } } } },
select: {
version: true,
id: true,
groups: true,
edges: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from '@typebot.io/schemas'

export const leadGenerationTypebot: StartTypebot = {
version: null,
id: 'clckrl4q5000t3b6sabwokaar',
groups: [
{
Expand Down
21 changes: 13 additions & 8 deletions packages/schemas/features/chat/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { inputBlockSchemas } from '../blocks/schemas'
import { chatCompletionMessageSchema } from '../blocks/integrations/openai'
import { sessionStateSchema } from './sessionState'
import { dynamicThemeSchema } from './shared'
import { preprocessTypebot } from '../typebot/helpers/preprocessTypebot'

const chatSessionSchema = z.object({
id: z.string(),
Expand Down Expand Up @@ -84,14 +85,18 @@ const scriptToExecuteSchema = z.object({
),
})

const startTypebotSchema = typebotSchema._def.schema.pick({
id: true,
groups: true,
edges: true,
variables: true,
settings: true,
theme: true,
})
export const startTypebotSchema = z.preprocess(
preprocessTypebot,
typebotSchema._def.schema.pick({
version: true,
id: true,
groups: true,
edges: true,
variables: true,
settings: true,
theme: true,
})
)

const startParamsSchema = z.object({
typebot: startTypebotSchema
Expand Down
9 changes: 6 additions & 3 deletions packages/schemas/features/chat/shared.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { z } from 'zod'
import { publicTypebotSchema } from '../publicTypebot'
import { preprocessTypebot } from '../typebot/helpers/preprocessTypebot'

export const typebotInSessionStateSchema = publicTypebotSchema._def.schema.pick(
{
export const typebotInSessionStateSchema = z.preprocess(
preprocessTypebot,
publicTypebotSchema._def.schema.pick({
version: true,
id: true,
groups: true,
edges: true,
variables: true,
}
})
)
export type TypebotInSession = z.infer<typeof typebotInSessionStateSchema>

Expand Down
10 changes: 0 additions & 10 deletions packages/schemas/features/publicTypebot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
variableSchema,
themeSchema,
settingsSchema,
typebotSchema,
} from './typebot'
import { z } from 'zod'
import { preprocessTypebot } from './typebot/helpers/preprocessTypebot'
Expand All @@ -26,13 +25,4 @@ export const publicTypebotSchema = z.preprocess(
})
) satisfies z.ZodType<PrismaPublicTypebot, z.ZodTypeDef, unknown>

const publicTypebotWithName = publicTypebotSchema._def.schema.merge(
typebotSchema._def.schema.pick({
name: true,
isArchived: true,
isClosed: true,
})
)

export type PublicTypebot = z.infer<typeof publicTypebotSchema>
export type PublicTypebotWithName = z.infer<typeof publicTypebotWithName>
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ export const preprocessTypebot = (typebot: any) => {
if (!typebot || typebot.version === '5') return typebot
return {
...typebot,
groups: typebot.groups.map(preprocessGroup),
edges: typebot.edges?.filter(
(edge: any) => edgeSchema.safeParse(edge).success
),
groups: typebot.groups ? typebot.groups.map(preprocessGroup) : [],
edges: typebot.edges
? typebot.edges?.filter((edge: any) => edgeSchema.safeParse(edge).success)
: [],
}
}

Expand Down

3 comments on commit 06ecdf0

@vercel
Copy link

@vercel vercel bot commented on 06ecdf0 Aug 24, 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
wassep.io
sbutton.wpwakanda.com
segredosdothreads.com
talk.convobuilder.com
terrosdoscassinos.com
test.leadbooster.help
whats.laracardoso.com
www.acesso-app.online
www.hemertonsilva.com
zillabot.saaszilla.co
815639944.21000000.one
83720273.bouclidom.com
aplicacao.bmind.com.br
apply.ansuraniphone.my
bbutton.wpwwakanda.com
bolsamaisbrasil.app.br
bot.chat-debora.online
bot.clubedotrader.club
bot.gameincrivel.store
bot.louismarcondes.com
bot.perfaceacademy.com
bot.pratikmandalia.com
bot.sucessodigital.xyz
bot.t20worldcup.com.au
bot.whatsappweb.adm.br
bot2.mycompany.reviews
bot3.mycompany.reviews
bot4.mycompany.reviews
c23111azqw.nigerias.io
chat.footballmeetup.ie
conto.barrettamario.it
dieta.barrettamario.it
felipewelington.com.br
form.bridesquadapp.com
form.searchcube.com.sg
go.orodrigoribeiro.com
help.giversforgood.com
info.clickasuransi.com
jenifferrodrigues.club
kodawariab736.skeep.it
mdb.diego.progenbr.com
michaeljackson.riku.ai
premium.kandabrand.com
psicologiacognitiva.co
report.gratirabbit.com
resume.gratirabbit.com
suporte.pedroallan.com
teambuilding.hidden.sg
83242573.actualizar.xyz
87656003.actualizar.xyz
viewer-v2-typebot-io.vercel.app
mdb.assessoria.rodrigo.progenbr.com
register.thailandmicespecialist.com
mdb.assessoria.desideri.progenbr.com
mdb.assessoria.fernanda.progenbr.com
mdb.assessoria.jbatista.progenbr.com
mdb.assessoria.mauricio.progenbr.com
mdb.evento.autocadastro.progenbr.com
form.shopmercedesbenzsouthorlando.com
mdb.evento.equipeinterna.progenbr.com
bot.studiotecnicoimmobiliaremerelli.it
mdb.assessoria.boaventura.progenbr.com
mdb.assessoria.jtrebesqui.progenbr.com
pesquisa.escolamodacomproposito.com.br
anamnese.clinicaramosodontologia.com.br
gabinete.baleia.formulario.progenbr.com
mdb.assessoria.carreirinha.progenbr.com
chrome-os-inquiry-system.itschromeos.com
mdb.assessoria.paulomarques.progenbr.com
viewer-v2-git-main-typebot-io.vercel.app
main-menu-for-itschromeos.itschromeos.com
mdb.assessoria.qrcode.ademir.progenbr.com
mdb.assessoria.qrcode.arthur.progenbr.com
mdb.assessoria.qrcode.danilo.progenbr.com
mdb.assessoria.qrcode.marcao.progenbr.com
mdb.assessoria.qrcode.marcio.progenbr.com
mdb.assessoria.qrcode.aloisio.progenbr.com
mdb.assessoria.qrcode.girotto.progenbr.com
mdb.assessoria.qrcode.marinho.progenbr.com
mdb.assessoria.qrcode.rodrigo.progenbr.com
mdb.assessoria.carlosalexandre.progenbr.com
mdb.assessoria.qrcode.desideri.progenbr.com
mdb.assessoria.qrcode.fernanda.progenbr.com
mdb.assessoria.qrcode.jbatista.progenbr.com
mdb.assessoria.qrcode.mauricio.progenbr.com
mdb.assessoria.fernanda.regional.progenbr.com
mdb.assessoria.qrcode.boaventura.progenbr.com
mdb.assessoria.qrcode.jtrebesqui.progenbr.com
mdb.assessoria.qrcode.carreirinha.progenbr.com
mdb.assessoria.qrcode.paulomarques.progenbr.com
mdb.assessoria.qrcode.carlosalexandre.progenbr.com
mdb.assessoria.qrcode.fernanda.regional.progenbr.com

@vercel
Copy link

@vercel vercel bot commented on 06ecdf0 Aug 24, 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 06ecdf0 Aug 24, 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.typebot.io
docs-git-main-typebot-io.vercel.app
docs-typebot-io.vercel.app

Please sign in to comment.