♻️ Export bot-engine code into its own package
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
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 true
|
||||
})
|
||||
return {
|
||||
...block,
|
||||
items: filteredItems,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import {
|
||||
SessionState,
|
||||
VariableWithValue,
|
||||
ChoiceInputBlock,
|
||||
ItemType,
|
||||
} from '@typebot.io/schemas'
|
||||
import { isDefined } from '@typebot.io/lib'
|
||||
import { filterChoiceItems } from './filterChoiceItems'
|
||||
import { deepParseVariables } from '../../../variables/deepParseVariables'
|
||||
import { transformStringVariablesToList } from '../../../variables/transformVariablesToList'
|
||||
import { updateVariablesInSession } from '../../../variables/updateVariablesInSession'
|
||||
|
||||
export const injectVariableValuesInButtonsInputBlock =
|
||||
(state: SessionState) =>
|
||||
(block: ChoiceInputBlock): ChoiceInputBlock => {
|
||||
const { variables } = state.typebotsQueue[0].typebot
|
||||
if (block.options.dynamicVariableId) {
|
||||
const variable = variables.find(
|
||||
(variable) =>
|
||||
variable.id === block.options.dynamicVariableId &&
|
||||
isDefined(variable.value)
|
||||
) as VariableWithValue | undefined
|
||||
if (!variable) return block
|
||||
const value = getVariableValue(state)(variable)
|
||||
return {
|
||||
...block,
|
||||
items: value.filter(isDefined).map((item, idx) => ({
|
||||
id: idx.toString(),
|
||||
type: ItemType.BUTTON,
|
||||
blockId: block.id,
|
||||
content: item,
|
||||
})),
|
||||
}
|
||||
}
|
||||
return deepParseVariables(variables)(filterChoiceItems(variables)(block))
|
||||
}
|
||||
|
||||
const getVariableValue =
|
||||
(state: SessionState) =>
|
||||
(variable: VariableWithValue): (string | null)[] => {
|
||||
if (!Array.isArray(variable.value)) {
|
||||
const { variables } = state.typebotsQueue[0].typebot
|
||||
const [transformedVariable] = transformStringVariablesToList(variables)([
|
||||
variable.id,
|
||||
])
|
||||
updateVariablesInSession(state)([transformedVariable])
|
||||
return transformedVariable.value as string[]
|
||||
}
|
||||
return variable.value
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import { ChoiceInputBlock, SessionState } from '@typebot.io/schemas'
|
||||
import { injectVariableValuesInButtonsInputBlock } from './injectVariableValuesInButtonsInputBlock'
|
||||
import { ParsedReply } from '../../../types'
|
||||
|
||||
export const parseButtonsReply =
|
||||
(state: SessionState) =>
|
||||
(inputValue: string, block: ChoiceInputBlock): ParsedReply => {
|
||||
const displayedItems =
|
||||
injectVariableValuesInButtonsInputBlock(state)(block).items
|
||||
if (block.options.isMultipleChoice) {
|
||||
const longestItemsFirst = [...displayedItems].sort(
|
||||
(a, b) => (b.content?.length ?? 0) - (a.content?.length ?? 0)
|
||||
)
|
||||
const matchedItemsByContent = longestItemsFirst.reduce<{
|
||||
strippedInput: string
|
||||
matchedItemIds: string[]
|
||||
}>(
|
||||
(acc, item) => {
|
||||
if (
|
||||
item.content &&
|
||||
acc.strippedInput.toLowerCase().includes(item.content.toLowerCase())
|
||||
)
|
||||
return {
|
||||
strippedInput: acc.strippedInput.replace(item.content ?? '', ''),
|
||||
matchedItemIds: [...acc.matchedItemIds, item.id],
|
||||
}
|
||||
return acc
|
||||
},
|
||||
{
|
||||
strippedInput: inputValue.trim(),
|
||||
matchedItemIds: [],
|
||||
}
|
||||
)
|
||||
const remainingItems = displayedItems.filter(
|
||||
(item) => !matchedItemsByContent.matchedItemIds.includes(item.id)
|
||||
)
|
||||
const matchedItemsByIndex = remainingItems.reduce<{
|
||||
strippedInput: string
|
||||
matchedItemIds: string[]
|
||||
}>(
|
||||
(acc, item, idx) => {
|
||||
if (acc.strippedInput.includes(`${idx + 1}`))
|
||||
return {
|
||||
strippedInput: acc.strippedInput.replace(`${idx + 1}`, ''),
|
||||
matchedItemIds: [...acc.matchedItemIds, item.id],
|
||||
}
|
||||
return acc
|
||||
},
|
||||
{
|
||||
strippedInput: matchedItemsByContent.strippedInput,
|
||||
matchedItemIds: [],
|
||||
}
|
||||
)
|
||||
const matchedItems = displayedItems.filter((item) =>
|
||||
[
|
||||
...matchedItemsByContent.matchedItemIds,
|
||||
...matchedItemsByIndex.matchedItemIds,
|
||||
].includes(item.id)
|
||||
)
|
||||
if (matchedItems.length === 0) return { status: 'fail' }
|
||||
return {
|
||||
status: 'success',
|
||||
reply: matchedItems.map((item) => item.content).join(', '),
|
||||
}
|
||||
}
|
||||
if (state.whatsApp) {
|
||||
const matchedItem = displayedItems.find((item) => item.id === inputValue)
|
||||
if (!matchedItem) return { status: 'fail' }
|
||||
return {
|
||||
status: 'success',
|
||||
reply: matchedItem.content ?? '',
|
||||
}
|
||||
}
|
||||
const longestItemsFirst = [...displayedItems].sort(
|
||||
(a, b) => (b.content?.length ?? 0) - (a.content?.length ?? 0)
|
||||
)
|
||||
const matchedItem = longestItemsFirst.find(
|
||||
(item) =>
|
||||
item.content &&
|
||||
inputValue.toLowerCase().trim() === item.content.toLowerCase().trim()
|
||||
)
|
||||
if (!matchedItem) return { status: 'fail' }
|
||||
return {
|
||||
status: 'success',
|
||||
reply: matchedItem.content ?? '',
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user