2
0

🐛 (js) Improve session remember behavior

Make sure it correctly retrieves saved variables and doesn't clash with other embedded typebots
This commit is contained in:
Baptiste Arnaud
2023-03-02 10:55:03 +01:00
parent c172a44566
commit ba253cf3e9
16 changed files with 122 additions and 42 deletions

View File

@ -1,8 +1,9 @@
import { checkChatsUsage } from '@/features/usage'
import {
parsePrefilledVariables,
prefillVariables,
deepParseVariable,
parseVariables,
injectVariablesFromExistingResult,
} from '@/features/variables'
import prisma from '@/lib/prisma'
import { publicProcedure } from '@/utils/server/trpc'
@ -20,6 +21,7 @@ import {
Theme,
Typebot,
Variable,
VariableWithValue,
} from 'models'
import {
continueBotFlow,
@ -27,7 +29,7 @@ import {
setResultAsCompleted,
startBotFlow,
} from '../utils'
import { env, omit } from 'utils'
import { env, isDefined, omit } from 'utils'
export const sendMessageProcedure = publicProcedure
.meta({
@ -109,19 +111,24 @@ const startSession = async (startParams?: StartParams, userId?: string) => {
const typebot = await getTypebot(startParams, userId)
const startVariables = startParams.prefilledVariables
? parsePrefilledVariables(typebot.variables, startParams.prefilledVariables)
const prefilledVariables = startParams.prefilledVariables
? prefillVariables(typebot.variables, startParams.prefilledVariables)
: typebot.variables
const result = await getResult({
...startParams,
isPreview,
typebot: typebot.id,
startVariables,
prefilledVariables,
isNewResultOnRefreshEnabled:
typebot.settings.general.isNewResultOnRefreshEnabled ?? false,
})
const startVariables =
result && result.variables.length > 0
? injectVariablesFromExistingResult(prefilledVariables, result.variables)
: prefilledVariables
const initialState: SessionState = {
typebot: {
id: typebot.id,
@ -293,35 +300,64 @@ const getResult = async ({
typebot,
isPreview,
resultId,
startVariables,
prefilledVariables,
isNewResultOnRefreshEnabled,
}: Pick<StartParams, 'isPreview' | 'resultId' | 'typebot'> & {
startVariables: Variable[]
prefilledVariables: Variable[]
isNewResultOnRefreshEnabled: boolean
}) => {
if (isPreview || typeof typebot !== 'string') return undefined
const data = {
isCompleted: false,
typebotId: typebot,
variables: startVariables.filter((variable) => variable.value),
} satisfies Prisma.ResultUncheckedCreateInput
if (isPreview || typeof typebot !== 'string') return
const select = {
id: true,
variables: true,
hasStarted: true,
} satisfies Prisma.ResultSelect
return (
const existingResult =
resultId && !isNewResultOnRefreshEnabled
? await prisma.result.update({
? ((await prisma.result.findFirst({
where: { id: resultId },
data,
select,
})
: await prisma.result.create({
data,
select,
})
) as Pick<Result, 'id' | 'variables' | 'hasStarted'>
})) as Pick<Result, 'id' | 'variables' | 'hasStarted'>)
: undefined
if (existingResult) {
const prefilledVariableWithValue = prefilledVariables.filter(
(prefilledVariable) => isDefined(prefilledVariable.value)
)
const updatedResult = {
variables: prefilledVariableWithValue.concat(
existingResult.variables.filter(
(resultVariable) =>
isDefined(resultVariable.value) &&
!prefilledVariableWithValue.some(
(prefilledVariable) =>
prefilledVariable.name === resultVariable.name
)
)
) as VariableWithValue[],
}
await prisma.result.updateMany({
where: { id: existingResult.id },
data: updatedResult,
})
return {
id: existingResult.id,
variables: updatedResult.variables,
hasStarted: existingResult.hasStarted,
}
} else {
return (await prisma.result.create({
data: {
isCompleted: false,
typebotId: typebot,
variables: prefilledVariables.filter((variable) =>
isDefined(variable.value)
),
},
select,
})) as Pick<Result, 'id' | 'variables' | 'hasStarted'>
}
}
const parseDynamicThemeInState = (theme: Theme) => {

View File

@ -1,5 +1,6 @@
import prisma from '@/lib/prisma'
import {
Result,
SessionState,
StartParams,
Typebot,
@ -119,7 +120,7 @@ export const deepParseVariable =
return { ...newObj, [key]: currentValue }
}, {} as T)
export const parsePrefilledVariables = (
export const prefillVariables = (
variables: Typebot['variables'],
prefilledVariables: NonNullable<StartParams['prefilledVariables']>
): Variable[] =>
@ -132,6 +133,22 @@ export const parsePrefilledVariables = (
}
})
export const injectVariablesFromExistingResult = (
variables: Typebot['variables'],
resultVariables: Result['variables']
): Variable[] =>
variables.map((variable) => {
const resultVariable = resultVariables.find(
(resultVariable) =>
resultVariable.name === variable.name && !variable.value
)
if (!resultVariable) return variable
return {
...variable,
value: resultVariable.value,
}
})
export const updateVariables =
(state: SessionState) =>
async (newVariables: VariableWithUnknowValue[]): Promise<SessionState> => ({