2023-05-25 10:32:35 +02:00
import { z } from 'zod'
2022-11-29 10:02:40 +01:00
import {
2023-08-06 10:03:45 +02:00
executableWebhookSchema ,
2022-11-29 10:02:40 +01:00
googleAnalyticsOptionsSchema ,
2022-12-22 17:02:34 +01:00
paymentInputRuntimeOptionsSchema ,
2023-06-28 09:52:03 +02:00
pixelOptionsSchema ,
2022-12-22 17:02:34 +01:00
redirectOptionsSchema ,
2023-08-24 07:48:30 +02:00
} from '../blocks'
import { logSchema } from '../result'
2023-11-08 15:34:16 +01:00
import { listVariableValue } from '../typebot'
2023-01-25 11:27:47 +01:00
import {
textBubbleContentSchema ,
imageBubbleContentSchema ,
videoBubbleContentSchema ,
audioBubbleContentSchema ,
embedBubbleContentSchema ,
2023-08-24 07:48:30 +02:00
} from '../blocks/bubbles'
2023-11-08 15:34:16 +01:00
import { nativeMessageSchema } from '../blocks/integrations/openai'
2023-08-24 07:48:30 +02:00
import { sessionStateSchema } from './sessionState'
import { dynamicThemeSchema } from './shared'
2023-08-24 09:11:10 +02:00
import { preprocessTypebot } from '../typebot/helpers/preprocessTypebot'
2023-11-08 15:34:16 +01:00
import { typebotV5Schema , typebotV6Schema } from '../typebot/typebot'
import { inputBlockSchemas } from '../blocks/inputs/schema'
import { BubbleBlockType } from '../blocks/bubbles/constants'
2022-11-29 10:02:40 +01:00
2023-03-07 14:41:57 +01:00
const chatSessionSchema = z . object ( {
id : z.string ( ) ,
createdAt : z.date ( ) ,
updatedAt : z.date ( ) ,
state : sessionStateSchema ,
} )
2023-11-13 15:27:36 +01:00
export type ChatSession = z . infer < typeof chatSessionSchema >
2022-11-29 10:02:40 +01:00
2022-12-22 17:02:34 +01:00
const textMessageSchema = z . object ( {
2023-03-14 16:42:12 +01:00
type : z . literal ( BubbleBlockType . TEXT ) ,
2023-04-13 17:04:21 +02:00
content : textBubbleContentSchema ,
2022-12-22 17:02:34 +01:00
} )
const imageMessageSchema = z . object ( {
type : z . enum ( [ BubbleBlockType . IMAGE ] ) ,
content : imageBubbleContentSchema ,
2022-11-29 10:02:40 +01:00
} )
2022-12-22 17:02:34 +01:00
const videoMessageSchema = z . object ( {
type : z . enum ( [ BubbleBlockType . VIDEO ] ) ,
content : videoBubbleContentSchema ,
} )
const audioMessageSchema = z . object ( {
type : z . enum ( [ BubbleBlockType . AUDIO ] ) ,
content : audioBubbleContentSchema ,
} )
const embedMessageSchema = z . object ( {
type : z . enum ( [ BubbleBlockType . EMBED ] ) ,
2023-02-19 09:53:57 +01:00
content : embedBubbleContentSchema
. omit ( {
height : true ,
} )
2023-03-14 16:42:12 +01:00
. merge ( z . object ( { height : z.number ( ) . optional ( ) } ) ) ,
2022-12-22 17:02:34 +01:00
} )
2023-11-13 15:27:36 +01:00
export const chatMessageSchema = z
2023-01-27 10:54:59 +01:00
. object ( { id : z.string ( ) } )
. and (
2023-03-14 16:42:12 +01:00
z . discriminatedUnion ( 'type' , [
textMessageSchema ,
imageMessageSchema ,
videoMessageSchema ,
audioMessageSchema ,
embedMessageSchema ,
] )
2023-01-27 10:54:59 +01:00
)
2023-11-13 15:27:36 +01:00
export type ChatMessage = z . infer < typeof chatMessageSchema >
2022-11-29 10:02:40 +01:00
2023-01-27 15:58:05 +01:00
const scriptToExecuteSchema = z . object ( {
2022-11-29 10:02:40 +01:00
content : z.string ( ) ,
args : z.array (
z . object ( {
id : z.string ( ) ,
2023-02-23 14:44:37 +01:00
value : z
. string ( )
. or ( z . number ( ) )
. or ( z . boolean ( ) )
2023-03-21 15:42:03 +01:00
. or ( listVariableValue )
2023-02-23 14:44:37 +01:00
. nullish ( ) ,
2022-11-29 10:02:40 +01:00
} )
) ,
} )
2023-11-13 15:27:36 +01:00
export type ScriptToExecute = z . infer < typeof scriptToExecuteSchema >
2022-11-29 10:02:40 +01:00
2023-11-08 15:34:16 +01:00
const startTypebotPick = {
version : true ,
id : true ,
groups : true ,
events : true ,
edges : true ,
variables : true ,
settings : true ,
theme : true ,
} as const
2023-08-24 09:11:10 +02:00
export const startTypebotSchema = z . preprocess (
preprocessTypebot ,
2023-11-08 15:34:16 +01:00
z . discriminatedUnion ( 'version' , [
typebotV5Schema . _def . schema . pick ( startTypebotPick ) ,
typebotV6Schema . pick ( startTypebotPick ) ,
] )
2023-08-24 09:11:10 +02:00
)
2023-11-13 15:27:36 +01:00
export type StartTypebot = z . infer < typeof startTypebotSchema >
2023-01-16 12:13:21 +01:00
2023-11-13 15:27:36 +01:00
export const chatLogSchema = logSchema
2023-06-16 19:26:29 +02:00
. pick ( {
status : true ,
description : true ,
} )
. merge ( z . object ( { details : z.unknown ( ) . optional ( ) } ) )
2023-11-13 15:27:36 +01:00
export type ChatLog = z . infer < typeof chatLogSchema >
2023-06-16 19:26:29 +02:00
2023-11-13 15:27:36 +01:00
export const startChatInputSchema = z . object ( {
publicId : z.string ( ) ,
isStreamEnabled : z.boolean ( ) . optional ( ) ,
message : z.string ( ) . optional ( ) ,
resultId : z
2022-12-22 17:02:34 +01:00
. string ( )
. optional ( )
2023-11-13 15:27:36 +01:00
. describe ( "Provide it if you'd like to overwrite an existing result." ) ,
isOnlyRegistering : z
. boolean ( )
. optional ( )
2022-12-22 17:02:34 +01:00
. describe (
2023-11-13 15:27:36 +01:00
'If set to `true`, it will only register the session and not start the bot. This is used for 3rd party chat platforms as it can require a session to be registered before sending the first message.'
2022-12-22 17:02:34 +01:00
) ,
2023-11-13 15:27:36 +01:00
prefilledVariables : z
. record ( z . unknown ( ) )
2022-12-22 17:02:34 +01:00
. optional ( )
. describe (
2023-11-13 15:27:36 +01:00
'[More info about prefilled variables.](https://docs.typebot.io/editor/variables#prefilled-variables)'
2022-12-22 17:02:34 +01:00
) ,
2023-11-13 15:27:36 +01:00
} )
export type StartChatInput = z . infer < typeof startChatInputSchema >
export const startFromSchema = z . discriminatedUnion ( 'type' , [
z . object ( {
type : z . literal ( 'group' ) ,
groupId : z.string ( ) ,
} ) ,
z . object ( {
type : z . literal ( 'event' ) ,
eventId : z.string ( ) ,
} ) ,
] )
export type StartFrom = z . infer < typeof startFromSchema >
export const startPreviewChatInputSchema = z . object ( {
typebotId : z.string ( ) ,
isStreamEnabled : z.boolean ( ) . optional ( ) ,
message : z.string ( ) . optional ( ) ,
isOnlyRegistering : z
. boolean ( )
. optional ( )
. describe (
'If set to `true`, it will only register the session and not start the bot. This is used for 3rd party chat platforms as it can require a session to be registered before sending the first message.'
) ,
typebot : startTypebotSchema
2023-06-16 19:26:29 +02:00
. optional ( )
2023-11-13 15:27:36 +01:00
. describe (
'If set, it will override the typebot that is used to start the chat.'
) ,
startFrom : startFromSchema.optional ( ) ,
2022-12-22 17:02:34 +01:00
} )
2023-11-13 15:27:36 +01:00
export type StartPreviewChatInput = z . infer < typeof startPreviewChatInputSchema >
2022-12-22 17:02:34 +01:00
2023-11-13 15:27:36 +01:00
export const runtimeOptionsSchema = paymentInputRuntimeOptionsSchema . optional ( )
export type RuntimeOptions = z . infer < typeof runtimeOptionsSchema >
2022-12-22 17:02:34 +01:00
2023-06-28 09:52:03 +02:00
const startPropsToInjectSchema = z . object ( {
googleAnalyticsId : z.string ( ) . optional ( ) ,
2023-09-26 10:22:02 +02:00
pixelIds : z.array ( z . string ( ) ) . optional ( ) ,
2023-06-28 09:52:03 +02:00
gtmId : z.string ( ) . optional ( ) ,
customHeadCode : z.string ( ) . optional ( ) ,
} )
2023-11-13 15:27:36 +01:00
export type StartPropsToInject = z . infer < typeof startPropsToInjectSchema >
2023-06-28 09:52:03 +02:00
2023-11-13 15:27:36 +01:00
export const clientSideActionSchema = z
2023-01-26 15:26:42 +01:00
. object ( {
2023-01-27 10:54:59 +01:00
lastBubbleBlockId : z.string ( ) . optional ( ) ,
2023-09-04 14:52:16 +02:00
expectsDedicatedReply : z.boolean ( ) . optional ( ) ,
2023-01-26 15:26:42 +01:00
} )
2023-01-27 10:54:59 +01:00
. and (
z
. object ( {
2023-01-27 15:58:05 +01:00
scriptToExecute : scriptToExecuteSchema ,
2023-01-27 10:54:59 +01:00
} )
. or (
z . object ( {
redirect : redirectOptionsSchema ,
} )
)
. or (
z . object ( {
2023-01-27 15:58:05 +01:00
chatwoot : z.object ( { scriptToExecute : scriptToExecuteSchema } ) ,
2023-01-27 10:54:59 +01:00
} )
)
. or (
z . object ( {
googleAnalytics : googleAnalyticsOptionsSchema ,
} )
)
. or (
z . object ( {
wait : z.object ( {
secondsToWaitFor : z.number ( ) ,
} ) ,
} )
)
2023-04-14 12:11:42 +02:00
. or (
z . object ( {
setVariable : z.object ( { scriptToExecute : scriptToExecuteSchema } ) ,
} )
)
2023-05-25 10:32:35 +02:00
. or (
z . object ( {
streamOpenAiChatCompletion : z.object ( {
messages : z.array (
2023-11-08 15:34:16 +01:00
nativeMessageSchema . pick ( { content : true , role : true } )
2023-05-25 10:32:35 +02:00
) ,
} ) ,
} )
)
2023-05-26 09:20:22 +02:00
. or (
z . object ( {
webhookToExecute : executableWebhookSchema ,
} )
)
2023-06-28 09:52:03 +02:00
. or (
z . object ( {
startPropsToInject : startPropsToInjectSchema ,
} )
)
. or (
z . object ( {
pixel : pixelOptionsSchema ,
} )
)
2023-01-26 18:23:09 +01:00
)
2023-01-26 15:26:42 +01:00
2023-11-08 15:34:16 +01:00
const typebotInChatReplyPick = {
version : true ,
id : true ,
groups : true ,
edges : true ,
variables : true ,
settings : true ,
theme : true ,
} as const
export const typebotInChatReply = z . preprocess (
preprocessTypebot ,
z . discriminatedUnion ( 'version' , [
typebotV5Schema . _def . schema . pick ( typebotInChatReplyPick ) ,
typebotV6Schema . pick ( typebotInChatReplyPick ) ,
] )
)
2023-11-13 15:27:36 +01:00
const chatResponseBaseSchema = z . object ( {
lastMessageNewFormat : z
. string ( )
. optional ( )
. describe (
'The sent message is validated and formatted on the backend. This is set only if the message differs from the formatted version.'
) ,
2022-12-22 17:02:34 +01:00
messages : z.array ( chatMessageSchema ) ,
2023-05-04 09:20:30 -04:00
input : z
2023-11-08 15:34:16 +01:00
. union ( [
z . discriminatedUnion ( 'type' , [ . . . inputBlockSchemas . v5 ] ) ,
z . discriminatedUnion ( 'type' , [ . . . inputBlockSchemas . v6 ] ) ,
] )
2022-12-22 17:02:34 +01:00
. and (
z . object ( {
prefilledValue : z.string ( ) . optional ( ) ,
runtimeOptions : runtimeOptionsSchema.optional ( ) ,
} )
)
. optional ( ) ,
2023-01-26 15:26:42 +01:00
clientSideActions : z.array ( clientSideActionSchema ) . optional ( ) ,
2023-11-13 15:27:36 +01:00
logs : z.array ( chatLogSchema ) . optional ( ) ,
dynamicTheme : dynamicThemeSchema.optional ( ) ,
} )
export const startChatResponseSchema = chatResponseBaseSchema . extend ( {
2022-12-22 17:02:34 +01:00
sessionId : z.string ( ) . optional ( ) ,
2023-11-13 15:27:36 +01:00
typebot : z.object ( {
id : z.string ( ) ,
theme : z.union ( [
typebotV5Schema . _def . schema . shape . theme ,
typebotV6Schema . shape . theme ,
] ) ,
settings : z.union ( [
typebotV5Schema . _def . schema . shape . settings ,
typebotV6Schema . shape . settings ,
] ) ,
} ) ,
2022-12-22 17:02:34 +01:00
resultId : z.string ( ) . optional ( ) ,
2022-11-29 10:02:40 +01:00
} )
2023-11-13 15:27:36 +01:00
export type StartChatResponse = z . infer < typeof startChatResponseSchema >
2022-11-29 10:02:40 +01:00
2023-11-13 15:27:36 +01:00
export const startPreviewChatResponseSchema = startChatResponseSchema . omit ( {
resultId : true ,
} )
2023-08-24 07:48:30 +02:00
2023-11-13 15:27:36 +01:00
export const continueChatResponseSchema = chatResponseBaseSchema
export type ContinueChatResponse = z . infer < typeof continueChatResponseSchema >