⚡ (webhook) Add client execution option
This commit is contained in:
@@ -71,8 +71,7 @@ if (window.$chatwoot) {
|
||||
|
||||
export const executeChatwootBlock = (
|
||||
{ typebot, result }: SessionState,
|
||||
block: ChatwootBlock,
|
||||
lastBubbleBlockId?: string
|
||||
block: ChatwootBlock
|
||||
): ExecuteIntegrationResponse => {
|
||||
const chatwootCode =
|
||||
block.options.task === 'Close widget'
|
||||
@@ -88,7 +87,6 @@ export const executeChatwootBlock = (
|
||||
outgoingEdgeId: block.outgoingEdgeId,
|
||||
clientSideActions: [
|
||||
{
|
||||
lastBubbleBlockId,
|
||||
chatwoot: {
|
||||
scriptToExecute: {
|
||||
content: parseVariables(typebot.variables, { fieldToParse: 'id' })(
|
||||
|
||||
@@ -5,8 +5,7 @@ import { GoogleAnalyticsBlock, SessionState } from '@typebot.io/schemas'
|
||||
|
||||
export const executeGoogleAnalyticsBlock = (
|
||||
{ typebot: { variables } }: SessionState,
|
||||
block: GoogleAnalyticsBlock,
|
||||
lastBubbleBlockId?: string
|
||||
block: GoogleAnalyticsBlock
|
||||
): ExecuteIntegrationResponse => {
|
||||
const googleAnalytics = deepParseVariables(variables)(block.options)
|
||||
return {
|
||||
@@ -19,7 +18,6 @@ export const executeGoogleAnalyticsBlock = (
|
||||
? Number(googleAnalytics.value)
|
||||
: undefined,
|
||||
},
|
||||
lastBubbleBlockId,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
ZapierBlock,
|
||||
MakeComBlock,
|
||||
PabblyConnectBlock,
|
||||
VariableWithUnknowValue,
|
||||
SessionState,
|
||||
Webhook,
|
||||
Typebot,
|
||||
@@ -17,17 +16,23 @@ import {
|
||||
KeyValue,
|
||||
ReplyLog,
|
||||
ResultInSession,
|
||||
ExecutableWebhook,
|
||||
} from '@typebot.io/schemas'
|
||||
import { stringify } from 'qs'
|
||||
import { byId, omit } from '@typebot.io/lib'
|
||||
import { omit } from '@typebot.io/lib'
|
||||
import { parseAnswers } from '@typebot.io/lib/results'
|
||||
import got, { Method, Headers, HTTPError } from 'got'
|
||||
import got, { Method, HTTPError, OptionsInit } from 'got'
|
||||
import { parseSampleResult } from './parseSampleResult'
|
||||
import { ExecuteIntegrationResponse } from '@/features/chat/types'
|
||||
import { saveErrorLog } from '@/features/logs/saveErrorLog'
|
||||
import { saveSuccessLog } from '@/features/logs/saveSuccessLog'
|
||||
import { updateVariables } from '@/features/variables/updateVariables'
|
||||
import { parseVariables } from '@/features/variables/parseVariables'
|
||||
import { resumeWebhookExecution } from './resumeWebhookExecution'
|
||||
|
||||
type ParsedWebhook = ExecutableWebhook & {
|
||||
basicAuth: { username?: string; password?: string }
|
||||
isJson: boolean
|
||||
}
|
||||
|
||||
export const executeWebhookBlock = async (
|
||||
state: SessionState,
|
||||
@@ -51,70 +56,34 @@ export const executeWebhookBlock = async (
|
||||
return { outgoingEdgeId: block.outgoingEdgeId, logs: [log] }
|
||||
}
|
||||
const preparedWebhook = prepareWebhookAttributes(webhook, block.options)
|
||||
const webhookResponse = await executeWebhook({ typebot })(
|
||||
preparedWebhook,
|
||||
typebot.variables,
|
||||
const parsedWebhook = await parseWebhookAttributes(
|
||||
typebot,
|
||||
block.groupId,
|
||||
result
|
||||
)
|
||||
const status = webhookResponse.statusCode.toString()
|
||||
const isError = status.startsWith('4') || status.startsWith('5')
|
||||
|
||||
if (isError) {
|
||||
)(preparedWebhook)
|
||||
if (!parsedWebhook) {
|
||||
log = {
|
||||
status: 'error',
|
||||
description: `Webhook returned error: ${webhookResponse.data}`,
|
||||
details: JSON.stringify(webhookResponse.data, null, 2).substring(0, 1000),
|
||||
description: `Couldn't parse webhook attributes`,
|
||||
}
|
||||
result &&
|
||||
(await saveErrorLog({
|
||||
resultId: result.id,
|
||||
message: log.description,
|
||||
details: log.details,
|
||||
}))
|
||||
} else {
|
||||
log = {
|
||||
status: 'success',
|
||||
description: `Webhook executed successfully!`,
|
||||
details: JSON.stringify(webhookResponse.data, null, 2).substring(0, 1000),
|
||||
}
|
||||
result &&
|
||||
(await saveSuccessLog({
|
||||
resultId: result.id,
|
||||
message: log.description,
|
||||
details: JSON.stringify(webhookResponse.data, null, 2).substring(
|
||||
0,
|
||||
1000
|
||||
),
|
||||
}))
|
||||
return { outgoingEdgeId: block.outgoingEdgeId, logs: [log] }
|
||||
}
|
||||
|
||||
const newVariables = block.options.responseVariableMapping.reduce<
|
||||
VariableWithUnknowValue[]
|
||||
>((newVariables, varMapping) => {
|
||||
if (!varMapping?.bodyPath || !varMapping.variableId) return newVariables
|
||||
const existingVariable = typebot.variables.find(byId(varMapping.variableId))
|
||||
if (!existingVariable) return newVariables
|
||||
const func = Function(
|
||||
'data',
|
||||
`return data.${parseVariables(typebot.variables)(varMapping?.bodyPath)}`
|
||||
)
|
||||
try {
|
||||
const value: unknown = func(webhookResponse)
|
||||
return [...newVariables, { ...existingVariable, value }]
|
||||
} catch (err) {
|
||||
return newVariables
|
||||
}
|
||||
}, [])
|
||||
if (newVariables.length > 0) {
|
||||
const newSessionState = await updateVariables(state)(newVariables)
|
||||
if (block.options.isExecutedOnClient)
|
||||
return {
|
||||
outgoingEdgeId: block.outgoingEdgeId,
|
||||
newSessionState,
|
||||
clientSideActions: [
|
||||
{
|
||||
webhookToExecute: parsedWebhook,
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
return { outgoingEdgeId: block.outgoingEdgeId, logs: log ? [log] : undefined }
|
||||
const webhookResponse = await executeWebhook(parsedWebhook, result)
|
||||
return resumeWebhookExecution(state, block)(webhookResponse)
|
||||
}
|
||||
|
||||
const prepareWebhookAttributes = (
|
||||
@@ -131,19 +100,15 @@ const prepareWebhookAttributes = (
|
||||
|
||||
const checkIfBodyIsAVariable = (body: string) => /^{{.+}}$/.test(body)
|
||||
|
||||
export const executeWebhook =
|
||||
({ typebot }: Pick<SessionState, 'typebot'>) =>
|
||||
async (
|
||||
webhook: Webhook,
|
||||
variables: Variable[],
|
||||
const parseWebhookAttributes =
|
||||
(
|
||||
typebot: SessionState['typebot'],
|
||||
groupId: string,
|
||||
result: ResultInSession
|
||||
): Promise<WebhookResponse> => {
|
||||
if (!webhook.url || !webhook.method)
|
||||
return {
|
||||
statusCode: 400,
|
||||
data: { message: `Webhook doesn't have url or method` },
|
||||
}
|
||||
) =>
|
||||
async (webhook: Webhook): Promise<ParsedWebhook | undefined> => {
|
||||
if (!webhook.url || !webhook.method) return
|
||||
const { variables } = typebot
|
||||
const basicAuth: { username?: string; password?: string } = {}
|
||||
const basicAuthHeaderIdx = webhook.headers.findIndex(
|
||||
(h) =>
|
||||
@@ -161,13 +126,11 @@ export const executeWebhook =
|
||||
webhook.headers.splice(basicAuthHeaderIdx, 1)
|
||||
}
|
||||
const headers = convertKeyValueTableToObject(webhook.headers, variables) as
|
||||
| Headers
|
||||
| ExecutableWebhook['headers']
|
||||
| undefined
|
||||
const queryParams = stringify(
|
||||
convertKeyValueTableToObject(webhook.queryParams, variables)
|
||||
)
|
||||
const contentType = headers ? headers['Content-Type'] : undefined
|
||||
|
||||
const bodyContent = await getBodyContent(
|
||||
typebot,
|
||||
[]
|
||||
@@ -186,62 +149,62 @@ export const executeWebhook =
|
||||
)
|
||||
: { data: undefined, isJson: false }
|
||||
|
||||
const request = {
|
||||
return {
|
||||
url: parseVariables(variables)(
|
||||
webhook.url + (queryParams !== '' ? `?${queryParams}` : '')
|
||||
),
|
||||
method: webhook.method as Method,
|
||||
basicAuth,
|
||||
method: webhook.method,
|
||||
headers,
|
||||
...basicAuth,
|
||||
json:
|
||||
!contentType?.includes('x-www-form-urlencoded') && body && isJson
|
||||
? body
|
||||
: undefined,
|
||||
form:
|
||||
contentType?.includes('x-www-form-urlencoded') && body
|
||||
? body
|
||||
: undefined,
|
||||
body: body && !isJson ? body : undefined,
|
||||
body,
|
||||
isJson,
|
||||
}
|
||||
try {
|
||||
const response = await got(request.url, omit(request, 'url'))
|
||||
await saveSuccessLog({
|
||||
resultId: result.id,
|
||||
message: 'Webhook successfuly executed.',
|
||||
details: {
|
||||
statusCode: response.statusCode,
|
||||
request,
|
||||
response: safeJsonParse(response.body).data,
|
||||
},
|
||||
})
|
||||
return {
|
||||
}
|
||||
|
||||
export const executeWebhook = async (
|
||||
webhook: ParsedWebhook,
|
||||
result: ResultInSession
|
||||
): Promise<WebhookResponse> => {
|
||||
const { headers, url, method, basicAuth, body, isJson } = webhook
|
||||
const contentType = headers ? headers['Content-Type'] : undefined
|
||||
|
||||
const request = {
|
||||
url,
|
||||
method: method as Method,
|
||||
headers,
|
||||
...(basicAuth ?? {}),
|
||||
json:
|
||||
!contentType?.includes('x-www-form-urlencoded') && body && isJson
|
||||
? body
|
||||
: undefined,
|
||||
form:
|
||||
contentType?.includes('x-www-form-urlencoded') && body ? body : undefined,
|
||||
body: body && !isJson ? (body as string) : undefined,
|
||||
} satisfies OptionsInit
|
||||
try {
|
||||
const response = await got(request.url, omit(request, 'url'))
|
||||
await saveSuccessLog({
|
||||
resultId: result.id,
|
||||
message: 'Webhook successfuly executed.',
|
||||
details: {
|
||||
statusCode: response.statusCode,
|
||||
data: safeJsonParse(response.body).data,
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof HTTPError) {
|
||||
const response = {
|
||||
statusCode: error.response.statusCode,
|
||||
data: safeJsonParse(error.response.body as string).data,
|
||||
}
|
||||
await saveErrorLog({
|
||||
resultId: result.id,
|
||||
message: 'Webhook returned an error',
|
||||
details: {
|
||||
request,
|
||||
response,
|
||||
},
|
||||
})
|
||||
return response
|
||||
}
|
||||
request,
|
||||
response: safeJsonParse(response.body).data,
|
||||
},
|
||||
})
|
||||
return {
|
||||
statusCode: response.statusCode,
|
||||
data: safeJsonParse(response.body).data,
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof HTTPError) {
|
||||
const response = {
|
||||
statusCode: 500,
|
||||
data: { message: `Error from Typebot server: ${error}` },
|
||||
statusCode: error.response.statusCode,
|
||||
data: safeJsonParse(error.response.body as string).data,
|
||||
}
|
||||
console.error(error)
|
||||
await saveErrorLog({
|
||||
resultId: result.id,
|
||||
message: 'Webhook failed to execute',
|
||||
message: 'Webhook returned an error',
|
||||
details: {
|
||||
request,
|
||||
response,
|
||||
@@ -249,7 +212,22 @@ export const executeWebhook =
|
||||
})
|
||||
return response
|
||||
}
|
||||
const response = {
|
||||
statusCode: 500,
|
||||
data: { message: `Error from Typebot server: ${error}` },
|
||||
}
|
||||
console.error(error)
|
||||
await saveErrorLog({
|
||||
resultId: result.id,
|
||||
message: 'Webhook failed to execute',
|
||||
details: {
|
||||
request,
|
||||
response,
|
||||
},
|
||||
})
|
||||
return response
|
||||
}
|
||||
}
|
||||
|
||||
const getBodyContent =
|
||||
(
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
import { ExecuteIntegrationResponse } from '@/features/chat/types'
|
||||
import { saveErrorLog } from '@/features/logs/saveErrorLog'
|
||||
import { saveSuccessLog } from '@/features/logs/saveSuccessLog'
|
||||
import { parseVariables } from '@/features/variables/parseVariables'
|
||||
import { updateVariables } from '@/features/variables/updateVariables'
|
||||
import { byId } from '@typebot.io/lib'
|
||||
import {
|
||||
MakeComBlock,
|
||||
PabblyConnectBlock,
|
||||
VariableWithUnknowValue,
|
||||
WebhookBlock,
|
||||
ZapierBlock,
|
||||
} from '@typebot.io/schemas'
|
||||
import { ReplyLog, SessionState } from '@typebot.io/schemas/features/chat'
|
||||
|
||||
export const resumeWebhookExecution =
|
||||
(
|
||||
state: SessionState,
|
||||
block: WebhookBlock | ZapierBlock | MakeComBlock | PabblyConnectBlock
|
||||
) =>
|
||||
async (response: {
|
||||
statusCode: number
|
||||
data?: unknown
|
||||
}): Promise<ExecuteIntegrationResponse> => {
|
||||
const { typebot, result } = state
|
||||
let log: ReplyLog | undefined
|
||||
const status = response.statusCode.toString()
|
||||
const isError = status.startsWith('4') || status.startsWith('5')
|
||||
|
||||
if (isError) {
|
||||
log = {
|
||||
status: 'error',
|
||||
description: `Webhook returned error: ${response.data}`,
|
||||
details: JSON.stringify(response.data, null, 2).substring(0, 1000),
|
||||
}
|
||||
result &&
|
||||
(await saveErrorLog({
|
||||
resultId: result.id,
|
||||
message: log.description,
|
||||
details: log.details,
|
||||
}))
|
||||
} else {
|
||||
log = {
|
||||
status: 'success',
|
||||
description: `Webhook executed successfully!`,
|
||||
details: JSON.stringify(response.data, null, 2).substring(0, 1000),
|
||||
}
|
||||
result &&
|
||||
(await saveSuccessLog({
|
||||
resultId: result.id,
|
||||
message: log.description,
|
||||
details: JSON.stringify(response.data, null, 2).substring(0, 1000),
|
||||
}))
|
||||
}
|
||||
|
||||
const newVariables = block.options.responseVariableMapping.reduce<
|
||||
VariableWithUnknowValue[]
|
||||
>((newVariables, varMapping) => {
|
||||
if (!varMapping?.bodyPath || !varMapping.variableId) return newVariables
|
||||
const existingVariable = typebot.variables.find(
|
||||
byId(varMapping.variableId)
|
||||
)
|
||||
if (!existingVariable) return newVariables
|
||||
const func = Function(
|
||||
'data',
|
||||
`return data.${parseVariables(typebot.variables)(varMapping?.bodyPath)}`
|
||||
)
|
||||
try {
|
||||
const value: unknown = func(response)
|
||||
return [...newVariables, { ...existingVariable, value }]
|
||||
} catch (err) {
|
||||
return newVariables
|
||||
}
|
||||
}, [])
|
||||
if (newVariables.length > 0) {
|
||||
const newSessionState = await updateVariables(state)(newVariables)
|
||||
return {
|
||||
outgoingEdgeId: block.outgoingEdgeId,
|
||||
newSessionState,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
outgoingEdgeId: block.outgoingEdgeId,
|
||||
logs: log ? [log] : undefined,
|
||||
}
|
||||
}
|
||||
@@ -5,15 +5,13 @@ import { ExecuteLogicResponse } from '@/features/chat/types'
|
||||
|
||||
export const executeRedirect = (
|
||||
{ typebot: { variables } }: SessionState,
|
||||
block: RedirectBlock,
|
||||
lastBubbleBlockId?: string
|
||||
block: RedirectBlock
|
||||
): ExecuteLogicResponse => {
|
||||
if (!block.options?.url) return { outgoingEdgeId: block.outgoingEdgeId }
|
||||
const formattedUrl = sanitizeUrl(parseVariables(variables)(block.options.url))
|
||||
return {
|
||||
clientSideActions: [
|
||||
{
|
||||
lastBubbleBlockId,
|
||||
redirect: { url: formattedUrl, isNewTab: block.options.isNewTab },
|
||||
},
|
||||
],
|
||||
|
||||
@@ -6,8 +6,7 @@ import { ScriptBlock, SessionState, Variable } from '@typebot.io/schemas'
|
||||
|
||||
export const executeScript = (
|
||||
{ typebot: { variables } }: SessionState,
|
||||
block: ScriptBlock,
|
||||
lastBubbleBlockId?: string
|
||||
block: ScriptBlock
|
||||
): ExecuteLogicResponse => {
|
||||
if (!block.options.content) return { outgoingEdgeId: block.outgoingEdgeId }
|
||||
|
||||
@@ -21,7 +20,6 @@ export const executeScript = (
|
||||
clientSideActions: [
|
||||
{
|
||||
scriptToExecute: scriptToExecute,
|
||||
lastBubbleBlockId,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
@@ -8,8 +8,7 @@ import { parseScriptToExecuteClientSideAction } from '../script/executeScript'
|
||||
|
||||
export const executeSetVariable = async (
|
||||
state: SessionState,
|
||||
block: SetVariableBlock,
|
||||
lastBubbleBlockId?: string
|
||||
block: SetVariableBlock
|
||||
): Promise<ExecuteLogicResponse> => {
|
||||
const { variables } = state.typebot
|
||||
if (!block.options?.variableId)
|
||||
@@ -28,7 +27,6 @@ export const executeSetVariable = async (
|
||||
setVariable: {
|
||||
scriptToExecute,
|
||||
},
|
||||
lastBubbleBlockId,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
@@ -4,8 +4,7 @@ import { SessionState, WaitBlock } from '@typebot.io/schemas'
|
||||
|
||||
export const executeWait = async (
|
||||
{ typebot: { variables } }: SessionState,
|
||||
block: WaitBlock,
|
||||
lastBubbleBlockId?: string
|
||||
block: WaitBlock
|
||||
): Promise<ExecuteLogicResponse> => {
|
||||
if (!block.options.secondsToWaitFor)
|
||||
return { outgoingEdgeId: block.outgoingEdgeId }
|
||||
@@ -19,7 +18,6 @@ export const executeWait = async (
|
||||
? [
|
||||
{
|
||||
wait: { secondsToWaitFor: parsedSecondsToWaitFor },
|
||||
lastBubbleBlockId,
|
||||
},
|
||||
]
|
||||
: undefined,
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
ResultInSession,
|
||||
SessionState,
|
||||
SetVariableBlock,
|
||||
WebhookBlock,
|
||||
} from '@typebot.io/schemas'
|
||||
import { isInputBlock, isNotDefined, byId, isDefined } from '@typebot.io/lib'
|
||||
import { executeGroup } from './executeGroup'
|
||||
@@ -26,6 +27,7 @@ import { updateVariables } from '@/features/variables/updateVariables'
|
||||
import { parseVariables } from '@/features/variables/parseVariables'
|
||||
import { OpenAIBlock } from '@typebot.io/schemas/features/blocks/integrations/openai'
|
||||
import { resumeChatCompletion } from '@/features/blocks/integrations/openai/resumeChatCompletion'
|
||||
import { resumeWebhookExecution } from '@/features/blocks/integrations/webhook/resumeWebhookExecution'
|
||||
|
||||
export const continueBotFlow =
|
||||
(state: SessionState) =>
|
||||
@@ -60,6 +62,12 @@ export const continueBotFlow =
|
||||
}
|
||||
newSessionState = await updateVariables(state)([newVariable])
|
||||
}
|
||||
} else if (reply && block.type === IntegrationBlockType.WEBHOOK) {
|
||||
const result = await resumeWebhookExecution(
|
||||
state,
|
||||
block
|
||||
)(JSON.parse(reply))
|
||||
if (result.newSessionState) newSessionState = result.newSessionState
|
||||
} else if (
|
||||
isDefined(reply) &&
|
||||
block.type === IntegrationBlockType.OPEN_AI &&
|
||||
@@ -250,7 +258,7 @@ const computeStorageUsed = async (reply: string) => {
|
||||
const getOutgoingEdgeId =
|
||||
({ typebot: { variables } }: Pick<SessionState, 'typebot'>) =>
|
||||
(
|
||||
block: InputBlock | SetVariableBlock | OpenAIBlock,
|
||||
block: InputBlock | SetVariableBlock | OpenAIBlock | WebhookBlock,
|
||||
reply: string | null
|
||||
) => {
|
||||
if (
|
||||
|
||||
@@ -67,9 +67,9 @@ export const executeGroup =
|
||||
logs,
|
||||
}
|
||||
const executionResponse = isLogicBlock(block)
|
||||
? await executeLogic(newSessionState, lastBubbleBlockId)(block)
|
||||
? await executeLogic(newSessionState)(block)
|
||||
: isIntegrationBlock(block)
|
||||
? await executeIntegration(newSessionState, lastBubbleBlockId)(block)
|
||||
? await executeIntegration(newSessionState)(block)
|
||||
: null
|
||||
|
||||
if (!executionResponse) continue
|
||||
@@ -83,12 +83,17 @@ export const executeGroup =
|
||||
) {
|
||||
clientSideActions = [
|
||||
...(clientSideActions ?? []),
|
||||
...executionResponse.clientSideActions,
|
||||
...executionResponse.clientSideActions.map((action) => ({
|
||||
...action,
|
||||
lastBubbleBlockId,
|
||||
})),
|
||||
]
|
||||
if (
|
||||
executionResponse.clientSideActions?.find(
|
||||
(action) =>
|
||||
'setVariable' in action || 'streamOpenAiChatCompletion' in action
|
||||
'setVariable' in action ||
|
||||
'streamOpenAiChatCompletion' in action ||
|
||||
'webhookToExecute' in action
|
||||
)
|
||||
) {
|
||||
return {
|
||||
|
||||
@@ -12,15 +12,15 @@ import {
|
||||
import { ExecuteIntegrationResponse } from '../types'
|
||||
|
||||
export const executeIntegration =
|
||||
(state: SessionState, lastBubbleBlockId?: string) =>
|
||||
(state: SessionState) =>
|
||||
async (block: IntegrationBlock): Promise<ExecuteIntegrationResponse> => {
|
||||
switch (block.type) {
|
||||
case IntegrationBlockType.GOOGLE_SHEETS:
|
||||
return executeGoogleSheetBlock(state, block)
|
||||
case IntegrationBlockType.CHATWOOT:
|
||||
return executeChatwootBlock(state, block, lastBubbleBlockId)
|
||||
return executeChatwootBlock(state, block)
|
||||
case IntegrationBlockType.GOOGLE_ANALYTICS:
|
||||
return executeGoogleAnalyticsBlock(state, block, lastBubbleBlockId)
|
||||
return executeGoogleAnalyticsBlock(state, block)
|
||||
case IntegrationBlockType.EMAIL:
|
||||
return executeSendEmailBlock(state, block)
|
||||
case IntegrationBlockType.WEBHOOK:
|
||||
|
||||
@@ -10,21 +10,21 @@ import { executeTypebotLink } from '@/features/blocks/logic/typebotLink/executeT
|
||||
import { executeAbTest } from '@/features/blocks/logic/abTest/executeAbTest'
|
||||
|
||||
export const executeLogic =
|
||||
(state: SessionState, lastBubbleBlockId?: string) =>
|
||||
(state: SessionState) =>
|
||||
async (block: LogicBlock): Promise<ExecuteLogicResponse> => {
|
||||
switch (block.type) {
|
||||
case LogicBlockType.SET_VARIABLE:
|
||||
return executeSetVariable(state, block, lastBubbleBlockId)
|
||||
return executeSetVariable(state, block)
|
||||
case LogicBlockType.CONDITION:
|
||||
return executeCondition(state, block)
|
||||
case LogicBlockType.REDIRECT:
|
||||
return executeRedirect(state, block, lastBubbleBlockId)
|
||||
return executeRedirect(state, block)
|
||||
case LogicBlockType.SCRIPT:
|
||||
return executeScript(state, block, lastBubbleBlockId)
|
||||
return executeScript(state, block)
|
||||
case LogicBlockType.TYPEBOT_LINK:
|
||||
return executeTypebotLink(state, block)
|
||||
case LogicBlockType.WAIT:
|
||||
return executeWait(state, block, lastBubbleBlockId)
|
||||
return executeWait(state, block)
|
||||
case LogicBlockType.JUMP:
|
||||
return executeJumpBlock(state, block.options)
|
||||
case LogicBlockType.AB_TEST:
|
||||
|
||||
Reference in New Issue
Block a user