2
0

📝 Migrate from Docusaurus to Mintlify (#1115)

Closes #868
This commit is contained in:
Baptiste Arnaud
2023-12-22 09:13:53 +01:00
committed by GitHub
parent 512bb09282
commit 1e5fa5a575
450 changed files with 49522 additions and 104787 deletions

View File

@ -72,7 +72,7 @@ Collect your **Results** and get insights:
Built for **developers**:
- 🔓 No vendor-locking. Features built with flexibility in mind.
- 💻 Easy-to-use [APIs](https://docs.typebot.io/api).
- 💻 Easy-to-use [APIs](https://docs.typebot.io/api-reference).
## Getting started with Typebot

View File

@ -25,6 +25,7 @@
"@giphy/js-util": "5.0.0",
"@giphy/react-components": "7.1.0",
"@googleapis/drive": "8.0.0",
"@lilyrose2798/trpc-openapi": "^1.3.9",
"@paralleldrive/cuid2": "2.2.1",
"@sentry/nextjs": "7.77.0",
"@tanstack/react-query": "4.29.19",
@ -90,7 +91,6 @@
"svg-round-corners": "0.4.1",
"swr": "2.2.0",
"tinycolor2": "1.6.0",
"trpc-openapi": "1.2.0",
"unsplash-js": "7.0.18",
"use-debounce": "9.0.4"
},
@ -102,9 +102,9 @@
"@typebot.io/forge-schemas": "workspace:*",
"@typebot.io/lib": "workspace:*",
"@typebot.io/prisma": "workspace:*",
"@typebot.io/radar": "workspace:*",
"@typebot.io/schemas": "workspace:*",
"@typebot.io/tsconfig": "workspace:*",
"@typebot.io/radar": "workspace:*",
"@types/canvas-confetti": "1.6.0",
"@types/jsonwebtoken": "9.0.2",
"@types/micro-cors": "0.1.3",

View File

@ -24,7 +24,7 @@ export const getSubscription = authenticatedProcedure
)
.output(
z.object({
subscription: subscriptionSchema.or(z.null()),
subscription: subscriptionSchema.or(z.null().openapi({ type: 'string' })),
})
)
.query(async ({ input: { workspaceId }, ctx: { user } }) => {

View File

@ -18,7 +18,11 @@ export const getUsage = authenticatedProcedure
})
.input(
z.object({
workspaceId: z.string(),
workspaceId: z
.string()
.describe(
'[Where to find my workspace ID?](../how-to#how-to-find-my-workspaceid)'
),
})
)
.output(z.object({ totalChatsUsed: z.number(), resetsAt: z.date() }))

View File

@ -20,7 +20,11 @@ export const listInvoices = authenticatedProcedure
})
.input(
z.object({
workspaceId: z.string(),
workspaceId: z
.string()
.describe(
'[Where to find my workspace ID?](../how-to#how-to-find-my-workspaceid)'
),
})
)
.output(

View File

@ -3,7 +3,6 @@ import { Plan } from '@typebot.io/prisma'
import { TextLink } from '@/components/TextLink'
import { useToast } from '@/hooks/useToast'
import { trpc } from '@/lib/trpc'
import { Workspace } from '@typebot.io/schemas'
import { PreCheckoutModal, PreCheckoutModalProps } from './PreCheckoutModal'
import { useState } from 'react'
import { ParentModalProvider } from '@/features/graph/providers/ParentModalProvider'
@ -13,9 +12,10 @@ import { ProPlanPricingCard } from './ProPlanPricingCard'
import { useTranslate } from '@tolgee/react'
import { StripeClimateLogo } from './StripeClimateLogo'
import { guessIfUserIsEuropean } from '@typebot.io/lib/billing/guessIfUserIsEuropean'
import { WorkspaceInApp } from '@/features/workspace/WorkspaceProvider'
type Props = {
workspace: Workspace
workspace: WorkspaceInApp
excludedPlans?: ('STARTER' | 'PRO')[]
}

View File

@ -9,15 +9,14 @@ import {
Tooltip,
} from '@chakra-ui/react'
import { AlertIcon } from '@/components/icons'
import { Workspace } from '@typebot.io/prisma'
import React from 'react'
import { WorkspaceInApp } from '@/features/workspace/WorkspaceProvider'
import { parseNumberWithCommas } from '@typebot.io/lib'
import { defaultQueryOptions, trpc } from '@/lib/trpc'
import { getChatsLimit } from '@typebot.io/lib/billing/getChatsLimit'
import { useTranslate } from '@tolgee/react'
type Props = {
workspace: Workspace
workspace: WorkspaceInApp
}
export const UsageProgressBars = ({ workspace }: Props) => {

View File

@ -44,7 +44,7 @@ export const getHelpDocUrl = (
case IntegrationBlockType.CHATWOOT:
return 'https://docs.typebot.io/editor/blocks/integrations/chatwoot'
case IntegrationBlockType.GOOGLE_ANALYTICS:
return 'https://docs.typebot.io/editor/blocks/integrations/ga'
return 'https://docs.typebot.io/editor/blocks/integrations/google-analytics'
case IntegrationBlockType.GOOGLE_SHEETS:
return 'https://docs.typebot.io/editor/blocks/integrations/google-sheets'
case IntegrationBlockType.ZAPIER:

View File

@ -37,7 +37,7 @@ export const ApiPreviewInstructions = (props: StackProps) => {
<OrderedList spacing={6} px="1">
<ListItem>
All your requests need to be authenticated with an API token.{' '}
<TextLink href="https://docs.typebot.io/api/builder/authenticate">
<TextLink href="https://docs.typebot.io/api-reference/authentication">
See instructions
</TextLink>
.
@ -90,7 +90,7 @@ export const ApiPreviewInstructions = (props: StackProps) => {
<Text fontSize="sm" pl="1">
Check out the{' '}
<TextLink
href="https://docs.typebot.io/api/start-preview-chat"
href="https://docs.typebot.io/api-reference/chat/start-preview-chat"
isExternal
>
API reference

View File

@ -79,7 +79,7 @@ export const WhatsAppPreviewInstructions = (props: StackProps) => {
<Text fontSize="sm">Need help?</Text>
<Button
as={Link}
href="https://docs.typebot.io/embed/whatsapp"
href="https://docs.typebot.io/deploy/whatsapp/overview"
leftIcon={<BuoyIcon />}
size="sm"
>

View File

@ -154,7 +154,7 @@ export const PublishButton = ({
<Stack spacing="3">
<Text>
You are about to a deploy a version of your bot with an updated
engine. (Typebot V6).
engine (Typebot V6).
</Text>
<Text fontWeight="bold">
Make sure to check out all the{' '}

View File

@ -86,7 +86,10 @@ export const ApiModal = ({
</OrderedList>
<Text fontSize="sm" colorScheme="gray">
Check out the{' '}
<TextLink href="https://docs.typebot.io/api/start-chat" isExternal>
<TextLink
href="https://docs.typebot.io/api-reference/chat/start-chat"
isExternal
>
API reference
</TextLink>{' '}
for more information

View File

@ -30,7 +30,10 @@ export const WebflowPopupInstructions = () => {
</OrderedList>
<Text fontSize="sm" colorScheme="gray" pl="5">
Check out the{' '}
<TextLink href="https://docs.typebot.io/embed/webflow#popup" isExternal>
<TextLink
href="https://docs.typebot.io/deploy/web/webflow#popup"
isExternal
>
Webflow embed documentation
</TextLink>{' '}
for more options.

View File

@ -302,7 +302,7 @@ const Requirements = () => (
<Text>
Make sure you have{' '}
<TextLink
href="https://docs.typebot.io/embed/whatsapp/create-meta-app"
href="https://docs.typebot.io/deploy/whatsapp/create-meta-app"
isExternal
>
created a WhatsApp Meta app

View File

@ -18,7 +18,11 @@ export const deleteResults = authenticatedProcedure
})
.input(
z.object({
typebotId: z.string(),
typebotId: z
.string()
.describe(
"[Where to find my bot's ID?](../how-to#how-to-find-my-typebotid)"
),
resultIds: z
.string()
.describe(

View File

@ -17,7 +17,11 @@ export const getResult = authenticatedProcedure
})
.input(
z.object({
typebotId: z.string(),
typebotId: z
.string()
.describe(
"[Where to find my bot's ID?](../how-to#how-to-find-my-typebotid)"
),
resultId: z.string(),
})
)

View File

@ -16,7 +16,11 @@ export const getResultLogs = authenticatedProcedure
})
.input(
z.object({
typebotId: z.string(),
typebotId: z
.string()
.describe(
"[Where to find my bot's ID?](../how-to#how-to-find-my-typebotid)"
),
resultId: z.string(),
})
)

View File

@ -19,7 +19,11 @@ export const getResults = authenticatedProcedure
})
.input(
z.object({
typebotId: z.string(),
typebotId: z
.string()
.describe(
"[Where to find my bot's ID?](../how-to#how-to-find-my-typebotid)"
),
limit: z.coerce.number().min(1).max(maxLimit).default(50),
cursor: z.string().optional(),
})

View File

@ -18,7 +18,11 @@ export const deleteTypebot = authenticatedProcedure
})
.input(
z.object({
typebotId: z.string(),
typebotId: z
.string()
.describe(
"[Where to find my bot's ID?](../how-to#how-to-find-my-typebotid)"
),
})
)
.output(

View File

@ -23,10 +23,15 @@ export const getPublishedTypebot = authenticatedProcedure
})
.input(
z.object({
typebotId: z.string(),
typebotId: z
.string()
.describe(
"[Where to find my bot's ID?](../how-to#how-to-find-my-typebotid)"
),
migrateToLatestVersion: z
.boolean()
.optional()
.default(false)
.describe(
'If enabled, the typebot will be converted to the latest schema version'
),
@ -36,11 +41,14 @@ export const getPublishedTypebot = authenticatedProcedure
z.object({
publishedTypebot: publicTypebotSchema.nullable(),
version: z
.union([
publicTypebotSchemaV5._def.schema.shape.version,
publicTypebotSchemaV6.shape.version,
.enum([
...publicTypebotSchemaV5._def.schema.shape.version._def.values,
publicTypebotSchemaV6.shape.version._def.value,
])
.optional(),
.optional()
.describe(
'Provides the version the published bot was migrated from if `migrateToLatestVersion` is set to `true`.'
),
})
)
.query(

View File

@ -20,10 +20,15 @@ export const getTypebot = publicProcedure
})
.input(
z.object({
typebotId: z.string(),
typebotId: z
.string()
.describe(
"[Where to find my bot's ID?](../how-to#how-to-find-my-typebotid)"
),
migrateToLatestVersion: z
.boolean()
.optional()
.default(false)
.describe(
'If enabled, the typebot will be converted to the latest schema version'
),

View File

@ -35,13 +35,23 @@ const omittedProps = {
const importingTypebotSchema = z.preprocess(
preprocessTypebot,
z.discriminatedUnion('version', [
typebotV5Schema._def.schema.omit(omittedProps).extend({
typebotV6Schema
.omit(omittedProps)
.extend({
resultsTablePreferences: resultsTablePreferencesSchema.nullish(),
selectedThemeTemplateId: z.string().nullish(),
})
.openapi({
title: 'Typebot V6',
}),
typebotV6Schema.omit(omittedProps).extend({
typebotV5Schema._def.schema
.omit(omittedProps)
.extend({
resultsTablePreferences: resultsTablePreferencesSchema.nullish(),
selectedThemeTemplateId: z.string().nullish(),
})
.openapi({
title: 'Typebot V5',
}),
])
)
@ -82,7 +92,11 @@ export const importTypebot = authenticatedProcedure
})
.input(
z.object({
workspaceId: z.string(),
workspaceId: z
.string()
.describe(
'[Where to find my workspace ID?](../how-to#how-to-find-my-workspaceid)'
),
typebot: importingTypebotSchema,
})
)

View File

@ -17,7 +17,16 @@ export const listTypebots = authenticatedProcedure
tags: ['Typebot'],
},
})
.input(z.object({ workspaceId: z.string(), folderId: z.string().optional() }))
.input(
z.object({
workspaceId: z
.string()
.describe(
'[Where to find my workspace ID?](../how-to#how-to-find-my-workspaceid)'
),
folderId: z.string().optional(),
})
)
.output(
z.object({
typebots: z.array(

View File

@ -29,7 +29,11 @@ export const publishTypebot = authenticatedProcedure
})
.input(
z.object({
typebotId: z.string(),
typebotId: z
.string()
.describe(
"[Where to find my bot's ID?](../how-to#how-to-find-my-typebotid)"
),
})
)
.output(

View File

@ -16,7 +16,11 @@ export const unpublishTypebot = authenticatedProcedure
})
.input(
z.object({
typebotId: z.string(),
typebotId: z
.string()
.describe(
"[Where to find my bot's ID?](../how-to#how-to-find-my-typebotid)"
),
})
)
.output(

View File

@ -51,10 +51,21 @@ export const updateTypebot = authenticatedProcedure
})
.input(
z.object({
typebotId: z.string(),
typebotId: z
.string()
.describe(
"[Where to find my bot's ID?](../how-to#how-to-find-my-typebotid)"
),
typebot: z.union([
typebotV5Schema._def.schema.pick(typebotUpdateSchemaPick).partial(),
typebotV6Schema.pick(typebotUpdateSchemaPick).partial(),
typebotV6Schema.pick(typebotUpdateSchemaPick).partial().openapi({
title: 'Typebot V6',
}),
typebotV5Schema._def.schema
.pick(typebotUpdateSchemaPick)
.partial()
.openapi({
title: 'Typebot V5',
}),
]),
updatedAt: z
.date()

View File

@ -17,9 +17,22 @@ import { useTypebot } from '../editor/providers/TypebotProvider'
import { setWorkspaceIdInLocalStorage } from './helpers/setWorkspaceIdInLocalStorage'
import { parseNewName } from './helpers/parseNewName'
export type WorkspaceInApp = Omit<
Workspace,
| 'chatsLimitFirstEmailSentAt'
| 'chatsLimitSecondEmailSentAt'
| 'storageLimitFirstEmailSentAt'
| 'storageLimitSecondEmailSentAt'
| 'customChatsLimit'
| 'customStorageLimit'
| 'additionalChatsIndex'
| 'additionalStorageIndex'
| 'isQuarantined'
>
const workspaceContext = createContext<{
workspaces: Pick<Workspace, 'id' | 'name' | 'icon' | 'plan'>[]
workspace?: Workspace
workspace?: WorkspaceInApp
currentRole?: WorkspaceRole
switchWorkspace: (workspaceId: string) => void
createWorkspace: (name?: string) => Promise<void>

View File

@ -19,7 +19,18 @@ export const createWorkspace = authenticatedProcedure
.input(z.object({ icon: z.string().optional(), name: z.string() }))
.output(
z.object({
workspace: workspaceSchema,
workspace: workspaceSchema.omit({
chatsLimitFirstEmailSentAt: true,
chatsLimitSecondEmailSentAt: true,
storageLimitFirstEmailSentAt: true,
storageLimitSecondEmailSentAt: true,
customChatsLimit: true,
customSeatsLimit: true,
customStorageLimit: true,
additionalChatsIndex: true,
additionalStorageIndex: true,
isQuarantined: true,
}),
})
)
.mutation(async ({ input: { name, icon }, ctx: { user } }) => {

View File

@ -16,7 +16,11 @@ export const deleteWorkspace = authenticatedProcedure
})
.input(
z.object({
workspaceId: z.string(),
workspaceId: z
.string()
.describe(
'[Where to find my workspace ID?](../how-to#how-to-find-my-workspaceid)'
),
})
)
.output(

View File

@ -17,12 +17,26 @@ export const getWorkspace = authenticatedProcedure
})
.input(
z.object({
workspaceId: z.string(),
workspaceId: z
.string()
.describe(
'[Where to find my workspace ID?](../how-to#how-to-find-my-workspaceid)'
),
})
)
.output(
z.object({
workspace: workspaceSchema,
workspace: workspaceSchema.omit({
chatsLimitFirstEmailSentAt: true,
chatsLimitSecondEmailSentAt: true,
storageLimitFirstEmailSentAt: true,
storageLimitSecondEmailSentAt: true,
customChatsLimit: true,
customStorageLimit: true,
additionalChatsIndex: true,
additionalStorageIndex: true,
isQuarantined: true,
}),
})
)
.query(async ({ input: { workspaceId }, ctx: { user } }) => {

View File

@ -17,7 +17,11 @@ export const listInvitationsInWorkspace = authenticatedProcedure
})
.input(
z.object({
workspaceId: z.string(),
workspaceId: z
.string()
.describe(
'[Where to find my workspace ID?](../how-to#how-to-find-my-workspaceid)'
),
})
)
.output(

View File

@ -17,7 +17,11 @@ export const listMembersInWorkspace = authenticatedProcedure
})
.input(
z.object({
workspaceId: z.string(),
workspaceId: z
.string()
.describe(
'[Where to find my workspace ID?](../how-to#how-to-find-my-workspaceid)'
),
})
)
.output(

View File

@ -19,12 +19,16 @@ export const updateWorkspace = authenticatedProcedure
z.object({
name: z.string().optional(),
icon: z.string().optional(),
workspaceId: z.string(),
workspaceId: z
.string()
.describe(
'[Where to find my workspace ID?](../how-to#how-to-find-my-workspaceid)'
),
})
)
.output(
z.object({
workspace: workspaceSchema,
workspace: workspaceSchema.pick({ name: true, icon: true }),
})
)
.mutation(async ({ input: { workspaceId, ...updates }, ctx: { user } }) => {

View File

@ -17,10 +17,10 @@ import {
MenuItem,
Text,
} from '@chakra-ui/react'
import { Workspace } from '@typebot.io/schemas'
import { WorkspaceInApp } from '../WorkspaceProvider'
type Props = {
currentWorkspace?: Workspace
currentWorkspace?: WorkspaceInApp
onWorkspaceSelected: (workspaceId: string) => void
onCreateNewWorkspaceClick: () => void
onLogoutClick: () => void

View File

@ -6,6 +6,10 @@ import {
Button,
useDisclosure,
Text,
Input,
InputGroup,
InputRightElement,
FormHelperText,
} from '@chakra-ui/react'
import { ConfirmModal } from '@/components/ConfirmModal'
import React from 'react'
@ -13,6 +17,7 @@ import { EditableEmojiOrImageIcon } from '@/components/EditableEmojiOrImageIcon'
import { useWorkspace } from '../WorkspaceProvider'
import { TextInput } from '@/components/inputs'
import { useTranslate } from '@tolgee/react'
import { CopyButton } from '@/components/CopyButton'
export const WorkspaceSettingsForm = ({ onClose }: { onClose: () => void }) => {
const { t } = useTranslate()
@ -50,12 +55,31 @@ export const WorkspaceSettingsForm = ({ onClose }: { onClose: () => void }) => {
</Flex>
</FormControl>
{workspace && (
<>
<TextInput
label={t('workspace.settings.name.label')}
withVariableButton={false}
defaultValue={workspace?.name}
onChange={handleNameChange}
/>
<FormControl>
<FormLabel>ID:</FormLabel>
<InputGroup>
<Input
type={'text'}
defaultValue={workspace.id}
pr="16"
readOnly
/>
<InputRightElement width="72px">
<CopyButton textToCopy={workspace.id} size="xs" />
</InputRightElement>
</InputGroup>
<FormHelperText>
Used when interacting with the Typebot API.
</FormHelperText>
</FormControl>
</>
)}
{workspace && workspaces && workspaces.length > 1 && (
<DeleteWorkspaceButton

View File

@ -15,11 +15,11 @@ import {
UsersIcon,
} from '@/components/icons'
import { EmojiOrImageIcon } from '@/components/EmojiOrImageIcon'
import { User, Workspace, WorkspaceRole } from '@typebot.io/prisma'
import { User, WorkspaceRole } from '@typebot.io/prisma'
import { useState } from 'react'
import { MembersList } from './MembersList'
import { WorkspaceSettingsForm } from './WorkspaceSettingsForm'
import { useWorkspace } from '../WorkspaceProvider'
import { WorkspaceInApp, useWorkspace } from '../WorkspaceProvider'
import packageJson from '../../../../../../package.json'
import { UserPreferencesForm } from '@/features/account/components/UserPreferencesForm'
import { MyAccountForm } from '@/features/account/components/MyAccountForm'
@ -29,7 +29,7 @@ import { useTranslate } from '@tolgee/react'
type Props = {
isOpen: boolean
user: User
workspace: Workspace
workspace: WorkspaceInApp
onClose: () => void
}

View File

@ -1,4 +1,4 @@
import { generateOpenApiDocument } from 'trpc-openapi'
import { generateOpenApiDocument } from '@lilyrose2798/trpc-openapi'
import { writeFileSync } from 'fs'
import { publicRouter } from './routers/publicRouter'
@ -6,10 +6,10 @@ const openApiDocument = generateOpenApiDocument(publicRouter, {
title: 'Builder API',
version: '1.0.0',
baseUrl: 'https://app.typebot.io/api',
docsUrl: 'https://docs.typebot.io/api',
docsUrl: 'https://docs.typebot.io/api-reference',
})
writeFileSync(
'./openapi/builder/_spec_.json',
'./openapi/builder.json',
JSON.stringify(openApiDocument, null, 2)
)

View File

@ -1,6 +1,6 @@
import { TRPCError, initTRPC } from '@trpc/server'
import { Context } from './context'
import { OpenApiMeta } from 'trpc-openapi'
import { OpenApiMeta } from '@lilyrose2798/trpc-openapi'
import superjson from 'superjson'
import * as Sentry from '@sentry/nextjs'
import { ZodError } from 'zod'

View File

@ -1,7 +1,7 @@
import { createContext } from '@/helpers/server/context'
import * as Sentry from '@sentry/nextjs'
import { NextApiRequest, NextApiResponse } from 'next'
import { createOpenApiNextHandler } from 'trpc-openapi'
import { createOpenApiNextHandler } from '@lilyrose2798/trpc-openapi'
import cors from 'nextjs-cors'
import { publicRouter } from '@/helpers/server/routers/publicRouter'

View File

@ -1,29 +0,0 @@
# Typebot docs
This is the source code of Typebot's documentation located at https://docs.typebot.io
# Website
This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
## Installation
```console
pnpm install
```
## Local Development
```console
pnpm start
```
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
## Build
```console
pnpm build
```
This command generates static content into the `build` directory and can be served using any static contents hosting service.

View File

@ -1,10 +1,8 @@
---
sidebar_position: 1
title: 'Authentication'
---
# Authentication
Every API resources are protected, and therefore require that you authenticate using an API token.
Some API endpoints are protected, and therefore require that you authenticate using an API token.
## Generate a token
@ -14,11 +12,13 @@ Every API resources are protected, and therefore require that you authenticate u
4. Give it a name, then click on "Create token"
5. Copy your token.
<img
src="/img/api/authentication/generateToken.png"
<Frame>
<img
src="/images/api/authentication/generateToken.png"
width="900"
alt="Generate token"
/>
/>
</Frame>
## Use your token

View File

@ -0,0 +1,4 @@
---
title: 'Get current usage'
openapi: GET /v1/billing/usage
---

View File

@ -0,0 +1,4 @@
---
title: 'List invoices'
openapi: GET /v1/billing/invoices
---

View File

@ -0,0 +1,4 @@
---
title: 'Continue chat'
openapi: POST /v1/sessions/{sessionId}/continueChat
---

View File

@ -0,0 +1,4 @@
---
title: 'Save logs'
openapi: POST /v1/sessions/{sessionId}/clientLogs
---

View File

@ -0,0 +1,4 @@
---
title: 'Start chat'
openapi: POST /v1/typebots/{publicId}/startChat
---

View File

@ -0,0 +1,4 @@
---
title: 'Start preview chat'
openapi: POST /v1/typebots/{typebotId}/preview/startChat
---

View File

@ -0,0 +1,4 @@
---
title: 'Update typebot in session'
openapi: POST /v1/sessions/{sessionId}/updateTypebot
---

View File

@ -0,0 +1,84 @@
---
title: "Create User"
api: "POST https://api.mintlify.com/api/user"
description: "This endpoint creates a new user"
---
### Body
<ParamField body="current_token" type="string">
This is the current user group token you have for the user group that you want
to rotate.
</ParamField>
### Response
<ResponseField name="success" type="number">
Indicates whether the call was successful. 1 if successful, 0 if not.
</ResponseField>
<ResponseField name="user_group" type="object">
The contents of the user group
<Expandable title="Toggle object">
<ResponseField name="team_id" type="number">
This is the internal ID for this user group. You don't need to record this
information, since you will not need to use it.
</ResponseField>
<ResponseField name="token" type="string">
This is the user group token (userGroupToken or USER_GROUP_TOKEN) that will be
used to identify which user group is viewing the dashboard. You should save
this on your end to use when rendering an embedded dashboard.
</ResponseField>
<ResponseField name="name" type="string">
This is the name of the user group provided in the request body.
</ResponseField>
<ResponseField name="provided_id" type="string">
This is the user_group_id provided in the request body.
</ResponseField>
<ResponseField name="api_environment_tag" type="JSON or null">
This is the environment tag of the user group. Possible values are 'Customer'
and 'Testing'. User group id's must be unique to each environment, so you can
not create multiple user groups with with same id. If you have a production
customer and a test user group with the same id, you will be required to label
one as 'Customer' and another as 'Testing'
</ResponseField>
</Expandable>
</ResponseField>
<RequestExample>
```bash Example Request
curl --location --request POST 'https://api.mintlify.com/api/user' \
--header 'Content-Type: application/json' \
--header 'Authorization: Token <token>' \
--data-raw '{
"current_token": ""
}'
```
</RequestExample>
<ResponseExample>
```json Response
{
"success": 1,
"user_group": {
"team_id": 3,
"token": "<user_group_token_to_auth_dashboard>",
"name": "Example 1",
"provided_id": "example_1"
}
}
```
</ResponseExample>

View File

@ -0,0 +1,47 @@
---
title: "Delete User"
api: "DELETE https://api.mintlify.com/api/user"
description: "This endpoint deletes an existing user."
---
### Body
<ParamField body="data_source_provided_id" type="string">
The data source ID provided in the data tab may be used to identify the data
source for the user group
</ParamField>
<ParamField body="current_token" type="string">
This is the current user group token you have for the user group you want to
delete
</ParamField>
### Response
<ResponseField name="success" type="number">
Indicates whether the call was successful. 1 if successful, 0 if not.
</ResponseField>
<RequestExample>
```bash Example Request
curl --location --request DELETE 'https://api.mintlify.com/api/user' \
--header 'Content-Type: application/json' \
--header 'Authorization: Token <token>' \
--data-raw '{
"user_group_id": "example_1"
"current_token": "abcdef"
}'
```
</RequestExample>
<ResponseExample>
```json Response
{
"success": 1
}
```
</ResponseExample>

View File

@ -0,0 +1,101 @@
---
title: "Get User"
api: "GET https://api.mintlify.com/api/user"
description: "This endpoint gets or creates a new user."
---
### Body
<ParamField body="name" type="string">
This is the name of the user group.
</ParamField>
<ParamField body="user_group_id" type="string">
This is the ID you use to identify this user group in your database.
</ParamField>
<ParamField body="mapping" type="object">
This is a JSON mapping of schema id to either the data source that this user group should be
associated with or id of the datasource you provided when creating it.
</ParamField>
<ParamField body="properties" type="object">
This is a JSON object for properties assigned to this user group. These will be accessible through
variables in the dashboards and SQL editor
</ParamField>
### Response
<ResponseField name="success" type="number">
Indicates whether the call was successful. 1 if successful, 0 if not.
</ResponseField>
<ResponseField name="new_user_group" type="boolean">
Indicates whether a new user group was created.
</ResponseField>
<ResponseField name="user_group" type="object">
The contents of the user group
<Expandable title="Toggle object">
<ResponseField name="team_id" type="number">
This is the internal ID for this user group. You don't need to record this information, since
you will not need to use it.
</ResponseField>
<ResponseField name="token" type="string">
This is the user group token (userGroupToken or USER_GROUP_TOKEN) that will be used to identify
which user group is viewing the dashboard. You should save this on your end to use when rendering
an embedded dashboard.
</ResponseField>
<ResponseField name="name" type="string">
This is the name of the user group provided in the request body.
</ResponseField>
<ResponseField name="provided_id" type="string">
This is the user_group_id provided in the request body.
</ResponseField>
<ResponseField name="properties" type="JSON or null">
This is the properties object if it was provided in the request body
</ResponseField>
</Expandable>
</ResponseField>
<RequestExample>
```bash Example Request
curl --location --request GET 'https://api.mintlify.com/api/user' \
--header 'Content-Type: application/json' \
--header 'Authorization: Token <token>' \
--data-raw '{
"user_group_id": "example_1",
"name": "Example 1",
"mapping": {"40": "213", "134": "386"},
"properties": {"filterValue": "value"}
}'
```
</RequestExample>
<ResponseExample>
```json Response
{
"success": 1,
"new_user_group": true,
"user_group": {
"team_id": 3,
"token": "<user_group_token_to_auth_dashboard>",
"name": "Example 1",
"provided_id": "example_1"
}
}
```
</ResponseExample>

View File

@ -0,0 +1,101 @@
---
title: "Update User"
api: "PUT https://api.mintlify.com/api/user"
description: "This endpoint updates an existing user."
---
### Body
<ParamField body="name" type="string">
This is the name of the user group.
</ParamField>
<ParamField body="user_group_id" type="string">
This is the ID you use to identify this user group in your database.
</ParamField>
<ParamField body="mapping" type="object">
This is a JSON mapping of schema id to either the data source that this user
group should be associated with or id of the datasource you provided when
creating it.
</ParamField>
<ParamField body="properties" type="object">
This is a JSON object for properties assigned to this user group. These will
be accessible through variables in the dashboards and SQL editor
</ParamField>
### Response
<ResponseField name="success" type="number">
Indicates whether the call was successful. 1 if successful, 0 if not.
</ResponseField>
<ResponseField name="user_group" type="object">
The contents of the user group
<Expandable title="Toggle object">
<ResponseField name="team_id" type="number">
Indicates whether a new user group was created.
</ResponseField>
<ResponseField name="token" type="string">
This is the user group token (userGroupToken or USER_GROUP_TOKEN) that will be
used to identify which user group is viewing the dashboard. You should save
this on your end to use when rendering an embedded dashboard.
</ResponseField>
<ResponseField name="name" type="string">
This is the name of the user group provided in the request body.
</ResponseField>
<ResponseField name="provided_id" type="string">
This is the user_group_id provided in the request body.
</ResponseField>
<ResponseField name="properties" type="JSON | Null">
This is the properties object if it was provided in the request body
</ResponseField>
<ResponseField name="api_environment_tag" type="JSON or null">
This is the environment tag of the user group. Possible values are 'Customer'
and 'Testing'
</ResponseField>
</Expandable>
</ResponseField>
<RequestExample>
```bash Example Request
curl --location --request PUT 'https://api.mintlify.com/api/user' \
--header 'Content-Type: application/json' \
--header 'Authorization: Token <token>' \
--data-raw '{
"user_group_id": "example_1",
"name": "Example 1",
"mapping": {"40": "213", "134": "386"},
"properties": {"filterValue": "value"}
}'
```
</RequestExample>
<ResponseExample>
```json Response
{
"success": 1,
"user_group": {
"team_id": 113,
"token": "<user_group_token_to_auth_dashboard>",
"name": "ok",
"provided_id": "6"
}
}
```
</ResponseExample>

View File

@ -0,0 +1,21 @@
---
title: How-to
---
### How to find my `typebotId`
If you'd like to execute the typebot in preview mode, you will need to provide the ID of the building typebot available in the editor URL:
<Frame>
<img src="/images/api/typebotId.png" alt="Get typebot ID" />
</Frame>
### How to find my `publicId`
For published typebot execution, you need to provide the public typebot ID available here:
<img src="/images/api/publicId.png" alt="Get typebot ID" />
### How to find my `workspaceId`
In your workspace dashboard, head over to `Settings & Members > Workspace > Settings` and copy the workspace ID

View File

@ -0,0 +1,4 @@
---
title: 'Delete results'
openapi: DELETE /v1/typebots/{typebotId}/results
---

View File

@ -0,0 +1,4 @@
---
title: 'Get a result'
openapi: GET /v1/typebots/{typebotId}/results/{resultId}
---

View File

@ -0,0 +1,4 @@
---
title: 'List logs in result'
openapi: GET /v1/typebots/{typebotId}/results/{resultId}/logs
---

View File

@ -0,0 +1,4 @@
---
title: 'List results'
openapi: GET /v1/typebots/{typebotId}/results
---

View File

@ -0,0 +1,4 @@
---
title: 'Create a typebot'
openapi: POST /v1/typebots
---

View File

@ -0,0 +1,4 @@
---
title: 'Delete a typebot'
openapi: DELETE /v1/typebots/{typebotId}
---

View File

@ -0,0 +1,4 @@
---
title: 'Get published bot'
openapi: GET /v1/typebots/{typebotId}/publishedTypebot
---

View File

@ -0,0 +1,4 @@
---
title: 'Get a typebot'
openapi: GET /v1/typebots/{typebotId}
---

View File

@ -0,0 +1,4 @@
---
title: 'Import a typebot'
openapi: POST /v1/typebots/import
---

View File

@ -0,0 +1,4 @@
---
title: 'List typebots'
openapi: GET /v1/typebots
---

View File

@ -0,0 +1,4 @@
---
title: 'Publish typebot'
openapi: POST /v1/typebots/{typebotId}/publish
---

View File

@ -0,0 +1,4 @@
---
title: 'Unpublish typebot'
openapi: POST /v1/typebots/{typebotId}/unpublish
---

View File

@ -0,0 +1,4 @@
---
title: 'Update a typebot'
openapi: PATCH /v1/typebots/{typebotId}
---

View File

@ -0,0 +1,4 @@
---
title: 'Create a workspace'
openapi: POST /v1/workspaces
---

View File

@ -0,0 +1,4 @@
---
title: 'Delete a workspace'
openapi: DELETE /v1/workspaces/{workspaceId}
---

View File

@ -0,0 +1,4 @@
---
title: 'Get a workspace'
openapi: GET /v1/workspaces/{workspaceId}
---

View File

@ -0,0 +1,4 @@
---
title: 'List members'
openapi: GET /v1/workspaces/{workspaceId}/members
---

View File

@ -0,0 +1,4 @@
---
title: 'List workspaces'
openapi: GET /v1/workspaces
---

View File

@ -0,0 +1,4 @@
---
title: 'Update a workspace'
openapi: PATCH /v1/workspaces/{workspaceId}
---

View File

@ -1,3 +0,0 @@
module.exports = {
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
};

View File

@ -1,6 +1,8 @@
# Breaking changes
---
title: Breaking changes
---
## Typebot v7
## Typebot v6
- List variables now don't automatically display the last item when inserted into a bubble. It was too "magical". Now you can leverage the inline code feature to easily get the last element of a list:
@ -10,7 +12,7 @@
Check out the new [Inline variable formatting section](./editor/variables) for more information.
- Input prefill is now disabled by default. You can still enable it in the [Settings](./editor/settings) tab of your bot.
- Input prefill is now disabled by default. You can still enable it in the [Settings](./settings/overview) tab of your bot.
- `Message sequence` option in the OpenAI block was removed because it was also too "magical" and it. Now I've introduced the `Dialogue` option. For more information:
@ -23,8 +25,6 @@
>
<iframe
src="https://www.loom.com/embed/df5d64dd01ca47daa5b7acd18b05a725?sid=e6df2f5b-643c-4175-8351-03e1726b2749"
frameBorder={0}
webkitallowfullscreen
mozallowfullscreen
allowFullScreen
style={{

View File

@ -1,20 +1,21 @@
# Add a custom domain
---
title: Add a custom domain
---
You can bind a custom domain to your typebot in the "Share" tab.
<img
src="/img/custom-domain/add-domain.png"
width="700"
alt="Add my domain button"
/>
<Frame>
<img src="/images/custom-domain/add-domain.png" alt="Add my domain button" />
</Frame>
To connect a new domain, follow the instructions:
<img
src="/img/custom-domain/instructions.png"
width="700"
<Frame>
<img
src="/images/custom-domain/instructions.png"
alt="Add domain instructions"
/>
/>
</Frame>
Once you've added the corresponding DNS record, click on the "Save" button. You might have to wait for a few minutes before the record is properly propagated.
@ -22,10 +23,8 @@ Once you've added the corresponding DNS record, click on the "Save" button. You
If your domain is not properly configured or verified, you will see this error icon next to your domain link:
<img
src="/img/custom-domain/invalid-config.png"
width="500"
alt="Error icon"
/>
<Frame>
<img src="/images/custom-domain/invalid-config.png" alt="Error icon" />
</Frame>
Make sure to click on it to see what is required to do to fix the issue.

View File

@ -1,11 +1,14 @@
---
sidebar_position: 3
title: Iframe
---
# Iframe
You can easily get your typebot iframe code by clicking on the "Iframe" button in the "Share" tab of your typebot.
<img src="/img/embeddings/iframe/iframe-preview.png" width="600" alt="Iframe preview"/>
<Frame>
<img
src="/images/embeddings/iframe/iframe-preview.png"
alt="Iframe preview"
/>
</Frame>
Here, you can set up its width and height. A good default is a `width` of `100%` and a `height` of `600px`.

View File

@ -1,9 +1,7 @@
---
sidebar_position: 4
title: HTML & Javascript
---
# HTML & Javascript
## Standard
You can get the standard HTML and Javascript code by clicking on the "HTML & Javascript" button in the "Share" tab of your typebot.
@ -24,48 +22,6 @@ There, you can change the container dimensions. Here is a code example:
This code is creating a container with a 100% width (will match parent width) and 600px height.
## Popup
You can get the popup HTML and Javascript code by clicking on the "HTML & Javascript" button in the "Share" tab of your typebot.
Here is an example:
```html
<script type="module">
import Typebot from 'https://cdn.jsdelivr.net/npm/@typebot.io/js@0.2/dist/web.js'
Typebot.initPopup({
typebot: 'my-typebot',
apiHost: 'http://localhost:3001',
autoShowDelay: 3000,
})
</script>
```
This code will automatically trigger the popup window after 3 seconds.
### Open or Close a popup
You can use these commands:
```js
Typebot.open()
```
```js
Typebot.close()
```
```js
Typebot.toggle()
```
You can bind these commands on a button element, for example:
```html
<button onclick="Typebot.open()">Contact us</button>
```
### Multiple bots
If you have different bots on the same page you will have to make them distinct with an additional `id` prop:
@ -96,6 +52,26 @@ If you have different bots on the same page you will have to make them distinct
></typebot-standard>
```
## Popup
You can get the popup HTML and Javascript code by clicking on the "HTML & Javascript" button in the "Share" tab of your typebot.
Here is an example:
```html
<script type="module">
import Typebot from 'https://cdn.jsdelivr.net/npm/@typebot.io/js@0.2/dist/web.js'
Typebot.initPopup({
typebot: 'my-typebot',
apiHost: 'http://localhost:3001',
autoShowDelay: 3000,
})
</script>
```
This code will automatically trigger the popup window after 3 seconds.
## Bubble
You can get the bubble HTML and Javascript code by clicking on the "HTML & Javascript" button in the "Share" tab of your typebot.
@ -124,40 +100,6 @@ Here is an example:
This code will show the bubble and let a preview message appear after 5 seconds.
### Open or close the preview message
You can use these commands:
```js
Typebot.showPreviewMessage()
```
```js
Typebot.hidePreviewMessage()
```
### Open or close the typebot
You can use these commands:
```js
Typebot.open()
```
```js
Typebot.close()
```
```js
Typebot.toggle()
```
You can bind these commands on a button element, for example:
```html
<button onclick="Typebot.open()">Contact us</button>
```
### Custom button position
You can move the button with some custom CSS on your website. For example, you can place the bubble button higher with the following CSS:
@ -181,6 +123,35 @@ typebot-bubble::part(preview-message) {
}
```
## Commands
Here are the commands you can use to trigger your embedded typebot:
- `Typebot.open()`: Open popup or bubble
- `Typebot.close()`: Close popup or bubble
- `Typebot.toggle()`: Toggle the bubble or popup open/close state,
- `Typebot.showPreviewMessage()`: Show preview message from the bubble,
- `Typebot.hidePreviewMessage()`: Hide preview message from the bubble,
- `Typebot.setPrefilledVariables(...)`: Set prefilled variables.
Example:
```js
Typebot.setPrefilledVariables({
Name: 'Jhon',
Email: 'john@gmail.com',
})
```
For more information, check out [Additional configuration](#additional-configuration).
- `Typebot.setInputValue(...)`: Set the value in the currently displayed input.
You can bind these commands on a button element, for example:
```html
<button onclick="Typebot.open()">Contact us</button>
```
## Callbacks
If you need to trigger events on your parent website when the user interact with the bot, you can use the following callbacks:

View File

@ -0,0 +1,15 @@
---
title: Next.js
---
This lib is a convenient wrapper around the [Typebot React](./react) library. It makes sure the components are lazy loaded.
## Install
```bash
npm install @typebot.io/js @typebot.io/nextjs
```
## Usage
Use it like you would use the [Typebot React](./react) library.

View File

@ -1,9 +1,7 @@
---
sidebar_position: 5
title: React
---
# React
## Install
```bash
@ -39,28 +37,6 @@ const App = () => {
This code will automatically trigger the popup window after 3 seconds.
### Open or Close a popup
You can use these commands:
```js
import { open } from '@typebot.io/react'
open()
```
```js
import { close } from '@typebot.io/react'
close()
```
```js
import { toggle } from '@typebot.io/react'
toggle()
```
## Bubble
```tsx
@ -86,44 +62,6 @@ const App = () => {
This code will show the bubble and let a preview message appear after 5 seconds.
### Open or close the preview message
You can use these commands:
```js
import { showPreviewMessage } from '@typebot.io/react'
Typebot.showPreviewMessage()
```
```js
import { hidePreviewMessage } from '@typebot.io/react'
Typebot.hidePreviewMessage()
```
### Open or close the chat window
You can use these commands:
```js
import { open } from '@typebot.io/react'
open()
```
```js
import { close } from '@typebot.io/react'
close()
```
```js
import { toggle } from '@typebot.io/react'
toggle()
```
## Additional configuration
You can prefill the bot variable values in your embed code by adding the `prefilledVariables` option. Here is an example:

View File

@ -1,8 +1,8 @@
---
sidebar_position: 1
title: Overview
---
# Overview
To get the appropriate instructions to deploy your typebot in your platform of choice, make sure to head over the `Share` tab of your bot and select the platform you want to deploy your typebot on.
You can choose to embed your typebot in 3 different ways.
@ -10,7 +10,9 @@ You can choose to embed your typebot in 3 different ways.
Embeds the typebot in a box with the size of your choice anywhere on your app. This is what is used on Typebot homepage:
<img src="/img/embeddings/standard.png" alt="Standard"/>
<Frame>
<img src="/images/embeddings/standard.png" alt="Standard" />
</Frame>
You can also set the width to `100%` and the height to `100vh` to make it take the entire page dimensions
@ -18,10 +20,14 @@ You can also set the width to `100%` and the height to `100vh` to make it take t
Embeds the typebot in a Popup that overlays your website. It can be triggered after a delay or with a click of a button for example
<img src="/img/embeddings/popup.png" alt="Popup"/>
<Frame>
<img src="/images/embeddings/popup.png" alt="Popup" />
</Frame>
## Bubble
Embeds the typebot as a "chat bubble" at the bottom right corner of your site. Can be triggered automatically or with a click. It can also come with a "proactive message".
<img src="/img/embeddings/bubble1.png" alt="Bubble 1" width="600px"/>
<Frame>
<img src="/images/embeddings/bubble1.png" alt="Bubble 1" width="600px" />
</Frame>

View File

@ -0,0 +1,7 @@
---
title: Script embed snippet
---
The script embed option is useful only if you don't have access to the HTML tree of your application or if your website builder only allows you to inline script snippets.
Otherwise, it's preferable to follow [HTML & Javascript](./libraries/html-javascript) embed instructions because the script snippets are just scripts that will inject the code from the HTML & Javascript embed method.

View File

@ -1,4 +1,6 @@
# Webflow
---
title: Webflow
---
Head over to the Share tab of your bot and click on the Webflow button to get the embed instructions of your bot.
@ -42,4 +44,4 @@ It should look like:
Make sure to replace `BUTTON_ID_1` and `BUTTON_ID_2` with the ID you added on your button elements.
In this example we are opening the popup when the specified buttons are clicked but you could also use any of the [available commands](./commands).
In this example we are opening the popup when the specified buttons are clicked but you could also use any of the [available commands](./libraries/html-javascript#commands).

View File

@ -1,14 +1,14 @@
---
sidebar_position: 2
title: WordPress
---
# WordPress
Typebot has a native [WordPress plug-in](https://wordpress.org/plugins/typebot/) that helps you embed typebots in your WordPress site.
Of course, before using it, you need to create and publish your first typebot.
<img src="/img/embeddings/wordpress-preview.png" alt="WP plugin preview"/>
<Frame>
<img src="/images/embeddings/wordpress-preview.png" alt="WP plugin preview" />
</Frame>
The code snippet to paste is easily configurable in the Share tab of your bot after clicking on the "Wordpress" button.
@ -26,11 +26,16 @@ Examples:
## Personalize user experience
You can leverage the [prefilled variables](/editor/variables#prefilled-variables) and inject your user information directly into your typebot so that the experience is entirely customized to your user.
You can leverage the [prefilled variables](../../editor/variables#prefilled-variables) and inject your user information directly into your typebot so that the experience is entirely customized to your user.
Here are the available variables from WordPress, make sure to create them in your typebot's variables dropdown:
<img src="/img/embeddings/wp-variables.png" alt="WP predefined variables" width="400px"/>
<Frame style={{ maxWidth: '400px' }}>
<img
src="/images/embeddings/wp-variables.png"
alt="WP predefined variables"
/>
</Frame>
The only thing you need to do to enable this is:
@ -55,7 +60,9 @@ For WP Rocket:
1. Go to Settings > WP Rocket > Excluded Inline Javascript:
<img src="/img/embeddings/wp-rocket.png" width="600" alt="WP plugin preview"/>
<Frame>
<img src="/images/embeddings/wp-rocket.png" alt="WP Rocket" />
</Frame>
2. Type "typebot"
3. Save

View File

@ -1,13 +1,16 @@
# Create a WhatsApp Meta app
---
title: Create a WhatsApp Meta app
---
## 1. Create a Facebook Business account
1. Head over to https://business.facebook.com and log in
2. Create a new business account on the left side bar
:::note
It is possible that Meta automatically restricts your newly created Business account. In that case, make sure to verify your identity to proceed.
:::
<Info>
It is possible that Meta automatically restricts your newly created Business
account. In that case, make sure to verify your identity to proceed.
</Info>
## 2. Create a Meta app

View File

@ -1,18 +1,20 @@
---
sidebar_position: 1
slug: /embed/whatsapp
title: Overview
sidebarTitle: Overview
title: WhatsApp
---
# WhatsApp
WhatsApp integration is currently in beta. If you encounter any issue, please contact me directly using the Bubble in app.typebot.io.
## Preview
You can preview and test your bot by clicking on the Preview button in the editor and change the runtime to "WhatsApp".
<img src="/img/whatsapp/preview-dropdown.png" alt="WhatsApp preview dropdown" width="600px" />
<Frame>
<img
src="/images/whatsapp/preview-dropdown.png"
alt="WhatsApp preview dropdown"
/>
</Frame>
## Limitations
@ -32,7 +34,12 @@ WhatsApp environment have some limitations that you need to keep in mind when bu
You can automatically assign contact name and phone number to a variable in your bot using a Set variable block with the dedicated system values:
<img src="/img/whatsapp/contact-var.png" alt="WhatsApp contact system variables" width="600px" />
<Frame>
<img
src="/images/whatsapp/contact-var.png"
alt="WhatsApp contact system variables"
/>
</Frame>
## Deploy on your phone number
@ -42,7 +49,12 @@ Head over to the Share tab of your bot and click on the WhatsApp button to get t
You can customize how your bot behaves on WhatsApp in the `Configure integration` section
<img src="/img/whatsapp/configure-integration.png" alt="WhatsApp configure integration" width="600px" />
<Frame>
<img
src="/images/whatsapp/configure-integration.png"
alt="WhatsApp configure integration"
/>
</Frame>
**Session expiration timeout**: A number from 0 to 48 which is the number of hours after which the session will expire. If the user doesn't interact with the bot for more than the timeout, the session will expire and if user sends a new message, it will start a new chat. The default is 4 hours.
@ -52,7 +64,7 @@ You can customize how your bot behaves on WhatsApp in the `Configure integration
### How many WhatsApp numbers can I use?
You can integrate as many numbers as you'd like. Keep in mind that Typebot does not provide those numbers. We work as a "Bring your own Meta application" and we give you clear instructions on [how to set up your Meta app](./whatsapp/create-meta-app).
You can integrate as many numbers as you'd like. Keep in mind that Typebot does not provide those numbers. We work as a "Bring your own Meta application" and we give you clear instructions on [how to set up your Meta app](./create-meta-app).
### Can I link multiple bots to the same WhatsApp number?

View File

@ -1,4 +0,0 @@
{
"label": "Editor",
"position": 3
}

View File

@ -1,4 +0,0 @@
{
"label": "Blocks",
"position": 1
}

View File

@ -1,4 +0,0 @@
{
"label": "Bubbles",
"position": 2
}

View File

@ -1,31 +0,0 @@
import { FlowToBot } from '../../../../src/js/FlowToBot'
# Embed
The Embed bubble block allows you to display a website or an iframe to your user. You can paste a video URL from many sources including YouTube, Vimeo, and mp4.
<FlowToBot
flow={
<img
src="/img/blocks/bubbles/embed.png"
width="100%"
style={{ maxWidth: '600px' }}
alt="Embed bubble"
/>
}
bot={
<video controls width="100%" style={{ maxWidth: '400px' }}>
<source src="/img/blocks/bubbles/embed-chat.mp4" type="video/mp4" />
</video>
}
/>
:::note
Not all websites allow embedding. If you see a blank space, it means the website you're trying to embed doesn't allow it.
:::
## Embed a PDF hosted on Google Drive
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.

View File

@ -1,25 +0,0 @@
---
sidebar_position: 2
---
import { FlowToBot } from '../../../../src/js/FlowToBot'
# Image
The Image bubble block allows you to display an image to your user. You can upload an image, paste a URL or choose a GIF from the Giphy native integration.
<FlowToBot
flow={
<img
src="/img/blocks/bubbles/image.png"
width="100%"
style={{ maxWidth: '300px' }}
alt="Image bubble"
/>
}
bot={
<video controls width="100%" style={{ maxWidth: '400px' }}>
<source src="/img/blocks/bubbles/image-chat.mp4" type="video/mp4" />
</video>
}
/>

View File

@ -1,36 +0,0 @@
---
sidebar_position: 1
---
import { FlowToBot } from '../../../../src/js/FlowToBot'
# Text
The Text bubble block allows you to display a simple text bubble to your user. They can be chained and it will create a smooth animation:
<FlowToBot
flow={
<img
src="/img/blocks/bubbles/3-text-bubbles.png"
width="100%"
style={{ maxWidth: '300px' }}
alt="Text bubbles"
/>
}
bot={
<video controls width="100%" style={{ maxWidth: '600px' }}>
<source
src="/img/blocks/bubbles/3-text-bubbles-chat.mp4"
type="video/mp4"
/>
</video>
}
/>
## Insert a link
You can insert a link in your text bubbles using the link icon in the editor:
<img src="/img/blocks/bubbles/text-link.png" width="400" alt="Text link icon" />
You can insert any links starting with `http:`, `https:`, `mailto:`, `tel:` or `sms:`. It can also be a variable.

View File

@ -1,21 +0,0 @@
import { FlowToBot } from '../../../../src/js/FlowToBot'
# Video
The Video bubble block allows you to display a video to your user. You can paste a video URL from many sources including YouTube, Vimeo, and mp4.
<FlowToBot
flow={
<img
src="/img/blocks/bubbles/video.png"
alt="Video bubble"
width="100%"
style={{ maxWidth: '300px' }}
/>
}
bot={
<video controls width="100%" style={{ maxWidth: '500px' }}>
<source src="/img/blocks/bubbles/video-chat.mp4" type="video/mp4" />
</video>
}
/>

View File

@ -1,4 +0,0 @@
{
"label": "Inputs",
"position": 2
}

View File

@ -1,100 +0,0 @@
---
sidebar_position: 7
---
import { FlowToBot } from '../../../../src/js/FlowToBot'
import { YoutubeEmbed } from '../../../../src/js/YoutubeEmbed.jsx'
# Buttons
The Buttons input block allows you to offer your user predefined choices, either single choice options or multiple choices
## Single choice
Single choice input allows you to directly split your flow depending on what the user selects by linking any choice to a specific path in your flow.
Link the "Default" item to determine the default path independent of what the user chooses.
<FlowToBot
flow={
<img
src="/img/blocks/inputs/single-choice-flow.png"
width="100%"
style={{ maxWidth: '500px' }}
alt="Single choice in flow"
/>
}
bot={
<img
src="/img/blocks/inputs/single-choice-bot.png"
width="100%"
style={{ maxWidth: '300px' }}
alt="Single choice in bot"
/>
}
/>
## Multiple choices
<FlowToBot
flow={
<img
src="/img/blocks/inputs/multiple-choices-flow.png"
width="100%"
style={{ maxWidth: '500px' }}
alt="Multiple choices in flow"
/>
}
bot={
<video controls width="100%" style={{ maxWidth: '400px' }}>
<source
src="/img/blocks/inputs/multiple-choices-bot.mp4"
type="video/mp4"
/>
</video>
}
/>
## Dynamic items
Instead of adding items manually, you can also display a dynamic list of items based on a variable.
<img
src="/img/blocks/inputs/buttons-dynamic.png"
alt="Dynamic items list"
width="600px"
/>
This is useful when you want to display a list of items from another data source. For this to work, you first need to make sure the variable you are using contains a list of values. This list can be extracted from an integration block like Google Sheets.
## How to
### Add a "Other" button
Sometimes you want to allow your user to enter a value that is not in the predefined choices. You can do this by adding a "Other" button and connect it to a "Text" input block.
<img
src="/img/blocks/inputs/buttons-other.png"
width="100%"
style={{ maxWidth: '900px' }}
alt="Other button flow"
/>
### Different replies based on multiple choices
If you'd like to have different replies based on the multiple choices the user selects. You will need to
1. Save the answer into a variable.
2. Add a "Condition" block
3. Add comparisons based on the value of this variable
<img
src="/img/blocks/inputs/buttons-condition.png"
width="100%"
style={{ maxWidth: '900px' }}
alt="Condition multiple button flow"
/>
### Conditionally display a certain button
<YoutubeEmbed videoId="c7LhC5BRSIA" />

View File

@ -1,32 +0,0 @@
---
sidebar_position: 3
---
import { FlowToBot } from '../../../../src/js/FlowToBot'
# Email
The Email input block allows you to ask your user for an email. It will check if it is properly formatted.
<FlowToBot
flow={
<img
src="/img/blocks/inputs/email-flow.png"
width="100%"
style={{ maxWidth: '500px' }}
alt="Email input in flow"
/>
}
bot={
<img
src="/img/blocks/inputs/email-bot.png"
width="100%"
style={{ maxWidth: '300px' }}
alt="Email input in bot"
/>
}
/>
The retry message will be displayed whenever Typebot detected that the email is not properly formatted.
It won't check if the email address is **valid**. To do that, you will have to trigger a [Webhook block](/editor/blocks/integrations/webhook) and call an email validation service API.

View File

@ -1,34 +0,0 @@
---
sidebar_position: 10
---
import { FlowToBot } from '../../../../src/js/FlowToBot'
# File upload
The File upload input block allows you to collect files from your user.
<FlowToBot
flow={
<img
src="/img/blocks/inputs/file-upload-flow.png"
width="100%"
style={{ maxWidth: '500px' }}
alt="File upload input in flow"
/>
}
bot={
<img
src="/img/blocks/inputs/file-upload-bot.png"
width="100%"
style={{ maxWidth: '500px' }}
alt="File upload in bot"
/>
}
/>
The placeholder accepts [HTML](https://en.wikipedia.org/wiki/HTML).
## Size limit
There is a 10MB fixed limit per uploaded file. If you want your respondents to upload larger files, you should ask them to upload their files to a cloud storage service (e.g. Google Drive, Dropbox, etc.) and share the link with you.

View File

@ -1,28 +0,0 @@
---
sidebar_position: 2
---
import { FlowToBot } from '../../../../src/js/FlowToBot'
# Number
The Number input block allows you to ask your user for a number. You can configure a minimum, a maximum and a step:
<FlowToBot
flow={
<img
src="/img/blocks/inputs/number-flow.png"
width="100%"
style={{ maxWidth: '500px' }}
alt="Number input in flow"
/>
}
bot={
<img
src="/img/blocks/inputs/number-bot.png"
width="100%"
style={{ maxWidth: '300px' }}
alt="Number input in bot"
/>
}
/>

View File

@ -1,28 +0,0 @@
---
sidebar_position: 6
---
import { FlowToBot } from '../../../../src/js/FlowToBot'
# Phone number
The Phone number input block allows you to ask your user for a phone number and make sure it is properly formatted. It will also make sure that the number is stored in a consistent format. You can choose the default country code or leave it to international:
<FlowToBot
flow={
<img
src="/img/blocks/inputs/phone-number-flow.png"
width="100%"
style={{ maxWidth: '500px' }}
alt="Phone number input in flow"
/>
}
bot={
<img
src="/img/blocks/inputs/phone-number-bot.png"
width="100%"
style={{ maxWidth: '300px' }}
alt="Phone number input in bot"
/>
}
/>

View File

@ -1,57 +0,0 @@
---
sidebar_position: 9
---
import { FlowToBot } from '../../../../src/js/FlowToBot'
# Rating
The Rating input block allows you to ask your user for a rating.
<FlowToBot
flow={
<img
src="/img/blocks/inputs/rating-flow.png"
width="100%"
style={{ maxWidth: '500px' }}
alt="Rating in flow"
/>
}
bot={
<img
src="/img/blocks/inputs/rating-bot.png"
width="100%"
style={{ maxWidth: '300px' }}
alt="Rating in bot"
/>
}
/>
The rating input is very customizable, you can set a custom range, numbers or a custom icon, and bottom labels.
## NPS
You could for example configure it so that it collects the Net promoter score:
<FlowToBot
flow={
<img
src="/img/blocks/inputs/nps-flow.png"
width="100%"
style={{ maxWidth: '300px' }}
alt="NPS configuration"
/>
}
bot={
<img
src="/img/blocks/inputs/nps-bot.png"
width="100%"
style={{ maxWidth: '600px' }}
alt="NPS in bot"
/>
}
/>
## Custom icon
To insert a custom icon, you'll need to insert SVG content. It should start with `<svg>` and end with `</svg>`. You can find great open-source icons on [Feather](https://feathericons.com/)

View File

@ -1,55 +0,0 @@
---
sidebar_position: 1
---
import { FlowToBot } from '../../../../src/js/FlowToBot'
# Text
The Text input block allows you to ask your user for a text answer.
## Short text input
By default the text input is expecting a short answer:
<FlowToBot
flow={
<img
src="/img/blocks/inputs/short-text-flow.png"
width="100%"
style={{ maxWidth: '500px' }}
alt="Short text input in flow"
/>
}
bot={
<img
src="/img/blocks/inputs/short-text-bot.png"
width="100%"
style={{ maxWidth: '300px' }}
alt="Short text input in bot"
/>
}
/>
## Long text input
You can also ask your user for a longer text answer by enabling it in the input options:
<FlowToBot
flow={
<img
src="/img/blocks/inputs/long-text-flow.png"
width="100%"
style={{ maxWidth: '500px' }}
alt="Long text input in flow"
/>
}
bot={
<img
src="/img/blocks/inputs/long-text-bot.png"
width="100%"
style={{ maxWidth: '300px' }}
alt="Long text input in bot"
/>
}
/>

Some files were not shown because too many files have changed in this diff Show More