@@ -1,12 +1,15 @@
|
||||
import { executeCondition } from '@typebot.io/logic/executeCondition'
|
||||
import { ChoiceInputBlock, Variable } from '@typebot.io/schemas'
|
||||
import { executeCondition } from '../../logic/condition/executeCondition'
|
||||
|
||||
export const filterChoiceItems =
|
||||
(variables: Variable[]) =>
|
||||
(block: ChoiceInputBlock): ChoiceInputBlock => {
|
||||
const filteredItems = block.items.filter((item) => {
|
||||
if (item.displayCondition?.isEnabled && item.displayCondition?.condition)
|
||||
return executeCondition(variables)(item.displayCondition.condition)
|
||||
return executeCondition({
|
||||
variables,
|
||||
condition: item.displayCondition.condition,
|
||||
})
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
@@ -41,7 +41,6 @@ const getVariableValue =
|
||||
const [transformedVariable] = transformVariablesToList(variables)([
|
||||
variable.id,
|
||||
])
|
||||
updateVariablesInSession(state)([transformedVariable])
|
||||
return transformedVariable.value as string[]
|
||||
}
|
||||
return variable.value
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import { executeCondition } from '@typebot.io/logic/executeCondition'
|
||||
import { PictureChoiceBlock, Variable } from '@typebot.io/schemas'
|
||||
import { executeCondition } from '../../logic/condition/executeCondition'
|
||||
|
||||
export const filterPictureChoiceItems =
|
||||
(variables: Variable[]) =>
|
||||
(block: PictureChoiceBlock): PictureChoiceBlock => {
|
||||
const filteredItems = block.items.filter((item) => {
|
||||
if (item.displayCondition?.isEnabled && item.displayCondition?.condition)
|
||||
return executeCondition(variables)(item.displayCondition.condition)
|
||||
return executeCondition({
|
||||
variables,
|
||||
condition: item.displayCondition.condition,
|
||||
})
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
@@ -25,6 +25,7 @@ export const executeGoogleSheetBlock = async (
|
||||
})
|
||||
case GoogleSheetsAction.GET:
|
||||
return getRow(state, {
|
||||
blockId: block.id,
|
||||
options: block.options,
|
||||
outgoingEdgeId: block.outgoingEdgeId,
|
||||
})
|
||||
|
||||
@@ -14,9 +14,14 @@ import { updateVariablesInSession } from '@typebot.io/variables/updateVariablesI
|
||||
export const getRow = async (
|
||||
state: SessionState,
|
||||
{
|
||||
blockId,
|
||||
outgoingEdgeId,
|
||||
options,
|
||||
}: { outgoingEdgeId?: string; options: GoogleSheetsGetOptions }
|
||||
}: {
|
||||
blockId: string
|
||||
outgoingEdgeId?: string
|
||||
options: GoogleSheetsGetOptions
|
||||
}
|
||||
): Promise<ExecuteIntegrationResponse> => {
|
||||
const logs: ChatLog[] = []
|
||||
const { variables } = state.typebotsQueue[0].typebot
|
||||
@@ -79,10 +84,15 @@ export const getRow = async (
|
||||
[]
|
||||
)
|
||||
if (!newVariables) return { outgoingEdgeId }
|
||||
const newSessionState = updateVariablesInSession(state)(newVariables)
|
||||
const { updatedState, newSetVariableHistory } = updateVariablesInSession({
|
||||
state,
|
||||
newVariables,
|
||||
currentBlockId: blockId,
|
||||
})
|
||||
return {
|
||||
outgoingEdgeId,
|
||||
newSessionState,
|
||||
newSessionState: updatedState,
|
||||
newSetVariableHistory,
|
||||
}
|
||||
} catch (err) {
|
||||
logs.push({
|
||||
|
||||
@@ -107,12 +107,16 @@ export const createSpeechOpenAI = async (
|
||||
mimeType: 'audio/mpeg',
|
||||
})
|
||||
|
||||
newSessionState = updateVariablesInSession(newSessionState)([
|
||||
{
|
||||
...saveUrlInVariable,
|
||||
value: url,
|
||||
},
|
||||
])
|
||||
newSessionState = updateVariablesInSession({
|
||||
newVariables: [
|
||||
{
|
||||
...saveUrlInVariable,
|
||||
value: url,
|
||||
},
|
||||
],
|
||||
state: newSessionState,
|
||||
currentBlockId: undefined,
|
||||
}).updatedState
|
||||
|
||||
return {
|
||||
startTimeShouldBeUpdated: true,
|
||||
|
||||
@@ -22,7 +22,6 @@ import {
|
||||
defaultOpenAIOptions,
|
||||
} from '@typebot.io/schemas/features/blocks/integrations/openai/constants'
|
||||
import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants'
|
||||
import { isPlaneteScale } from '@typebot.io/lib/isPlanetScale'
|
||||
|
||||
export const createChatCompletionOpenAI = async (
|
||||
state: SessionState,
|
||||
@@ -68,9 +67,11 @@ export const createChatCompletionOpenAI = async (
|
||||
typebot.variables
|
||||
)(options.messages)
|
||||
if (variablesTransformedToList.length > 0)
|
||||
newSessionState = updateVariablesInSession(state)(
|
||||
variablesTransformedToList
|
||||
)
|
||||
newSessionState = updateVariablesInSession({
|
||||
state,
|
||||
newVariables: variablesTransformedToList,
|
||||
currentBlockId: undefined,
|
||||
}).updatedState
|
||||
|
||||
const temperature = parseVariableNumber(typebot.variables)(
|
||||
options.advancedSettings?.temperature
|
||||
|
||||
@@ -42,7 +42,11 @@ export const resumeChatCompletion =
|
||||
return newVariables
|
||||
}, [])
|
||||
if (newVariables && newVariables.length > 0)
|
||||
newSessionState = updateVariablesInSession(newSessionState)(newVariables)
|
||||
newSessionState = updateVariablesInSession({
|
||||
newVariables,
|
||||
state: newSessionState,
|
||||
currentBlockId: undefined,
|
||||
}).updatedState
|
||||
return {
|
||||
outgoingEdgeId,
|
||||
newSessionState,
|
||||
|
||||
@@ -70,10 +70,15 @@ export const resumeWebhookExecution = ({
|
||||
}
|
||||
}, [])
|
||||
if (newVariables && newVariables.length > 0) {
|
||||
const newSessionState = updateVariablesInSession(state)(newVariables)
|
||||
const { updatedState, newSetVariableHistory } = updateVariablesInSession({
|
||||
newVariables,
|
||||
state,
|
||||
currentBlockId: block.id,
|
||||
})
|
||||
return {
|
||||
outgoingEdgeId: block.outgoingEdgeId,
|
||||
newSessionState,
|
||||
newSessionState: updatedState,
|
||||
newSetVariableHistory,
|
||||
logs,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ export const executeZemanticAiBlock = async (
|
||||
block: ZemanticAiBlock
|
||||
): Promise<ExecuteIntegrationResponse> => {
|
||||
let newSessionState = state
|
||||
let setVariableHistory = []
|
||||
|
||||
if (!block.options?.credentialsId)
|
||||
return {
|
||||
@@ -82,24 +83,34 @@ export const executeZemanticAiBlock = async (
|
||||
|
||||
for (const r of block.options.responseMapping || []) {
|
||||
const variable = typebot.variables.find(byId(r.variableId))
|
||||
let newVariables = []
|
||||
switch (r.valueToExtract) {
|
||||
case 'Summary':
|
||||
if (isDefined(variable) && !isEmpty(res.summary)) {
|
||||
newSessionState = updateVariablesInSession(newSessionState)([
|
||||
{ ...variable, value: res.summary },
|
||||
])
|
||||
newVariables.push({ ...variable, value: res.summary })
|
||||
}
|
||||
break
|
||||
case 'Results':
|
||||
if (isDefined(variable) && res.results.length) {
|
||||
newSessionState = updateVariablesInSession(newSessionState)([
|
||||
{ ...variable, value: JSON.stringify(res.results) },
|
||||
])
|
||||
newVariables.push({
|
||||
...variable,
|
||||
value: JSON.stringify(res.results),
|
||||
})
|
||||
}
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
if (newVariables.length > 0) {
|
||||
const { newSetVariableHistory, updatedState } =
|
||||
updateVariablesInSession({
|
||||
newVariables,
|
||||
state: newSessionState,
|
||||
currentBlockId: block.id,
|
||||
})
|
||||
newSessionState = updatedState
|
||||
setVariableHistory.push(...newSetVariableHistory)
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
@@ -112,6 +123,7 @@ export const executeZemanticAiBlock = async (
|
||||
description: 'Could not execute Zemantic AI request',
|
||||
},
|
||||
],
|
||||
newSetVariableHistory: setVariableHistory,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,201 +0,0 @@
|
||||
import { isNotDefined, isDefined } from '@typebot.io/lib'
|
||||
import { Comparison, Condition, Variable } from '@typebot.io/schemas'
|
||||
import { findUniqueVariableValue } from '@typebot.io/variables/findUniqueVariableValue'
|
||||
import { parseVariables } from '@typebot.io/variables/parseVariables'
|
||||
import {
|
||||
LogicalOperator,
|
||||
ComparisonOperators,
|
||||
defaultConditionItemContent,
|
||||
} from '@typebot.io/schemas/features/blocks/logic/condition/constants'
|
||||
|
||||
export const executeCondition =
|
||||
(variables: Variable[]) =>
|
||||
(condition: Condition): boolean => {
|
||||
if (!condition.comparisons) return false
|
||||
return (condition.logicalOperator ??
|
||||
defaultConditionItemContent.logicalOperator) === LogicalOperator.AND
|
||||
? condition.comparisons.every(executeComparison(variables))
|
||||
: condition.comparisons.some(executeComparison(variables))
|
||||
}
|
||||
|
||||
const executeComparison =
|
||||
(variables: Variable[]) =>
|
||||
(comparison: Comparison): boolean => {
|
||||
if (!comparison?.variableId) return false
|
||||
const inputValue =
|
||||
variables.find((v) => v.id === comparison.variableId)?.value ?? null
|
||||
const value =
|
||||
comparison.value === 'undefined' || comparison.value === 'null'
|
||||
? null
|
||||
: findUniqueVariableValue(variables)(comparison.value) ??
|
||||
parseVariables(variables)(comparison.value)
|
||||
if (isNotDefined(comparison.comparisonOperator)) return false
|
||||
switch (comparison.comparisonOperator) {
|
||||
case ComparisonOperators.CONTAINS: {
|
||||
if (Array.isArray(inputValue)) {
|
||||
const equal = (a: string | null, b: string | null) => {
|
||||
if (typeof a === 'string' && typeof b === 'string')
|
||||
return a.normalize() === b.normalize()
|
||||
return a !== b
|
||||
}
|
||||
return compare(equal, inputValue, value, 'some')
|
||||
}
|
||||
const contains = (a: string | null, b: string | null) => {
|
||||
if (b === '' || !b || !a) return false
|
||||
return a
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.normalize()
|
||||
.includes(b.toLowerCase().trim().normalize())
|
||||
}
|
||||
return compare(contains, inputValue, value, 'some')
|
||||
}
|
||||
case ComparisonOperators.NOT_CONTAINS: {
|
||||
if (Array.isArray(inputValue)) {
|
||||
const notEqual = (a: string | null, b: string | null) => {
|
||||
if (typeof a === 'string' && typeof b === 'string')
|
||||
return a.normalize() !== b.normalize()
|
||||
return a !== b
|
||||
}
|
||||
return compare(notEqual, inputValue, value)
|
||||
}
|
||||
const notContains = (a: string | null, b: string | null) => {
|
||||
if (b === '' || !b || !a) return true
|
||||
return !a
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.normalize()
|
||||
.includes(b.toLowerCase().trim().normalize())
|
||||
}
|
||||
return compare(notContains, inputValue, value)
|
||||
}
|
||||
case ComparisonOperators.EQUAL: {
|
||||
return compare(
|
||||
(a, b) => {
|
||||
if (typeof a === 'string' && typeof b === 'string')
|
||||
return a.normalize() === b.normalize()
|
||||
return a === b
|
||||
},
|
||||
inputValue,
|
||||
value
|
||||
)
|
||||
}
|
||||
case ComparisonOperators.NOT_EQUAL: {
|
||||
return compare(
|
||||
(a, b) => {
|
||||
if (typeof a === 'string' && typeof b === 'string')
|
||||
return a.normalize() !== b.normalize()
|
||||
return a !== b
|
||||
},
|
||||
inputValue,
|
||||
value
|
||||
)
|
||||
}
|
||||
case ComparisonOperators.GREATER: {
|
||||
if (isNotDefined(inputValue) || isNotDefined(value)) return false
|
||||
if (typeof inputValue === 'string') {
|
||||
if (typeof value === 'string')
|
||||
return parseDateOrNumber(inputValue) > parseDateOrNumber(value)
|
||||
return Number(inputValue) > value.length
|
||||
}
|
||||
if (typeof value === 'string') return inputValue.length > Number(value)
|
||||
return inputValue.length > value.length
|
||||
}
|
||||
case ComparisonOperators.LESS: {
|
||||
if (isNotDefined(inputValue) || isNotDefined(value)) return false
|
||||
if (typeof inputValue === 'string') {
|
||||
if (typeof value === 'string')
|
||||
return parseDateOrNumber(inputValue) < parseDateOrNumber(value)
|
||||
return Number(inputValue) < value.length
|
||||
}
|
||||
if (typeof value === 'string') return inputValue.length < Number(value)
|
||||
return inputValue.length < value.length
|
||||
}
|
||||
case ComparisonOperators.IS_SET: {
|
||||
return isDefined(inputValue) && inputValue.length > 0
|
||||
}
|
||||
case ComparisonOperators.IS_EMPTY: {
|
||||
return isNotDefined(inputValue) || inputValue.length === 0
|
||||
}
|
||||
case ComparisonOperators.STARTS_WITH: {
|
||||
const startsWith = (a: string | null, b: string | null) => {
|
||||
if (b === '' || !b || !a) return false
|
||||
return a
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.normalize()
|
||||
.startsWith(b.toLowerCase().trim().normalize())
|
||||
}
|
||||
return compare(startsWith, inputValue, value)
|
||||
}
|
||||
case ComparisonOperators.ENDS_WITH: {
|
||||
const endsWith = (a: string | null, b: string | null) => {
|
||||
if (b === '' || !b || !a) return false
|
||||
return a
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.normalize()
|
||||
.endsWith(b.toLowerCase().trim().normalize())
|
||||
}
|
||||
return compare(endsWith, inputValue, value)
|
||||
}
|
||||
case ComparisonOperators.MATCHES_REGEX: {
|
||||
const matchesRegex = (a: string | null, b: string | null) => {
|
||||
if (b === '' || !b || !a) return false
|
||||
const regex = preprocessRegex(b)
|
||||
if (!regex) return false
|
||||
return new RegExp(regex.pattern, regex.flags).test(a)
|
||||
}
|
||||
return compare(matchesRegex, inputValue, value, 'some')
|
||||
}
|
||||
case ComparisonOperators.NOT_MATCH_REGEX: {
|
||||
const matchesRegex = (a: string | null, b: string | null) => {
|
||||
if (b === '' || !b || !a) return false
|
||||
const regex = preprocessRegex(b)
|
||||
if (!regex) return true
|
||||
return !new RegExp(regex.pattern, regex.flags).test(a)
|
||||
}
|
||||
return compare(matchesRegex, inputValue, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const compare = (
|
||||
compareStrings: (a: string | null, b: string | null) => boolean,
|
||||
a: Exclude<Variable['value'], undefined>,
|
||||
b: Exclude<Variable['value'], undefined>,
|
||||
type: 'every' | 'some' = 'every'
|
||||
): boolean => {
|
||||
if (!a || typeof a === 'string') {
|
||||
if (!b || typeof b === 'string') return compareStrings(a, b)
|
||||
return type === 'every'
|
||||
? b.every((b) => compareStrings(a, b))
|
||||
: b.some((b) => compareStrings(a, b))
|
||||
}
|
||||
if (!b || typeof b === 'string') {
|
||||
return type === 'every'
|
||||
? a.every((a) => compareStrings(a, b))
|
||||
: a.some((a) => compareStrings(a, b))
|
||||
}
|
||||
if (type === 'every')
|
||||
return a.every((a) => b.every((b) => compareStrings(a, b)))
|
||||
return a.some((a) => b.some((b) => compareStrings(a, b)))
|
||||
}
|
||||
|
||||
const parseDateOrNumber = (value: string): number => {
|
||||
const parsed = Number(value)
|
||||
if (isNaN(parsed)) {
|
||||
const time = Date.parse(value)
|
||||
return time
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
|
||||
const preprocessRegex = (regex: string) => {
|
||||
const regexWithFlags = regex.match(/\/(.+)\/([gimuy]*)$/)
|
||||
|
||||
if (regexWithFlags)
|
||||
return { pattern: regexWithFlags[1], flags: regexWithFlags[2] }
|
||||
|
||||
return { pattern: regex }
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
import { ConditionBlock, SessionState } from '@typebot.io/schemas'
|
||||
import { ExecuteLogicResponse } from '../../../types'
|
||||
import { executeCondition } from './executeCondition'
|
||||
|
||||
import { executeCondition } from '@typebot.io/logic/executeCondition'
|
||||
export const executeConditionBlock = (
|
||||
state: SessionState,
|
||||
block: ConditionBlock
|
||||
): ExecuteLogicResponse => {
|
||||
const { variables } = state.typebotsQueue[0].typebot
|
||||
const passedCondition = block.items.find(
|
||||
(item) => item.content && executeCondition(variables)(item.content)
|
||||
(item) =>
|
||||
item.content && executeCondition({ variables, condition: item.content })
|
||||
)
|
||||
return {
|
||||
outgoingEdgeId: passedCondition
|
||||
|
||||
@@ -24,14 +24,25 @@ export const executeScript = async (
|
||||
body: block.options.content,
|
||||
})
|
||||
|
||||
const newSessionState = newVariables
|
||||
? updateVariablesInSession(state)(newVariables)
|
||||
: state
|
||||
const updateVarResults = newVariables
|
||||
? updateVariablesInSession({
|
||||
newVariables,
|
||||
state,
|
||||
currentBlockId: block.id,
|
||||
})
|
||||
: undefined
|
||||
|
||||
let newSessionState = state
|
||||
|
||||
if (updateVarResults) {
|
||||
newSessionState = updateVarResults.updatedState
|
||||
}
|
||||
|
||||
return {
|
||||
outgoingEdgeId: block.outgoingEdgeId,
|
||||
logs: error ? [{ status: 'error', description: error }] : [],
|
||||
newSessionState,
|
||||
newSetVariableHistory: updateVarResults?.newSetVariableHistory,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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