2024-05-15 14:24:55 +02:00
|
|
|
import {
|
|
|
|
Answer,
|
|
|
|
SessionState,
|
|
|
|
SetVariableBlock,
|
|
|
|
SetVariableHistoryItem,
|
|
|
|
Variable,
|
2024-06-27 08:22:22 +02:00
|
|
|
VariableWithUnknowValue,
|
2024-08-29 15:05:35 +02:00
|
|
|
VariableWithValue,
|
2024-05-15 14:24:55 +02:00
|
|
|
} from '@typebot.io/schemas'
|
2024-08-29 15:05:35 +02:00
|
|
|
import { byId, isEmpty, isNotDefined } from '@typebot.io/lib'
|
2023-09-20 15:26:52 +02:00
|
|
|
import { ExecuteLogicResponse } from '../../../types'
|
2023-04-14 12:11:42 +02:00
|
|
|
import { parseScriptToExecuteClientSideAction } from '../script/executeScript'
|
2023-12-13 10:22:02 +01:00
|
|
|
import { parseVariables } from '@typebot.io/variables/parseVariables'
|
|
|
|
import { updateVariablesInSession } from '@typebot.io/variables/updateVariablesInSession'
|
2023-09-26 10:04:28 +02:00
|
|
|
import { createId } from '@paralleldrive/cuid2'
|
2024-02-16 10:07:29 +01:00
|
|
|
import { utcToZonedTime, format as tzFormat } from 'date-fns-tz'
|
2024-05-15 14:24:55 +02:00
|
|
|
import {
|
|
|
|
computeResultTranscript,
|
|
|
|
parseTranscriptMessageText,
|
|
|
|
} from '@typebot.io/logic/computeResultTranscript'
|
|
|
|
import prisma from '@typebot.io/lib/prisma'
|
2024-06-11 18:18:05 +02:00
|
|
|
import {
|
|
|
|
defaultSetVariableOptions,
|
|
|
|
sessionOnlySetVariableOptions,
|
|
|
|
} from '@typebot.io/schemas/features/blocks/logic/setVariable/constants'
|
2024-05-22 11:42:31 +02:00
|
|
|
import { createCodeRunner } from '@typebot.io/variables/codeRunners'
|
2024-06-11 18:18:05 +02:00
|
|
|
import { stringifyError } from '@typebot.io/lib/stringifyError'
|
2022-11-29 10:02:40 +01:00
|
|
|
|
2024-05-15 14:24:55 +02:00
|
|
|
export const executeSetVariable = async (
|
2022-11-29 10:02:40 +01:00
|
|
|
state: SessionState,
|
2024-08-13 16:01:22 +02:00
|
|
|
block: SetVariableBlock,
|
|
|
|
setVariableHistory: SetVariableHistoryItem[]
|
2024-05-15 14:24:55 +02:00
|
|
|
): Promise<ExecuteLogicResponse> => {
|
2023-08-24 07:48:30 +02:00
|
|
|
const { variables } = state.typebotsQueue[0].typebot
|
2022-11-29 10:02:40 +01:00
|
|
|
if (!block.options?.variableId)
|
|
|
|
return {
|
|
|
|
outgoingEdgeId: block.outgoingEdgeId,
|
|
|
|
}
|
2024-08-13 16:01:22 +02:00
|
|
|
|
2024-05-15 14:24:55 +02:00
|
|
|
const expressionToEvaluate = await getExpressionToEvaluate(state)(
|
|
|
|
block.options,
|
2024-08-13 16:01:22 +02:00
|
|
|
block.id,
|
|
|
|
setVariableHistory
|
2024-05-15 14:24:55 +02:00
|
|
|
)
|
2024-06-11 18:18:05 +02:00
|
|
|
const isCode =
|
|
|
|
(!block.options.type || block.options.type === 'Custom') &&
|
|
|
|
(block.options.isCode ?? defaultSetVariableOptions.isCode)
|
2023-06-15 14:45:42 +02:00
|
|
|
if (
|
|
|
|
expressionToEvaluate &&
|
2024-08-29 15:05:35 +02:00
|
|
|
expressionToEvaluate.type === 'code' &&
|
2023-08-29 10:01:28 +02:00
|
|
|
!state.whatsApp &&
|
2024-08-29 15:05:35 +02:00
|
|
|
(block.options.isExecutedOnClient ||
|
2023-06-15 14:45:42 +02:00
|
|
|
block.options.type === 'Moment of the day')
|
|
|
|
) {
|
2023-04-14 12:11:42 +02:00
|
|
|
const scriptToExecute = parseScriptToExecuteClientSideAction(
|
2023-08-24 07:48:30 +02:00
|
|
|
variables,
|
2024-08-29 15:05:35 +02:00
|
|
|
expressionToEvaluate.code
|
2023-04-14 12:11:42 +02:00
|
|
|
)
|
|
|
|
return {
|
|
|
|
outgoingEdgeId: block.outgoingEdgeId,
|
|
|
|
clientSideActions: [
|
|
|
|
{
|
2023-12-22 09:13:53 +01:00
|
|
|
type: 'setVariable',
|
2023-04-14 12:11:42 +02:00
|
|
|
setVariable: {
|
2024-06-11 18:18:05 +02:00
|
|
|
scriptToExecute: {
|
|
|
|
...scriptToExecute,
|
|
|
|
isCode,
|
|
|
|
},
|
2023-04-14 12:11:42 +02:00
|
|
|
},
|
2023-09-04 14:52:16 +02:00
|
|
|
expectsDedicatedReply: true,
|
2023-04-14 12:11:42 +02:00
|
|
|
},
|
|
|
|
],
|
|
|
|
}
|
|
|
|
}
|
2024-06-11 18:18:05 +02:00
|
|
|
const { value, error } =
|
|
|
|
(expressionToEvaluate
|
|
|
|
? evaluateSetVariableExpression(variables)(expressionToEvaluate)
|
|
|
|
: undefined) ?? {}
|
2022-11-29 10:02:40 +01:00
|
|
|
const existingVariable = variables.find(byId(block.options.variableId))
|
|
|
|
if (!existingVariable) return { outgoingEdgeId: block.outgoingEdgeId }
|
|
|
|
const newVariable = {
|
|
|
|
...existingVariable,
|
2024-06-11 18:18:05 +02:00
|
|
|
value,
|
2022-11-29 10:02:40 +01:00
|
|
|
}
|
2024-05-15 14:24:55 +02:00
|
|
|
const { newSetVariableHistory, updatedState } = updateVariablesInSession({
|
|
|
|
state,
|
|
|
|
newVariables: [
|
2024-06-27 08:22:22 +02:00
|
|
|
...parseColateralVariableChangeIfAny({ state, options: block.options }),
|
2024-05-15 14:24:55 +02:00
|
|
|
{
|
|
|
|
...newVariable,
|
|
|
|
isSessionVariable: sessionOnlySetVariableOptions.includes(
|
|
|
|
block.options.type as (typeof sessionOnlySetVariableOptions)[number]
|
|
|
|
)
|
|
|
|
? true
|
|
|
|
: newVariable.isSessionVariable,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
currentBlockId: block.id,
|
|
|
|
})
|
|
|
|
|
2022-11-29 10:02:40 +01:00
|
|
|
return {
|
|
|
|
outgoingEdgeId: block.outgoingEdgeId,
|
2024-05-15 14:24:55 +02:00
|
|
|
newSessionState: updatedState,
|
|
|
|
newSetVariableHistory,
|
2024-06-11 18:18:05 +02:00
|
|
|
logs:
|
|
|
|
error && isCode
|
|
|
|
? [
|
|
|
|
{
|
|
|
|
status: 'error',
|
|
|
|
description: 'Error evaluating Set variable code',
|
|
|
|
details: error,
|
|
|
|
},
|
|
|
|
]
|
|
|
|
: undefined,
|
2022-11-29 10:02:40 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const evaluateSetVariableExpression =
|
|
|
|
(variables: Variable[]) =>
|
2024-08-29 15:05:35 +02:00
|
|
|
(
|
|
|
|
expression:
|
|
|
|
| {
|
|
|
|
type: 'code'
|
|
|
|
code: string
|
|
|
|
}
|
|
|
|
| { type: 'value'; value: VariableWithValue['value'] }
|
|
|
|
): { value: unknown; error?: string } => {
|
|
|
|
if (expression.type === 'value') return { value: expression.value }
|
2023-02-22 12:21:11 +01:00
|
|
|
const isSingleVariable =
|
2024-08-29 15:05:35 +02:00
|
|
|
expression.code.startsWith('{{') &&
|
|
|
|
expression.code.endsWith('}}') &&
|
|
|
|
expression.code.split('{{').length === 2
|
|
|
|
if (isSingleVariable)
|
|
|
|
return { value: parseVariables(variables)(expression.code) }
|
2024-01-25 11:28:27 +01:00
|
|
|
// To avoid octal number evaluation
|
2024-08-29 15:05:35 +02:00
|
|
|
if (
|
|
|
|
!isNaN(expression.code as unknown as number) &&
|
|
|
|
/0[^.].+/.test(expression.code)
|
|
|
|
)
|
|
|
|
return { value: expression.code }
|
2022-11-29 10:02:40 +01:00
|
|
|
try {
|
2024-08-29 15:05:35 +02:00
|
|
|
const body = parseVariables(variables, { fieldToParse: 'id' })(
|
|
|
|
expression.code
|
|
|
|
)
|
2024-06-11 18:18:05 +02:00
|
|
|
return {
|
|
|
|
value: createCodeRunner({ variables })(
|
|
|
|
body.includes('return ') ? body : `return ${body}`
|
|
|
|
),
|
|
|
|
}
|
2022-11-29 10:02:40 +01:00
|
|
|
} catch (err) {
|
2024-06-11 18:18:05 +02:00
|
|
|
return {
|
2024-08-29 15:05:35 +02:00
|
|
|
value: parseVariables(variables)(expression.code),
|
2024-06-11 18:18:05 +02:00
|
|
|
error: stringifyError(err),
|
|
|
|
}
|
2022-11-29 10:02:40 +01:00
|
|
|
}
|
|
|
|
}
|
2023-05-11 17:17:24 -04:00
|
|
|
|
|
|
|
const getExpressionToEvaluate =
|
2023-08-29 10:01:28 +02:00
|
|
|
(state: SessionState) =>
|
2024-05-15 14:24:55 +02:00
|
|
|
async (
|
|
|
|
options: SetVariableBlock['options'],
|
2024-08-13 16:01:22 +02:00
|
|
|
blockId: string,
|
|
|
|
setVariableHistory: SetVariableHistoryItem[]
|
2024-08-29 15:05:35 +02:00
|
|
|
): Promise<
|
|
|
|
| { type: 'code'; code: string }
|
|
|
|
| { type: 'value'; value: VariableWithValue['value'] }
|
|
|
|
| null
|
|
|
|
> => {
|
2023-11-08 15:34:16 +01:00
|
|
|
switch (options?.type) {
|
2023-08-29 10:01:28 +02:00
|
|
|
case 'Contact name':
|
2024-08-29 15:05:35 +02:00
|
|
|
return state.whatsApp?.contact.name
|
|
|
|
? { type: 'value', value: state.whatsApp.contact.name }
|
|
|
|
: null
|
2023-09-26 09:50:20 +02:00
|
|
|
case 'Phone number': {
|
2024-08-29 15:05:35 +02:00
|
|
|
return state.whatsApp?.contact.phoneNumber
|
|
|
|
? { type: 'value', value: state.whatsApp.contact.phoneNumber }
|
|
|
|
: null
|
2023-09-26 09:50:20 +02:00
|
|
|
}
|
2024-02-16 10:13:56 +01:00
|
|
|
case 'Now': {
|
|
|
|
const timeZone = parseVariables(
|
|
|
|
state.typebotsQueue[0].typebot.variables
|
|
|
|
)(options.timeZone)
|
2024-08-29 15:05:35 +02:00
|
|
|
if (isEmpty(timeZone))
|
|
|
|
return { type: 'value', value: new Date().toISOString() }
|
|
|
|
return { type: 'value', value: toISOWithTz(new Date(), timeZone) }
|
2024-02-16 10:13:56 +01:00
|
|
|
}
|
|
|
|
|
2023-05-11 17:17:24 -04:00
|
|
|
case 'Today':
|
2024-08-29 15:05:35 +02:00
|
|
|
return { type: 'value', value: new Date().toISOString() }
|
2023-05-11 17:17:24 -04:00
|
|
|
case 'Tomorrow': {
|
2024-02-16 10:13:56 +01:00
|
|
|
const timeZone = parseVariables(
|
|
|
|
state.typebotsQueue[0].typebot.variables
|
|
|
|
)(options.timeZone)
|
|
|
|
if (isEmpty(timeZone))
|
2024-08-29 15:05:35 +02:00
|
|
|
return {
|
|
|
|
type: 'value',
|
|
|
|
value: new Date(Date.now() + 86400000).toISOString(),
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
type: 'value',
|
|
|
|
value: toISOWithTz(new Date(Date.now() + 86400000), timeZone),
|
|
|
|
}
|
2023-05-11 17:17:24 -04:00
|
|
|
}
|
|
|
|
case 'Yesterday': {
|
2024-02-16 10:13:56 +01:00
|
|
|
const timeZone = parseVariables(
|
|
|
|
state.typebotsQueue[0].typebot.variables
|
|
|
|
)(options.timeZone)
|
|
|
|
if (isEmpty(timeZone))
|
2024-08-29 15:05:35 +02:00
|
|
|
return {
|
|
|
|
type: 'value',
|
|
|
|
value: new Date(Date.now() - 86400000).toISOString(),
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
type: 'value',
|
|
|
|
value: toISOWithTz(new Date(Date.now() - 86400000), timeZone),
|
|
|
|
}
|
2023-05-11 17:17:24 -04:00
|
|
|
}
|
|
|
|
case 'Random ID': {
|
2024-08-29 15:05:35 +02:00
|
|
|
return { type: 'value', value: createId() }
|
2023-05-11 17:17:24 -04:00
|
|
|
}
|
2024-02-16 11:34:54 +01:00
|
|
|
case 'Result ID':
|
2023-05-11 17:17:24 -04:00
|
|
|
case 'User ID': {
|
2024-08-29 15:05:35 +02:00
|
|
|
return {
|
|
|
|
type: 'value',
|
|
|
|
value: state.typebotsQueue[0].resultId ?? createId(),
|
|
|
|
}
|
2023-05-11 17:17:24 -04:00
|
|
|
}
|
|
|
|
case 'Map item with same index': {
|
2024-08-29 15:05:35 +02:00
|
|
|
const baseListVariableValue =
|
|
|
|
state.typebotsQueue[0].typebot.variables.find(
|
|
|
|
byId(options.mapListItemParams?.baseListVariableId)
|
|
|
|
)?.value
|
|
|
|
const baseItemVariableValue =
|
|
|
|
state.typebotsQueue[0].typebot.variables.find(
|
|
|
|
byId(options.mapListItemParams?.baseItemVariableId)
|
|
|
|
)?.value
|
|
|
|
const targetListVariableValue =
|
|
|
|
state.typebotsQueue[0].typebot.variables.find(
|
|
|
|
byId(options.mapListItemParams?.targetListVariableId)
|
|
|
|
)?.value
|
|
|
|
|
|
|
|
if (
|
|
|
|
!Array.isArray(baseListVariableValue) ||
|
|
|
|
!baseItemVariableValue ||
|
|
|
|
typeof baseItemVariableValue !== 'string'
|
|
|
|
)
|
|
|
|
return null
|
|
|
|
const itemIndex = baseListVariableValue.indexOf(baseItemVariableValue)
|
|
|
|
if (itemIndex === -1 || !Array.isArray(targetListVariableValue))
|
|
|
|
return null
|
|
|
|
const value = targetListVariableValue.at(itemIndex)
|
|
|
|
if (isEmpty(value)) return null
|
|
|
|
return {
|
|
|
|
type: 'value',
|
|
|
|
value,
|
|
|
|
}
|
2023-05-11 17:17:24 -04:00
|
|
|
}
|
2024-06-27 08:22:22 +02:00
|
|
|
case 'Pop': {
|
2024-08-29 15:05:35 +02:00
|
|
|
const variableValue = state.typebotsQueue[0].typebot.variables.find(
|
|
|
|
byId(options.variableId)
|
|
|
|
)?.value
|
|
|
|
if (isNotDefined(variableValue)) return null
|
|
|
|
if (!Array.isArray(variableValue))
|
|
|
|
return {
|
|
|
|
type: 'value',
|
|
|
|
value: variableValue,
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
type: 'value',
|
|
|
|
value: variableValue.slice(0, -1),
|
|
|
|
}
|
2024-06-27 08:22:22 +02:00
|
|
|
}
|
|
|
|
case 'Shift': {
|
2024-08-29 15:05:35 +02:00
|
|
|
const variableValue = state.typebotsQueue[0].typebot.variables.find(
|
|
|
|
byId(options.variableId)
|
|
|
|
)?.value
|
|
|
|
if (isNotDefined(variableValue)) return null
|
|
|
|
if (!Array.isArray(variableValue))
|
|
|
|
return {
|
|
|
|
type: 'value',
|
|
|
|
value: variableValue,
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
type: 'value',
|
|
|
|
value: variableValue.slice(1),
|
|
|
|
}
|
2024-06-27 08:22:22 +02:00
|
|
|
}
|
2023-11-08 15:34:16 +01:00
|
|
|
case 'Append value(s)': {
|
2024-08-29 15:05:35 +02:00
|
|
|
if (!options.variableId) return null
|
2024-06-11 10:51:02 +02:00
|
|
|
const item = parseVariables(state.typebotsQueue[0].typebot.variables)(
|
|
|
|
options.item
|
2024-08-29 15:05:35 +02:00
|
|
|
)
|
|
|
|
const variableValue = state.typebotsQueue[0].typebot.variables.find(
|
|
|
|
byId(options.variableId)
|
|
|
|
)?.value
|
|
|
|
if (isNotDefined(variableValue))
|
|
|
|
return {
|
|
|
|
type: 'value',
|
|
|
|
value: [item],
|
|
|
|
}
|
|
|
|
if (!Array.isArray(variableValue))
|
|
|
|
return { type: 'value', value: [variableValue, item] }
|
|
|
|
return { type: 'value', value: variableValue.concat(item) }
|
2023-11-08 15:34:16 +01:00
|
|
|
}
|
2023-05-11 17:17:24 -04:00
|
|
|
case 'Empty': {
|
|
|
|
return null
|
|
|
|
}
|
2023-06-15 14:45:42 +02:00
|
|
|
case 'Moment of the day': {
|
2024-08-29 15:05:35 +02:00
|
|
|
return {
|
|
|
|
type: 'code',
|
|
|
|
code: `const now = new Date()
|
2023-06-15 14:45:42 +02:00
|
|
|
if(now.getHours() < 12) return 'morning'
|
|
|
|
if(now.getHours() >= 12 && now.getHours() < 18) return 'afternoon'
|
|
|
|
if(now.getHours() >= 18) return 'evening'
|
2024-08-29 15:05:35 +02:00
|
|
|
if(now.getHours() >= 22 || now.getHours() < 6) return 'night'`,
|
|
|
|
}
|
2023-06-15 14:45:42 +02:00
|
|
|
}
|
2023-09-26 09:50:20 +02:00
|
|
|
case 'Environment name': {
|
2024-08-29 15:05:35 +02:00
|
|
|
return {
|
|
|
|
type: 'value',
|
|
|
|
value: state.whatsApp ? 'whatsapp' : 'web',
|
|
|
|
}
|
2023-09-26 09:50:20 +02:00
|
|
|
}
|
2024-05-15 14:24:55 +02:00
|
|
|
case 'Transcript': {
|
|
|
|
const props = await parseTranscriptProps(state)
|
2024-08-29 15:05:35 +02:00
|
|
|
if (!props) return null
|
2024-05-15 14:24:55 +02:00
|
|
|
const typebotWithEmptyVariables = {
|
|
|
|
...state.typebotsQueue[0].typebot,
|
|
|
|
variables: state.typebotsQueue[0].typebot.variables.map((v) => ({
|
|
|
|
...v,
|
|
|
|
value: undefined,
|
|
|
|
})),
|
|
|
|
}
|
|
|
|
const transcript = computeResultTranscript({
|
|
|
|
typebot: typebotWithEmptyVariables,
|
|
|
|
stopAtBlockId: blockId,
|
|
|
|
...props,
|
2024-08-13 16:01:22 +02:00
|
|
|
setVariableHistory:
|
|
|
|
props.setVariableHistory.concat(setVariableHistory),
|
2024-05-15 14:24:55 +02:00
|
|
|
})
|
2024-08-29 15:05:35 +02:00
|
|
|
return {
|
|
|
|
type: 'value',
|
|
|
|
value: transcript
|
2024-05-15 14:24:55 +02:00
|
|
|
.map(
|
|
|
|
(message) =>
|
|
|
|
`${
|
|
|
|
message.role === 'bot' ? 'Assistant:' : 'User:'
|
|
|
|
} "${parseTranscriptMessageText(message)}"`
|
|
|
|
)
|
2024-08-29 15:05:35 +02:00
|
|
|
.join('\n\n'),
|
|
|
|
}
|
2024-05-15 14:24:55 +02:00
|
|
|
}
|
2023-05-11 17:17:24 -04:00
|
|
|
case 'Custom':
|
|
|
|
case undefined: {
|
2024-08-29 15:05:35 +02:00
|
|
|
return options?.expressionToEvaluate
|
|
|
|
? { type: 'code', code: options.expressionToEvaluate }
|
|
|
|
: null
|
2023-05-11 17:17:24 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-02-16 10:07:29 +01:00
|
|
|
|
|
|
|
const toISOWithTz = (date: Date, timeZone: string) => {
|
|
|
|
const zonedDate = utcToZonedTime(date, timeZone)
|
|
|
|
return tzFormat(zonedDate, "yyyy-MM-dd'T'HH:mm:ssXXX", { timeZone })
|
|
|
|
}
|
2024-05-15 14:24:55 +02:00
|
|
|
|
|
|
|
type ParsedTranscriptProps = {
|
2024-06-26 10:13:38 +02:00
|
|
|
answers: Pick<Answer, 'blockId' | 'content' | 'attachedFileUrls'>[]
|
2024-05-15 14:24:55 +02:00
|
|
|
setVariableHistory: Pick<
|
|
|
|
SetVariableHistoryItem,
|
|
|
|
'blockId' | 'variableId' | 'value'
|
|
|
|
>[]
|
|
|
|
visitedEdges: string[]
|
|
|
|
}
|
|
|
|
|
|
|
|
const parseTranscriptProps = async (
|
|
|
|
state: SessionState
|
|
|
|
): Promise<ParsedTranscriptProps | undefined> => {
|
|
|
|
if (!state.typebotsQueue[0].resultId)
|
|
|
|
return parsePreviewTranscriptProps(state)
|
|
|
|
return parseResultTranscriptProps(state)
|
|
|
|
}
|
|
|
|
|
|
|
|
const parsePreviewTranscriptProps = async (
|
|
|
|
state: SessionState
|
|
|
|
): Promise<ParsedTranscriptProps | undefined> => {
|
|
|
|
if (!state.previewMetadata) return
|
|
|
|
return {
|
|
|
|
answers: state.previewMetadata.answers ?? [],
|
|
|
|
setVariableHistory: state.previewMetadata.setVariableHistory ?? [],
|
|
|
|
visitedEdges: state.previewMetadata.visitedEdges ?? [],
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-26 10:13:38 +02:00
|
|
|
type UnifiedAnswersFromDB = (ParsedTranscriptProps['answers'][number] & {
|
|
|
|
createdAt: Date
|
|
|
|
})[]
|
|
|
|
|
2024-05-15 14:24:55 +02:00
|
|
|
const parseResultTranscriptProps = async (
|
|
|
|
state: SessionState
|
|
|
|
): Promise<ParsedTranscriptProps | undefined> => {
|
|
|
|
const result = await prisma.result.findUnique({
|
|
|
|
where: {
|
|
|
|
id: state.typebotsQueue[0].resultId,
|
|
|
|
},
|
|
|
|
select: {
|
|
|
|
edges: {
|
|
|
|
select: {
|
|
|
|
edgeId: true,
|
|
|
|
index: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
answers: {
|
|
|
|
select: {
|
|
|
|
blockId: true,
|
|
|
|
content: true,
|
2024-05-22 15:44:49 +02:00
|
|
|
createdAt: true,
|
2024-05-15 14:24:55 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
answersV2: {
|
|
|
|
select: {
|
|
|
|
blockId: true,
|
|
|
|
content: true,
|
2024-05-22 15:44:49 +02:00
|
|
|
createdAt: true,
|
2024-06-26 10:13:38 +02:00
|
|
|
attachedFileUrls: true,
|
2024-05-15 14:24:55 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
setVariableHistory: {
|
|
|
|
select: {
|
|
|
|
blockId: true,
|
|
|
|
variableId: true,
|
|
|
|
index: true,
|
|
|
|
value: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
if (!result) return
|
|
|
|
return {
|
2024-06-26 10:13:38 +02:00
|
|
|
answers: (result.answersV2 as UnifiedAnswersFromDB)
|
|
|
|
.concat(result.answers as UnifiedAnswersFromDB)
|
2024-05-22 15:44:49 +02:00
|
|
|
.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime()),
|
2024-05-15 14:24:55 +02:00
|
|
|
setVariableHistory: (
|
|
|
|
result.setVariableHistory as SetVariableHistoryItem[]
|
|
|
|
).sort((a, b) => a.index - b.index),
|
|
|
|
visitedEdges: result.edges
|
|
|
|
.sort((a, b) => a.index - b.index)
|
|
|
|
.map((edge) => edge.edgeId),
|
|
|
|
}
|
|
|
|
}
|
2024-06-27 08:22:22 +02:00
|
|
|
|
|
|
|
const parseColateralVariableChangeIfAny = ({
|
|
|
|
state,
|
|
|
|
options,
|
|
|
|
}: {
|
|
|
|
state: SessionState
|
|
|
|
options: SetVariableBlock['options']
|
|
|
|
}): VariableWithUnknowValue[] => {
|
|
|
|
if (!options || (options.type !== 'Pop' && options.type !== 'Shift'))
|
|
|
|
return []
|
|
|
|
const listVariableValue = state.typebotsQueue[0].typebot.variables.find(
|
|
|
|
(v) => v.id === options.variableId
|
|
|
|
)?.value
|
|
|
|
const variable = state.typebotsQueue[0].typebot.variables.find(
|
|
|
|
(v) => v.id === options.saveItemInVariableId
|
|
|
|
)
|
|
|
|
if (!variable || !listVariableValue) return []
|
|
|
|
return [
|
|
|
|
{
|
|
|
|
...variable,
|
|
|
|
value:
|
|
|
|
options.type === 'Pop'
|
|
|
|
? listVariableValue.at(-1)
|
|
|
|
: listVariableValue.at(0),
|
|
|
|
},
|
|
|
|
]
|
|
|
|
}
|