@ -1,4 +1,10 @@
|
||||
import { SessionState, SetVariableBlock, Variable } from '@typebot.io/schemas'
|
||||
import {
|
||||
Answer,
|
||||
SessionState,
|
||||
SetVariableBlock,
|
||||
SetVariableHistoryItem,
|
||||
Variable,
|
||||
} from '@typebot.io/schemas'
|
||||
import { byId, isEmpty } from '@typebot.io/lib'
|
||||
import { ExecuteLogicResponse } from '../../../types'
|
||||
import { parseScriptToExecuteClientSideAction } from '../script/executeScript'
|
||||
@ -7,18 +13,27 @@ import { parseVariables } from '@typebot.io/variables/parseVariables'
|
||||
import { updateVariablesInSession } from '@typebot.io/variables/updateVariablesInSession'
|
||||
import { createId } from '@paralleldrive/cuid2'
|
||||
import { utcToZonedTime, format as tzFormat } from 'date-fns-tz'
|
||||
import {
|
||||
computeResultTranscript,
|
||||
parseTranscriptMessageText,
|
||||
} from '@typebot.io/logic/computeResultTranscript'
|
||||
import prisma from '@typebot.io/lib/prisma'
|
||||
import { sessionOnlySetVariableOptions } from '@typebot.io/schemas/features/blocks/logic/setVariable/constants'
|
||||
import vm from 'vm'
|
||||
|
||||
export const executeSetVariable = (
|
||||
export const executeSetVariable = async (
|
||||
state: SessionState,
|
||||
block: SetVariableBlock
|
||||
): ExecuteLogicResponse => {
|
||||
): Promise<ExecuteLogicResponse> => {
|
||||
const { variables } = state.typebotsQueue[0].typebot
|
||||
if (!block.options?.variableId)
|
||||
return {
|
||||
outgoingEdgeId: block.outgoingEdgeId,
|
||||
}
|
||||
const expressionToEvaluate = getExpressionToEvaluate(state)(block.options)
|
||||
const expressionToEvaluate = await getExpressionToEvaluate(state)(
|
||||
block.options,
|
||||
block.id
|
||||
)
|
||||
const isCustomValue = !block.options.type || block.options.type === 'Custom'
|
||||
if (
|
||||
expressionToEvaluate &&
|
||||
@ -52,10 +67,25 @@ export const executeSetVariable = (
|
||||
...existingVariable,
|
||||
value: evaluatedExpression,
|
||||
}
|
||||
const newSessionState = updateVariablesInSession(state)([newVariable])
|
||||
const { newSetVariableHistory, updatedState } = updateVariablesInSession({
|
||||
state,
|
||||
newVariables: [
|
||||
{
|
||||
...newVariable,
|
||||
isSessionVariable: sessionOnlySetVariableOptions.includes(
|
||||
block.options.type as (typeof sessionOnlySetVariableOptions)[number]
|
||||
)
|
||||
? true
|
||||
: newVariable.isSessionVariable,
|
||||
},
|
||||
],
|
||||
currentBlockId: block.id,
|
||||
})
|
||||
|
||||
return {
|
||||
outgoingEdgeId: block.outgoingEdgeId,
|
||||
newSessionState,
|
||||
newSessionState: updatedState,
|
||||
newSetVariableHistory,
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,7 +115,10 @@ const evaluateSetVariableExpression =
|
||||
|
||||
const getExpressionToEvaluate =
|
||||
(state: SessionState) =>
|
||||
(options: SetVariableBlock['options']): string | null => {
|
||||
async (
|
||||
options: SetVariableBlock['options'],
|
||||
blockId: string
|
||||
): Promise<string | null> => {
|
||||
switch (options?.type) {
|
||||
case 'Contact name':
|
||||
return state.whatsApp?.contact.name ?? null
|
||||
@ -149,6 +182,34 @@ const getExpressionToEvaluate =
|
||||
case 'Environment name': {
|
||||
return state.whatsApp ? 'whatsapp' : 'web'
|
||||
}
|
||||
case 'Transcript': {
|
||||
const props = await parseTranscriptProps(state)
|
||||
if (!props) return ''
|
||||
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,
|
||||
})
|
||||
return (
|
||||
'return `' +
|
||||
transcript
|
||||
.map(
|
||||
(message) =>
|
||||
`${
|
||||
message.role === 'bot' ? 'Assistant:' : 'User:'
|
||||
} "${parseTranscriptMessageText(message)}"`
|
||||
)
|
||||
.join('\n\n') +
|
||||
'`'
|
||||
)
|
||||
}
|
||||
case 'Custom':
|
||||
case undefined: {
|
||||
return options?.expressionToEvaluate ?? null
|
||||
@ -160,3 +221,79 @@ const toISOWithTz = (date: Date, timeZone: string) => {
|
||||
const zonedDate = utcToZonedTime(date, timeZone)
|
||||
return tzFormat(zonedDate, "yyyy-MM-dd'T'HH:mm:ssXXX", { timeZone })
|
||||
}
|
||||
|
||||
type ParsedTranscriptProps = {
|
||||
answers: Pick<Answer, 'blockId' | 'content'>[]
|
||||
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 ?? [],
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
},
|
||||
},
|
||||
answersV2: {
|
||||
select: {
|
||||
blockId: true,
|
||||
content: true,
|
||||
},
|
||||
},
|
||||
setVariableHistory: {
|
||||
select: {
|
||||
blockId: true,
|
||||
variableId: true,
|
||||
index: true,
|
||||
value: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if (!result) return
|
||||
return {
|
||||
answers: result.answersV2.concat(result.answers),
|
||||
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),
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user