2
0
Files
bot/apps/viewer/src/features/chat/api/continueChat.ts
2024-01-17 09:04:07 +01:00

98 lines
2.8 KiB
TypeScript

import { publicProcedure } from '@/helpers/server/trpc'
import { continueChatResponseSchema } from '@typebot.io/schemas/features/chat/schema'
import { TRPCError } from '@trpc/server'
import { getSession } from '@typebot.io/bot-engine/queries/getSession'
import { saveStateToDatabase } from '@typebot.io/bot-engine/saveStateToDatabase'
import { continueBotFlow } from '@typebot.io/bot-engine/continueBotFlow'
import { parseDynamicTheme } from '@typebot.io/bot-engine/parseDynamicTheme'
import { isDefined, isNotDefined } from '@typebot.io/lib/utils'
import { z } from 'zod'
import { filterPotentiallySensitiveLogs } from '@typebot.io/bot-engine/logs/filterPotentiallySensitiveLogs'
export const continueChat = publicProcedure
.meta({
openapi: {
method: 'POST',
path: '/v1/sessions/{sessionId}/continueChat',
summary: 'Continue chat',
},
})
.input(
z.object({
message: z.string().optional(),
sessionId: z
.string()
.describe(
'The session ID you got from the [startChat](./start-chat) response.'
),
})
)
.output(continueChatResponseSchema)
.mutation(async ({ input: { sessionId, message }, ctx: { res, origin } }) => {
const session = await getSession(sessionId)
if (!session) {
throw new TRPCError({
code: 'NOT_FOUND',
message: 'Session not found.',
})
}
const isSessionExpired =
session &&
isDefined(session.state.expiryTimeout) &&
session.updatedAt.getTime() + session.state.expiryTimeout < Date.now()
if (isSessionExpired)
throw new TRPCError({
code: 'NOT_FOUND',
message: 'Session expired. You need to start a new session.',
})
if (
session?.state.allowedOrigins &&
session.state.allowedOrigins.length > 0
) {
if (origin && session.state.allowedOrigins.includes(origin))
res.setHeader('Access-Control-Allow-Origin', origin)
else res.removeHeader('Access-Control-Allow-Origin')
}
const {
messages,
input,
clientSideActions,
newSessionState,
logs,
lastMessageNewFormat,
visitedEdges,
} = await continueBotFlow(message, {
version: 2,
state: session.state,
startTime: Date.now(),
})
if (newSessionState)
await saveStateToDatabase({
session: {
id: session.id,
state: newSessionState,
},
input,
logs,
clientSideActions,
visitedEdges,
})
const isPreview = isNotDefined(session.state.typebotsQueue[0].resultId)
return {
messages,
input,
clientSideActions,
dynamicTheme: parseDynamicTheme(newSessionState),
logs: isPreview ? logs : logs?.filter(filterPotentiallySensitiveLogs),
lastMessageNewFormat,
}
})