2
0

(embed) Option to add a wait event for the embed bubble

Closes #1590
This commit is contained in:
Baptiste Arnaud
2024-06-19 15:27:45 +02:00
parent 4ab1803d39
commit 918836d6cf
20 changed files with 200 additions and 46 deletions

View File

@ -15,25 +15,23 @@ const defaultItem = {
id: createId(), id: createId(),
} }
type ItemWithId<T> = T & { id: string }
export type TableListItemProps<T> = { export type TableListItemProps<T> = {
item: T item: T
onItemChange: (item: T) => void onItemChange: (item: T) => void
} }
type Props<T> = { type Props<T extends object> = {
initialItems?: ItemWithId<T>[] initialItems?: T[]
isOrdered?: boolean isOrdered?: boolean
addLabel?: string addLabel?: string
newItemDefaultProps?: Partial<T> newItemDefaultProps?: Partial<T>
hasDefaultItem?: boolean hasDefaultItem?: boolean
ComponentBetweenItems?: (props: unknown) => JSX.Element ComponentBetweenItems?: (props: unknown) => JSX.Element
onItemsChange: (items: ItemWithId<T>[]) => void onItemsChange: (items: T[]) => void
children: (props: TableListItemProps<T>) => JSX.Element children: (props: TableListItemProps<T>) => JSX.Element
} }
export const TableList = <T,>({ export const TableList = <T extends object>({
initialItems, initialItems,
isOrdered, isOrdered,
addLabel = 'Add', addLabel = 'Add',
@ -45,7 +43,7 @@ export const TableList = <T,>({
}: Props<T>) => { }: Props<T>) => {
const [items, setItems] = useState( const [items, setItems] = useState(
addIdsIfMissing(initialItems) ?? addIdsIfMissing(initialItems) ??
(hasDefaultItem ? ([defaultItem] as ItemWithId<T>[]) : []) (hasDefaultItem ? ([defaultItem] as T[]) : [])
) )
const [showDeleteIndex, setShowDeleteIndex] = useState<number | null>(null) const [showDeleteIndex, setShowDeleteIndex] = useState<number | null>(null)
@ -56,14 +54,14 @@ export const TableList = <T,>({
const createItem = () => { const createItem = () => {
const id = createId() const id = createId()
const newItem = { id, ...newItemDefaultProps } as ItemWithId<T> const newItem = { id, ...newItemDefaultProps } as T
setItems([...items, newItem]) setItems([...items, newItem])
onItemsChange([...items, newItem]) onItemsChange([...items, newItem])
} }
const insertItem = (itemIndex: number) => () => { const insertItem = (itemIndex: number) => () => {
const id = createId() const id = createId()
const newItem = { id } as ItemWithId<T> const newItem = { id } as T
const newItems = [...items] const newItems = [...items]
newItems.splice(itemIndex + 1, 0, newItem) newItems.splice(itemIndex + 1, 0, newItem)
setItems(newItems) setItems(newItems)
@ -96,7 +94,7 @@ export const TableList = <T,>({
return ( return (
<Stack spacing={0}> <Stack spacing={0}>
{items.map((item, itemIndex) => ( {items.map((item, itemIndex) => (
<Box key={item.id}> <Box key={'id' in item ? (item.id as string) : itemIndex}>
{itemIndex !== 0 && ComponentBetweenItems && ( {itemIndex !== 0 && ComponentBetweenItems && (
<ComponentBetweenItems /> <ComponentBetweenItems />
)} )}
@ -185,7 +183,7 @@ export const TableList = <T,>({
) )
} }
const addIdsIfMissing = <T,>(items?: T[]): ItemWithId<T>[] | undefined => const addIdsIfMissing = <T,>(items?: T[]): T[] | undefined =>
items?.map((item) => ({ items?.map((item) => ({
id: createId(), id: createId(),
...item, ...item,

View File

@ -1,14 +1,29 @@
import { useTranslate } from '@tolgee/react' import { useTranslate } from '@tolgee/react'
import { Text } from '@chakra-ui/react' import { Stack, Text } from '@chakra-ui/react'
import { EmbedBubbleBlock } from '@typebot.io/schemas' import { EmbedBubbleBlock } from '@typebot.io/schemas'
import { SetVariableLabel } from '@/components/SetVariableLabel'
import { useTypebot } from '@/features/editor/providers/TypebotProvider'
type Props = { type Props = {
block: EmbedBubbleBlock block: EmbedBubbleBlock
} }
export const EmbedBubbleContent = ({ block }: Props) => { export const EmbedBubbleContent = ({ block }: Props) => {
const { typebot } = useTypebot()
const { t } = useTranslate() const { t } = useTranslate()
if (!block.content?.url) if (!block.content?.url)
return <Text color="gray.500">{t('clickToEdit')}</Text> return <Text color="gray.500">{t('clickToEdit')}</Text>
return <Text>{t('editor.blocks.bubbles.embed.node.show.text')}</Text> return (
<Stack>
<Text>{t('editor.blocks.bubbles.embed.node.show.text')}</Text>
{typebot &&
block.content.waitForEvent?.isEnabled &&
block.content.waitForEvent.saveDataInVariableId && (
<SetVariableLabel
variables={typebot.variables}
variableId={block.content.waitForEvent.saveDataInVariableId}
/>
)}
</Stack>
)
} }

View File

@ -1,9 +1,11 @@
import { TextInput, NumberInput } from '@/components/inputs' import { TextInput, NumberInput } from '@/components/inputs'
import { Stack, Text } from '@chakra-ui/react' import { Stack, Text } from '@chakra-ui/react'
import { EmbedBubbleBlock } from '@typebot.io/schemas' import { EmbedBubbleBlock, Variable } from '@typebot.io/schemas'
import { sanitizeUrl } from '@typebot.io/lib' import { sanitizeUrl } from '@typebot.io/lib'
import { useTranslate } from '@tolgee/react' import { useTranslate } from '@tolgee/react'
import { defaultEmbedBubbleContent } from '@typebot.io/schemas/features/blocks/bubbles/embed/constants' import { defaultEmbedBubbleContent } from '@typebot.io/schemas/features/blocks/bubbles/embed/constants'
import { SwitchWithRelatedSettings } from '@/components/SwitchWithRelatedSettings'
import { VariableSearchInput } from '@/components/inputs/VariableSearchInput'
type Props = { type Props = {
content: EmbedBubbleBlock['content'] content: EmbedBubbleBlock['content']
@ -23,6 +25,24 @@ export const EmbedUploadContent = ({ content, onSubmit }: Props) => {
height?: NonNullable<EmbedBubbleBlock['content']>['height'] height?: NonNullable<EmbedBubbleBlock['content']>['height']
) => height && onSubmit({ ...content, height }) ) => height && onSubmit({ ...content, height })
const updateWaitEventName = (name: string) =>
onSubmit({ ...content, waitForEvent: { ...content?.waitForEvent, name } })
const updateWaitForEventEnabled = (isEnabled: boolean) =>
onSubmit({
...content,
waitForEvent: { ...content?.waitForEvent, isEnabled },
})
const updateSaveDataInVariableId = (variable?: Pick<Variable, 'id'>) =>
onSubmit({
...content,
waitForEvent: {
...content?.waitForEvent,
saveDataInVariableId: variable?.id,
},
})
return ( return (
<Stack p="2" spacing={6}> <Stack p="2" spacing={6}>
<Stack> <Stack>
@ -43,8 +63,25 @@ export const EmbedUploadContent = ({ content, onSubmit }: Props) => {
defaultValue={content?.height ?? defaultEmbedBubbleContent.height} defaultValue={content?.height ?? defaultEmbedBubbleContent.height}
onValueChange={handleHeightChange} onValueChange={handleHeightChange}
suffix={t('editor.blocks.bubbles.embed.settings.numberInput.unit')} suffix={t('editor.blocks.bubbles.embed.settings.numberInput.unit')}
width="150px" direction="row"
/> />
<SwitchWithRelatedSettings
label="Wait for event?"
initialValue={content?.waitForEvent?.isEnabled ?? false}
onCheckChange={updateWaitForEventEnabled}
>
<TextInput
direction="row"
label="Name:"
defaultValue={content?.waitForEvent?.name}
onChange={updateWaitEventName}
/>
<VariableSearchInput
onSelectVariable={updateSaveDataInVariableId}
initialVariableId={content?.waitForEvent?.saveDataInVariableId}
label="Save data in variable"
/>
</SwitchWithRelatedSettings>
</Stack> </Stack>
) )
} }

View File

@ -35,3 +35,24 @@ The Embed bubble block allows you to display a website or an iframe to your user
For this, you'll need to select the pdf file you want to embed. Right click > Preview > More actions > Open in a new window. Now click More actions > Embed item. For this, you'll need to select the pdf file you want to embed. Right click > Preview > More actions > Open in a new window. Now click More actions > Embed item.
Copy the embed code and paste it in the Embed bubble block configuration. Copy the embed code and paste it in the Embed bubble block configuration.
## Wait for event
Enable this if you are the owner of the website you want to embed and would like to continue the bot flow only when an event from the embed is sent to the bot. This event dispatch needs to be executed in the embed website. Here is an example:
```js
window.parent.postMessage(
{ name: 'My event', data: 'Custom data passed to the typebot variable' },
'*'
)
```
You can choose the name of the event, it needs to match what you've set in the Embed bubble block configuration.
<Frame>
<img
src="/images/blocks/bubbles/embed-wait.jpg"
alt="Embed bubble"
className="rounded-lg"
/>
</Frame>

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

View File

@ -11,6 +11,7 @@ import { restartSession } from '@typebot.io/bot-engine/queries/restartSession'
import { continueBotFlow } from '@typebot.io/bot-engine/continueBotFlow' import { continueBotFlow } from '@typebot.io/bot-engine/continueBotFlow'
import { parseDynamicTheme } from '@typebot.io/bot-engine/parseDynamicTheme' import { parseDynamicTheme } from '@typebot.io/bot-engine/parseDynamicTheme'
import { isDefined } from '@typebot.io/lib/utils' import { isDefined } from '@typebot.io/lib/utils'
import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants'
export const sendMessageV1 = publicProcedure export const sendMessageV1 = publicProcedure
.meta({ .meta({
@ -136,8 +137,11 @@ export const sendMessageV1 = publicProcedure
logs: allLogs, logs: allLogs,
clientSideActions, clientSideActions,
visitedEdges, visitedEdges,
hasCustomEmbedBubble: messages.some( hasEmbedBubbleWithWaitEvent: messages.some(
(message) => message.type === 'custom-embed' (message) =>
message.type === 'custom-embed' ||
(message.type === BubbleBlockType.EMBED &&
message.content.waitForEvent?.isEnabled)
), ),
setVariableHistory, setVariableHistory,
}) })
@ -199,8 +203,11 @@ export const sendMessageV1 = publicProcedure
logs: allLogs, logs: allLogs,
clientSideActions, clientSideActions,
visitedEdges, visitedEdges,
hasCustomEmbedBubble: messages.some( hasEmbedBubbleWithWaitEvent: messages.some(
(message) => message.type === 'custom-embed' (message) =>
message.type === 'custom-embed' ||
(message.type === BubbleBlockType.EMBED &&
message.content.waitForEvent?.isEnabled)
), ),
setVariableHistory, setVariableHistory,
}) })

View File

@ -11,6 +11,7 @@ import {
chatReplySchema, chatReplySchema,
sendMessageInputSchema, sendMessageInputSchema,
} from '@typebot.io/schemas/features/chat/legacy/schema' } from '@typebot.io/schemas/features/chat/legacy/schema'
import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants'
export const sendMessageV2 = publicProcedure export const sendMessageV2 = publicProcedure
.meta({ .meta({
@ -136,8 +137,11 @@ export const sendMessageV2 = publicProcedure
logs: allLogs, logs: allLogs,
clientSideActions, clientSideActions,
visitedEdges, visitedEdges,
hasCustomEmbedBubble: messages.some( hasEmbedBubbleWithWaitEvent: messages.some(
(message) => message.type === 'custom-embed' (message) =>
message.type === 'custom-embed' ||
(message.type === BubbleBlockType.EMBED &&
message.content.waitForEvent?.isEnabled)
), ),
setVariableHistory, setVariableHistory,
}) })
@ -198,8 +202,11 @@ export const sendMessageV2 = publicProcedure
logs: allLogs, logs: allLogs,
clientSideActions, clientSideActions,
visitedEdges, visitedEdges,
hasCustomEmbedBubble: messages.some( hasEmbedBubbleWithWaitEvent: messages.some(
(message) => message.type === 'custom-embed' (message) =>
message.type === 'custom-embed' ||
(message.type === BubbleBlockType.EMBED &&
message.content.waitForEvent?.isEnabled)
), ),
setVariableHistory, setVariableHistory,
}) })

View File

@ -1,11 +1,12 @@
import { TRPCError } from '@trpc/server' import { TRPCError } from '@trpc/server'
import { isDefined, isNotDefined } from '@typebot.io/lib/utils' import { isDefined, isNotDefined, isNotEmpty } from '@typebot.io/lib/utils'
import { getSession } from '../queries/getSession' import { getSession } from '../queries/getSession'
import { continueBotFlow } from '../continueBotFlow' import { continueBotFlow } from '../continueBotFlow'
import { filterPotentiallySensitiveLogs } from '../logs/filterPotentiallySensitiveLogs' import { filterPotentiallySensitiveLogs } from '../logs/filterPotentiallySensitiveLogs'
import { parseDynamicTheme } from '../parseDynamicTheme' import { parseDynamicTheme } from '../parseDynamicTheme'
import { saveStateToDatabase } from '../saveStateToDatabase' import { saveStateToDatabase } from '../saveStateToDatabase'
import { computeCurrentProgress } from '../computeCurrentProgress' import { computeCurrentProgress } from '../computeCurrentProgress'
import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants'
type Props = { type Props = {
origin: string | undefined origin: string | undefined
@ -77,8 +78,11 @@ export const continueChat = async ({
clientSideActions, clientSideActions,
visitedEdges, visitedEdges,
setVariableHistory, setVariableHistory,
hasCustomEmbedBubble: messages.some( hasEmbedBubbleWithWaitEvent: messages.some(
(message) => message.type === 'custom-embed' (message) =>
message.type === 'custom-embed' ||
(message.type === BubbleBlockType.EMBED &&
message.content.waitForEvent?.isEnabled)
), ),
}) })

View File

@ -1,8 +1,10 @@
import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants'
import { computeCurrentProgress } from '../computeCurrentProgress' import { computeCurrentProgress } from '../computeCurrentProgress'
import { filterPotentiallySensitiveLogs } from '../logs/filterPotentiallySensitiveLogs' import { filterPotentiallySensitiveLogs } from '../logs/filterPotentiallySensitiveLogs'
import { restartSession } from '../queries/restartSession' import { restartSession } from '../queries/restartSession'
import { saveStateToDatabase } from '../saveStateToDatabase' import { saveStateToDatabase } from '../saveStateToDatabase'
import { startSession } from '../startSession' import { startSession } from '../startSession'
import { isNotEmpty } from '@typebot.io/lib'
type Props = { type Props = {
origin: string | undefined origin: string | undefined
@ -74,8 +76,11 @@ export const startChat = async ({
clientSideActions, clientSideActions,
visitedEdges, visitedEdges,
setVariableHistory, setVariableHistory,
hasCustomEmbedBubble: messages.some( hasEmbedBubbleWithWaitEvent: messages.some(
(message) => message.type === 'custom-embed' (message) =>
message.type === 'custom-embed' ||
(message.type === BubbleBlockType.EMBED &&
message.content.waitForEvent?.isEnabled)
), ),
}) })

View File

@ -3,6 +3,7 @@ import { restartSession } from '../queries/restartSession'
import { saveStateToDatabase } from '../saveStateToDatabase' import { saveStateToDatabase } from '../saveStateToDatabase'
import { startSession } from '../startSession' import { startSession } from '../startSession'
import { computeCurrentProgress } from '../computeCurrentProgress' import { computeCurrentProgress } from '../computeCurrentProgress'
import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants'
type Props = { type Props = {
message?: string message?: string
@ -69,8 +70,11 @@ export const startChatPreview = async ({
clientSideActions, clientSideActions,
visitedEdges, visitedEdges,
setVariableHistory, setVariableHistory,
hasCustomEmbedBubble: messages.some( hasEmbedBubbleWithWaitEvent: messages.some(
(message) => message.type === 'custom-embed' (message) =>
message.type === 'custom-embed' ||
(message.type === BubbleBlockType.EMBED &&
message.content.waitForEvent?.isEnabled)
), ),
initialSessionId: sessionId, initialSessionId: sessionId,
}) })

View File

@ -145,6 +145,13 @@ export const continueBotFlow = async (
} }
} }
} }
} else if (
block.type === BubbleBlockType.EMBED &&
block.content?.waitForEvent?.saveDataInVariableId
) {
variableToUpdate = state.typebotsQueue[0].typebot.variables.find(
(v) => v.id === block.content?.waitForEvent?.saveDataInVariableId
)
} }
if (variableToUpdate) { if (variableToUpdate) {

View File

@ -6,7 +6,7 @@ import {
SessionState, SessionState,
SetVariableHistoryItem, SetVariableHistoryItem,
} from '@typebot.io/schemas' } from '@typebot.io/schemas'
import { isNotEmpty } from '@typebot.io/lib' import { isEmpty, isNotEmpty } from '@typebot.io/lib'
import { import {
isBubbleBlock, isBubbleBlock,
isInputBlock, isInputBlock,
@ -32,6 +32,7 @@ import {
BubbleBlockWithDefinedContent, BubbleBlockWithDefinedContent,
parseBubbleBlock, parseBubbleBlock,
} from './parseBubbleBlock' } from './parseBubbleBlock'
import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants'
type ContextProps = { type ContextProps = {
version: 1 | 2 version: 1 | 2
@ -95,14 +96,30 @@ export const executeGroup = async (
if (isBubbleBlock(block)) { if (isBubbleBlock(block)) {
if (!block.content || (firstBubbleWasStreamed && index === 0)) continue if (!block.content || (firstBubbleWasStreamed && index === 0)) continue
messages.push( const message = parseBubbleBlock(block as BubbleBlockWithDefinedContent, {
parseBubbleBlock(block as BubbleBlockWithDefinedContent, { version,
version, variables: newSessionState.typebotsQueue[0].typebot.variables,
variables: newSessionState.typebotsQueue[0].typebot.variables, typebotVersion: newSessionState.typebotsQueue[0].typebot.version,
typebotVersion: newSessionState.typebotsQueue[0].typebot.version, textBubbleContentFormat,
textBubbleContentFormat, })
}) messages.push(message)
) if (
message.type === BubbleBlockType.EMBED &&
message.content.waitForEvent?.isEnabled
) {
return {
messages,
newSessionState: {
...newSessionState,
currentBlockId: block.id,
},
clientSideActions,
logs,
visitedEdges,
setVariableHistory,
}
}
lastBubbleBlockId = block.id lastBubbleBlockId = block.id
continue continue
} }

View File

@ -17,7 +17,7 @@ type Props = {
clientSideActions: ContinueChatResponse['clientSideActions'] clientSideActions: ContinueChatResponse['clientSideActions']
visitedEdges: VisitedEdge[] visitedEdges: VisitedEdge[]
setVariableHistory: SetVariableHistoryItem[] setVariableHistory: SetVariableHistoryItem[]
hasCustomEmbedBubble?: boolean hasEmbedBubbleWithWaitEvent?: boolean
initialSessionId?: string initialSessionId?: string
} }
@ -28,7 +28,7 @@ export const saveStateToDatabase = async ({
clientSideActions, clientSideActions,
visitedEdges, visitedEdges,
setVariableHistory, setVariableHistory,
hasCustomEmbedBubble, hasEmbedBubbleWithWaitEvent,
initialSessionId, initialSessionId,
}: Props) => { }: Props) => {
const containsSetVariableClientSideAction = clientSideActions?.some( const containsSetVariableClientSideAction = clientSideActions?.some(
@ -36,7 +36,9 @@ export const saveStateToDatabase = async ({
) )
const isCompleted = Boolean( const isCompleted = Boolean(
!input && !containsSetVariableClientSideAction && !hasCustomEmbedBubble !input &&
!containsSetVariableClientSideAction &&
!hasEmbedBubbleWithWaitEvent
) )
const queries: Prisma.PrismaPromise<any>[] = [] const queries: Prisma.PrismaPromise<any>[] = []

View File

@ -1,6 +1,6 @@
{ {
"name": "@typebot.io/js", "name": "@typebot.io/js",
"version": "0.2.88", "version": "0.2.89",
"description": "Javascript library to display typebots on your website", "description": "Javascript library to display typebots on your website",
"type": "module", "type": "module",
"main": "dist/index.js", "main": "dist/index.js",

View File

@ -51,6 +51,7 @@ export const HostBubble = (props: Props) => (
<EmbedBubble <EmbedBubble
content={props.message.content as EmbedBubbleBlock['content']} content={props.message.content as EmbedBubbleBlock['content']}
onTransitionEnd={props.onTransitionEnd} onTransitionEnd={props.onTransitionEnd}
onCompleted={props.onCompleted}
/> />
</Match> </Match>
<Match when={props.message.type === 'custom-embed'}> <Match when={props.message.type === 'custom-embed'}>

View File

@ -4,10 +4,12 @@ import { createSignal, onCleanup, onMount } from 'solid-js'
import { clsx } from 'clsx' import { clsx } from 'clsx'
import { EmbedBubbleBlock } from '@typebot.io/schemas' import { EmbedBubbleBlock } from '@typebot.io/schemas'
import { defaultEmbedBubbleContent } from '@typebot.io/schemas/features/blocks/bubbles/embed/constants' import { defaultEmbedBubbleContent } from '@typebot.io/schemas/features/blocks/bubbles/embed/constants'
import { isNotEmpty } from '@typebot.io/lib/utils'
type Props = { type Props = {
content: EmbedBubbleBlock['content'] content: EmbedBubbleBlock['content']
onTransitionEnd?: (ref?: HTMLDivElement) => void onTransitionEnd?: (ref?: HTMLDivElement) => void
onCompleted?: (data?: string) => void
} }
let typingTimeout: NodeJS.Timeout let typingTimeout: NodeJS.Timeout
@ -20,9 +22,29 @@ export const EmbedBubble = (props: Props) => {
props.onTransitionEnd ? true : false props.onTransitionEnd ? true : false
) )
const handleMessage = (
event: MessageEvent<{ name?: string; data?: string }>
) => {
if (
props.content?.waitForEvent?.isEnabled &&
isNotEmpty(event.data.name) &&
event.data.name === props.content?.waitForEvent.name
) {
props.onCompleted?.(
props.content.waitForEvent.saveDataInVariableId && event.data.data
? event.data.data
: undefined
)
window.removeEventListener('message', handleMessage)
}
}
onMount(() => { onMount(() => {
typingTimeout = setTimeout(() => { typingTimeout = setTimeout(() => {
setIsTyping(false) setIsTyping(false)
if (props.content?.waitForEvent?.isEnabled) {
window.addEventListener('message', handleMessage)
}
setTimeout(() => { setTimeout(() => {
props.onTransitionEnd?.(ref) props.onTransitionEnd?.(ref)
}, showAnimationDuration) }, showAnimationDuration)
@ -31,6 +53,7 @@ export const EmbedBubble = (props: Props) => {
onCleanup(() => { onCleanup(() => {
if (typingTimeout) clearTimeout(typingTimeout) if (typingTimeout) clearTimeout(typingTimeout)
window.removeEventListener('message', handleMessage)
}) })
return ( return (

View File

@ -1,6 +1,6 @@
{ {
"name": "@typebot.io/nextjs", "name": "@typebot.io/nextjs",
"version": "0.2.88", "version": "0.2.89",
"description": "Convenient library to display typebots on your Next.js website", "description": "Convenient library to display typebots on your Next.js website",
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",

View File

@ -1,6 +1,6 @@
{ {
"name": "@typebot.io/react", "name": "@typebot.io/react",
"version": "0.2.88", "version": "0.2.89",
"description": "Convenient library to display typebots on your React app", "description": "Convenient library to display typebots on your React app",
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",

View File

@ -6,6 +6,13 @@ import { BubbleBlockType } from '../constants'
export const embedBubbleContentSchema = z.object({ export const embedBubbleContentSchema = z.object({
url: z.string().optional(), url: z.string().optional(),
height: z.number().or(variableStringSchema).optional(), height: z.number().or(variableStringSchema).optional(),
waitForEvent: z
.object({
isEnabled: z.boolean().optional(),
name: z.string().optional(),
saveDataInVariableId: z.string().optional(),
})
.optional(),
}) })
export const embedBubbleBlockSchema = blockBaseSchema.merge( export const embedBubbleBlockSchema = blockBaseSchema.merge(

View File

@ -16,7 +16,6 @@ import {
import { logSchema } from '../result' import { logSchema } from '../result'
import { settingsSchema, themeSchema } from '../typebot' import { settingsSchema, themeSchema } from '../typebot'
import { import {
textBubbleContentSchema,
imageBubbleContentSchema, imageBubbleContentSchema,
videoBubbleContentSchema, videoBubbleContentSchema,
audioBubbleContentSchema, audioBubbleContentSchema,