2
0

Add API endpoint to update the typebot in ongoing chat session

This commit is contained in:
Baptiste Arnaud
2023-08-04 14:53:49 +02:00
parent f7de11611f
commit 53e4bc2b75
5 changed files with 175 additions and 30 deletions

View File

@@ -40,12 +40,11 @@ export const sendMessage = publicProcedure
summary: 'Send a message',
description:
'To initiate a chat, do not provide a `sessionId` nor a `message`.\n\nContinue the conversation by providing the `sessionId` and the `message` that should answer the previous question.\n\nSet the `isPreview` option to `true` to chat with the non-published version of the typebot.',
protect: true,
},
})
.input(sendMessageInputSchema)
.output(chatReplySchema)
.query(
.mutation(
async ({
input: { sessionId, message, startParams, clientLogs },
ctx: { user },

View File

@@ -0,0 +1,99 @@
import { publicProcedure } from '@/helpers/server/trpc'
import { TRPCError } from '@trpc/server'
import { z } from 'zod'
import { getSession } from '../queries/getSession'
import prisma from '@/lib/prisma'
import { PublicTypebot, SessionState, Typebot } from '@typebot.io/schemas'
export const updateTypebotInSession = publicProcedure
.meta({
openapi: {
method: 'POST',
path: '/sessions/{sessionId}/updateTypebot',
summary: 'Update typebot in session',
description:
'Update chat session with latest typebot modifications. This is useful when you want to update the typebot in an ongoing session after making changes to it.',
protect: true,
},
})
.input(
z.object({
sessionId: z.string(),
})
)
.output(z.object({ message: z.literal('success') }))
.mutation(async ({ input: { sessionId }, ctx: { user } }) => {
if (!user)
throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Unauthorized' })
const session = await getSession(sessionId)
if (!session)
throw new TRPCError({ code: 'NOT_FOUND', message: 'Session not found' })
const publicTypebot = (await prisma.publicTypebot.findFirst({
where: {
typebot: {
id: session.state.typebot.id,
OR: [
{
workspace: {
members: {
some: { userId: user.id, role: { in: ['ADMIN', 'MEMBER'] } },
},
},
},
{
collaborators: {
some: { userId: user.id, type: { in: ['WRITE'] } },
},
},
],
},
},
select: {
edges: true,
groups: true,
variables: true,
},
})) as Pick<PublicTypebot, 'edges' | 'variables' | 'groups'> | null
if (!publicTypebot)
throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Unauthorized' })
const newSessionState = updateSessionState(session.state, publicTypebot)
await prisma.chatSession.updateMany({
where: { id: session.id },
data: { state: newSessionState },
})
return { message: 'success' }
})
const updateSessionState = (
currentState: SessionState,
newTypebot: Pick<PublicTypebot, 'edges' | 'variables' | 'groups'>
): SessionState => ({
...currentState,
typebot: {
...currentState.typebot,
edges: newTypebot.edges,
variables: updateVariablesInSession(
currentState.typebot.variables,
newTypebot.variables
),
groups: newTypebot.groups,
},
})
const updateVariablesInSession = (
currentVariables: SessionState['typebot']['variables'],
newVariables: Typebot['variables']
): SessionState['typebot']['variables'] => [
...currentVariables,
...newVariables.filter(
(newVariable) =>
!currentVariables.find(
(currentVariable) => currentVariable.id === newVariable.id
)
),
]

View File

@@ -1,10 +1,12 @@
import { getUploadUrl } from '@/features/blocks/inputs/fileUpload/api/getUploadUrl'
import { sendMessage } from '@/features/chat/api/sendMessage'
import { router } from '../../trpc'
import { updateTypebotInSession } from '@/features/chat/api/updateTypebotInSession'
export const appRouter = router({
sendMessage,
getUploadUrl,
updateTypebotInSession,
})
export type AppRouter = typeof appRouter