2
0

⚗️ Implement bot v2 MVP (#194)

Closes #190
This commit is contained in:
Baptiste Arnaud
2022-12-22 17:02:34 +01:00
committed by GitHub
parent e55823e011
commit 1a3869ae6d
202 changed files with 8060 additions and 1152 deletions

View File

@ -11,7 +11,8 @@ export const emailInputOptionsSchema = optionBaseSchema
.and(textInputOptionsBaseSchema)
.and(
z.object({
retryMessageContent: z.string(),
// TODO: make it required once database migration is done
retryMessageContent: z.string().optional(),
})
)

View File

@ -32,6 +32,12 @@ export const paymentInputOptionsSchema = optionBaseSchema.and(
})
)
export const paymentInputRuntimeOptionsSchema = z.object({
paymentIntentSecret: z.string(),
amountLabel: z.string(),
publicKey: z.string(),
})
export const paymentInputSchema = blockBaseSchema.and(
z.object({
type: z.enum([InputBlockType.PAYMENT]),
@ -47,3 +53,6 @@ export const defaultPaymentInputOptions: PaymentInputOptions = {
export type PaymentInputBlock = z.infer<typeof paymentInputSchema>
export type PaymentInputOptions = z.infer<typeof paymentInputOptionsSchema>
export type PaymentInputRuntimeOptions = z.infer<
typeof paymentInputRuntimeOptionsSchema
>

View File

@ -6,6 +6,8 @@ import {
googleAnalyticsOptionsSchema,
imageBubbleContentSchema,
inputBlockSchema,
paymentInputRuntimeOptionsSchema,
redirectOptionsSchema,
textBubbleContentSchema,
videoBubbleContentSchema,
} from './blocks'
@ -13,6 +15,7 @@ import { publicTypebotSchema } from './publicTypebot'
import { ChatSession as ChatSessionPrisma } from 'db'
import { schemaForType } from './utils'
import { resultSchema } from './result'
import { typebotSchema } from './typebot'
const typebotInSessionStateSchema = publicTypebotSchema.pick({
id: true,
@ -28,7 +31,9 @@ export const sessionStateSchema = z.object({
queue: z.array(z.object({ edgeId: z.string(), typebotId: z.string() })),
}),
currentTypebotId: z.string(),
result: resultSchema.pick({ id: true, variables: true, hasStarted: true }),
result: resultSchema
.pick({ id: true, variables: true, hasStarted: true })
.optional(),
isPreview: z.boolean(),
currentBlock: z
.object({
@ -47,16 +52,38 @@ const chatSessionSchema = schemaForType<ChatSessionPrisma>()(
})
)
const simplifiedTextBubbleContentSchema = textBubbleContentSchema.pick({
plainText: true,
html: true,
const textMessageSchema = z.object({
type: z.enum([BubbleBlockType.TEXT]),
content: textBubbleContentSchema.omit({
richText: true,
}),
})
const chatMessageContentSchema = simplifiedTextBubbleContentSchema
.or(imageBubbleContentSchema)
.or(videoBubbleContentSchema)
.or(embedBubbleContentSchema)
.or(audioBubbleContentSchema)
const imageMessageSchema = z.object({
type: z.enum([BubbleBlockType.IMAGE]),
content: imageBubbleContentSchema,
})
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]),
content: embedBubbleContentSchema,
})
const chatMessageSchema = textMessageSchema
.or(imageMessageSchema)
.or(videoMessageSchema)
.or(audioMessageSchema)
.or(embedMessageSchema)
const codeToExecuteSchema = z.object({
content: z.string(),
@ -68,17 +95,55 @@ const codeToExecuteSchema = z.object({
),
})
const startParamsSchema = z.object({
typebotId: z.string({
description:
'[How can I find my typebot ID?](https://docs.typebot.io/api#how-to-find-my-typebotid)',
}),
isPreview: z
.boolean()
.optional()
.describe(
"If set to `true`, it will start a Preview session with the unpublished bot and it won't be saved in the Results tab."
),
resultId: z
.string()
.optional()
.describe("Provide it if you'd like to overwrite an existing result."),
prefilledVariables: z.record(z.unknown()).optional(),
})
export const sendMessageInputSchema = z.object({
message: z
.string()
.optional()
.describe(
'The answer to the previous chat input. Do not provide it if you are starting a new chat.'
),
sessionId: z
.string()
.optional()
.describe(
'Session ID that you get from the initial chat request to a bot. If not provided, it will create a new session.'
),
startParams: startParamsSchema.optional(),
})
const runtimeOptionsSchema = paymentInputRuntimeOptionsSchema.optional()
export const chatReplySchema = z.object({
messages: z.array(
z.object({
type: z.nativeEnum(BubbleBlockType),
content: chatMessageContentSchema,
})
),
input: inputBlockSchema.optional(),
messages: z.array(chatMessageSchema),
input: inputBlockSchema
.and(
z.object({
prefilledValue: z.string().optional(),
runtimeOptions: runtimeOptionsSchema.optional(),
})
)
.optional(),
logic: z
.object({
redirectUrl: z.string().optional(),
redirect: redirectOptionsSchema.optional(),
codeToExecute: codeToExecuteSchema.optional(),
})
.optional(),
@ -92,10 +157,26 @@ export const chatReplySchema = z.object({
googleAnalytics: googleAnalyticsOptionsSchema.optional(),
})
.optional(),
sessionId: z.string().optional(),
typebot: typebotSchema.pick({ theme: true, settings: true }).optional(),
resultId: z.string().optional(),
})
export const initialChatReplySchema = z
.object({
sessionId: z.string(),
resultId: z.string(),
typebot: typebotSchema.pick({ theme: true, settings: true }),
})
.and(chatReplySchema)
export type ChatSession = z.infer<typeof chatSessionSchema>
export type SessionState = z.infer<typeof sessionStateSchema>
export type TypebotInSession = z.infer<typeof typebotInSessionStateSchema>
export type ChatReply = z.infer<typeof chatReplySchema>
export type ChatMessageContent = z.infer<typeof chatMessageContentSchema>
export type InitialChatReply = z.infer<typeof initialChatReplySchema>
export type ChatMessage = z.infer<typeof chatMessageSchema>
export type SendMessageInput = z.infer<typeof sendMessageInputSchema>
export type CodeToExecute = z.infer<typeof codeToExecuteSchema>
export type StartParams = z.infer<typeof startParamsSchema>
export type RuntimeOptions = z.infer<typeof runtimeOptionsSchema>