# Get stats Source: https://docs.typebot.com/api-reference/analytics/get-stats builder GET /v1/typebots/{typebotId}/analytics/stats # Authentication Source: https://docs.typebot.com/api-reference/authentication Some API endpoints are protected, and therefore require that you authenticate using an API token. ## Generate a token 1. Navigate to your typebot dashboard ([https://app.typebot.io/typebots](https://app.typebot.io/typebots)) 2. Click on Settings & Members > My account 3. Under the "API tokens" section, click on "Create" 4. Give it a name, then click on "Create token" 5. Copy your token. Generate token ## Use your token You can authenticate by adding an `Authorization` header to all your HTTP calls. The Authorization header is formatted as such: `Authorization: Bearer ` (replace `` with your token previously generated). Example: ```sh theme={null} curl -L -X GET 'https://app.typebot.io/api/typebots/:typebotId/results' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer myAwesomeToken' ``` # Get current usage Source: https://docs.typebot.com/api-reference/billing/get-usage GET /v1/billing/usage # List invoices Source: https://docs.typebot.com/api-reference/billing/list-invoices GET /v1/billing/invoices # Continue chat Source: https://docs.typebot.com/api-reference/chat/continue-chat openapi/viewer.json POST /v1/sessions/{sessionId}/continueChat # Generate upload URL Source: https://docs.typebot.com/api-reference/chat/generate-upload-url openapi/viewer.json POST /v3/generate-upload-url Used to upload anything from the client to S3 bucket The `presignedUrl` and `formData` fields can be then used to upload the file to the S3 bucket, directly from the browser if necessary. Here is an example: ```js theme={null} // data contains the presignedUrl and formData fields from the response let upload if (data.formData && Object.keys(data.formData).length > 0) { const formData = new FormData() Object.entries(data.formData).forEach(([key, value]) => { formData.append(key, value) }) formData.append('file', file) upload = await fetch(data.presignedUrl, { method: 'POST', body: formData, }) } else { upload = await fetch(data.presignedUrl, { method: 'PUT', body: file, headers: { 'Content-Type': file.type, }, }) } ``` # Save logs Source: https://docs.typebot.com/api-reference/chat/save-logs POST /v2/sessions/{sessionId}/clientLogs # Start chat Source: https://docs.typebot.com/api-reference/chat/start-chat POST /v1/typebots/{publicId}/startChat # Start preview chat Source: https://docs.typebot.com/api-reference/chat/start-preview-chat openapi/viewer.json POST /v1/typebots/{typebotId}/preview/startChat Use this endpoint to test your bot. The answers will not be saved. And some blocks like "Send email" will be skipped. # Update typebot in session Source: https://docs.typebot.com/api-reference/chat/update-typebot-in-session POST /v1/sessions/{sessionId}/updateTypebot Update chat session with latest typebot modifications. This is useful when you want to update the typebot in an ongoing session after making changes to it. # Create a folder Source: https://docs.typebot.com/api-reference/folder/create POST /v1/folders # Delete a folder Source: https://docs.typebot.com/api-reference/folder/delete DELETE /v1/folders/{folderId} # Get a folder Source: https://docs.typebot.com/api-reference/folder/get GET /v1/folders/{folderId} # List folders Source: https://docs.typebot.com/api-reference/folder/list GET /v1/folders # Update a folder Source: https://docs.typebot.com/api-reference/folder/update PATCH /v1/folders/{folderId} # How-to Source: https://docs.typebot.com/api-reference/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: Get typebot ID ### How to find my `publicId` For published typebot execution, you need to provide the public typebot ID available here: Get typebot ID ### How to find my `workspaceId` In your workspace dashboard, head over to `Settings & Members > Workspace > Settings` and copy the workspace ID ### How to handle stream If you enabled stream, whenever a AI message should be streamed, you will receive that kind of JSON response: ```json theme={null} { "messages": [], "clientSideActions": [ { "type": "stream", "stream": true, "expectsDedicatedReply": true } ] } ``` The bot is ready to accept the message streaming. You now need to send the following query: ```sh theme={null} curl -X POST https://typebot.co/api/v2/sessions/{sessionId}/streamMessage ``` Where `{sessionId}` should be replaced by the session ID you got from the start chat response. This endpoint will send Server-Sent events with all the information to display the streamed message. Once it is done, you can contine the flow by sending a [continue chat request](./chat/continue-chat) with the streamed message as the message content. # Delete results Source: https://docs.typebot.com/api-reference/results/delete DELETE /v1/typebots/{typebotId}/results # Get a result Source: https://docs.typebot.com/api-reference/results/get GET /v1/typebots/{typebotId}/results/{resultId} # List results Source: https://docs.typebot.com/api-reference/results/list GET /v1/typebots/{typebotId}/results # List logs in result Source: https://docs.typebot.com/api-reference/results/list-logs GET /v1/typebots/{typebotId}/results/{resultId}/logs # Create a typebot Source: https://docs.typebot.com/api-reference/typebot/create POST /v1/typebots # Delete a typebot Source: https://docs.typebot.com/api-reference/typebot/delete DELETE /v1/typebots/{typebotId} # Get a typebot Source: https://docs.typebot.com/api-reference/typebot/get GET /v1/typebots/{typebotId} # Get published bot Source: https://docs.typebot.com/api-reference/typebot/get-published-bot GET /v1/typebots/{typebotId}/publishedTypebot # Import a typebot Source: https://docs.typebot.com/api-reference/typebot/import POST /v1/typebots/import # List typebots Source: https://docs.typebot.com/api-reference/typebot/list GET /v1/typebots # Publish typebot Source: https://docs.typebot.com/api-reference/typebot/publish POST /v1/typebots/{typebotId}/publish # Unpublish typebot Source: https://docs.typebot.com/api-reference/typebot/unpublish POST /v1/typebots/{typebotId}/unpublish # Update a typebot Source: https://docs.typebot.com/api-reference/typebot/update PATCH /v1/typebots/{typebotId} # Create a workspace Source: https://docs.typebot.com/api-reference/workspace/create POST /v1/workspaces # Delete a workspace Source: https://docs.typebot.com/api-reference/workspace/delete DELETE /v1/workspaces/{workspaceId} # Get a workspace Source: https://docs.typebot.com/api-reference/workspace/get GET /v1/workspaces/{workspaceId} # List workspaces Source: https://docs.typebot.com/api-reference/workspace/list GET /v1/workspaces # List members Source: https://docs.typebot.com/api-reference/workspace/list-members GET /v1/workspaces/{workspaceId}/members # Update a workspace Source: https://docs.typebot.com/api-reference/workspace/update PATCH /v1/workspaces/{workspaceId} # Typebot Schema Releases Source: https://docs.typebot.com/breaking-changes ## v6.1 * Introduces new defaults for web typebot theme to match the new Typebot branding. ## v6.0 * 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: ``` {{={{List var}}.at(-1)=}} ``` 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](./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: # Guidelines Source: https://docs.typebot.com/contribute/guidelines ## Code * When introducing new i18n keys, only provide en.json translations. The rest will be [translated in Tolgee](./guides/translation) later on. ## Pull requests * Before pushing any changes, we recommend you to build the project to make sure it's working as expected by running `bun run build` at the root of the repository. * The PR title and description should simply describe what the PR is about. We don't follow any conventions. * It's appreciated to add screenshots or videos of the changes when it's UI related * No need to add any tags * If your PR should close an issue when merged, add `Closes #` in the PR description. * We prefer to push atomic commits without bothering about commit message conventions. All of them will be squashed before being merged, so it doesn't matter. * Always let the author resolve himself the review threads he started * Once you pushed changes after a review, make sure to [re-request a review](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/requesting-a-pull-request-review#requesting-reviews-from-collaborators-and-organization-members). # Contribute to the blog Source: https://docs.typebot.com/contribute/guides/blog The [official Typebot blog](https://typebot.io/blog) is a place where we share any ideas, original content related to the chatbot industry, and Typebot itself. You are free to contribute to the blog or fix any typos you may find. 1. Head over to the [content folder](https://github.com/baptisteArno/typebot.io/tree/main/apps/landing-page/app/features/blog/content) on the Github repo. 2. Click on the blog post file you want to edit. Or create a new file by clicking on the `Add file` button. 3. If you did not already have a fork of the repository, you will be prompted to create one. 4. Once you're happy with your changes, hit `Commit changes...`. 5. Click on `Create pull request`. 6. Add a title and a description to describe your changes. 7. Click on `Create pull request`. It will be reviewed and merged if approved! ## New article guidelines * The article should be related to chatbots, or Typebot. * The article should be written in English. * The article should be original content. No plagiarism. * The article should not be 100% AI-generated. The mdx file should always start with the following frontmatter: ```md theme={null} --- title: 'My awesome blog post' description: 'A short summary of the blog post.' postedAt: '2023-11-19' author: '' --- ``` If you are a new author, you need to add your information to the `apps/landing-page/app/features/blog/data` folder. All images need to be placed under the `public/blog-assets/` folder where `` is the name of the mdx file you are creating/editing. The image file name should be in lowercase and separated by `-`. All links to other blog posts should look like `./.mdx`. Here are all the components you can use in your blog post: * `Image`: To display an image. Make sure you define width and height prop to avoid content shifting. Example: `My awesome image`. Used to wrap the image in a frame and display a caption below it. * `Info`: To display a callout block with an info icon. Example: `This is an info callout`. * `Success`: To display a callout block with a success icon. Example: `This is a success callout`. * `Warning`: To display a callout block with a warning icon. Example: `This is a warning callout`. * `Typebot`: To embed a typebot as a Standard component. Example: ``. You can provide the same props as the [Standard component](../../deploy/web/react#standard). * `YouTube`: To embed a YouTube video. Example: `` * `Cta`: To display a call-to-action that redirects to Typebot. Example: ```tsx theme={null} // Displays a CTA with default text content // Displays a minimalist CTA with just a logo and the CTA button ``` # Create a new block Source: https://docs.typebot.com/contribute/guides/create-block A blue robot forging a new block Creating a new block on Typebot is pretty easy and straightforward using our in-house framework [The Forge](../the-forge/overview). If you are considering merging this new block to the official Typebot repository, make sure to open a [Github issue](https://github.com/baptisteArno/typebot.io/issues/new) first. This will allow us to discuss the specification and the best way to implement it. 1. [Install the project locally](./local-installation) 2. Create a new branch: ```sh theme={null} git checkout -b MY_BRANCH_NAME ``` 3. Create your new block using the [Forge CLI](../the-forge/overview#forge-cli): ```sh theme={null} bun create-new-block ``` 4. The files should be generated in `packages/forge/blocks/YOUR_BLOCK_NAME` 5. Add the block's SVG logo in `packages/forge/blocks/YOUR_BLOCK_NAME/src/logo.tsx` 6. Right away you should be able to [run the application](./local-installation#running-the-project-locally) and see your newly-created logo in the sidebar of the editor. 7. Create a new action in the `packages/forge/blocks/YOUR_BLOCK_NAME/src/actions` folder. See [Action](../the-forge/action) for more information. 8. List this action in the `actions` array in `packages/forge/blocks/YOUR_BLOCK_NAME/src/index.ts` 9. Implement the action handler in `packages/forge/blocks/YOUR_BLOCK_NAME/src/handlers.ts`. See [Run](../the-forge/run) for more information. 10. To go further, check out the [Forge documentation](../the-forge/overview). Make sure to check out other blocks implementations in the [packages/forge/blocks](https://github.com/baptisteArno/typebot.io/tree/main/packages/forge/blocks) folder. ## Video tutorials Make sure to join our [Discord community](https://typebot.io/discord) to participate to these weekly office hours. # Contribute to the documentation Source: https://docs.typebot.com/contribute/guides/documentation A blue robot writing on a paper ## For a quick fix If the documentation is missing something, or you found a typo you can quickly edit the documentation: 1. Go to the documentation page you want to edit. 2. Click on the "Suggest edits" button at the bottom of the page. 3. You are redirected to a Github page where you can edit the content of the doc. 4. If you did not already have a fork of the repository, you will be prompted to create one. 5. Edit the content of the doc. 6. Hit "Commit changes...". 7. Click on "Create pull request". 8. Add a title and a description to describe your changes. 9. Click on "Create pull request". It will be reviewed and merged if approved! ## For a bigger modification If you'd like to add a new page or add a new section to the documentation: 1. [Install the project locally](./local-installation) 2. Create a new branch: ```sh theme={null} git checkout -b MY_BRANCH_NAME ``` 3. Run the docs in dev mode ```sh theme={null} cd apps/docs bun dev ``` 4. All your docs modification will be displayed in real time. 5. Once you are done, commit your changes and push your branch. 6. Create a pull request on the [Github repository](https://github.com/baptisteArno/typebot.io). It will be reviewed and merged if approved! # Install the project locally Source: https://docs.typebot.com/contribute/guides/local-installation ## Get started 1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device. ## Running the project locally 1. Make sure you have node, [bun](https://bun.sh/docs/installation) and [docker](https://docs.docker.com/compose/install/) installed. For node, I suggest you use [`proto`](https://moonrepo.dev/proto) or [`nvm`](https://github.com/nvm-sh/nvm) allowing you to manage different versions. It should then autodetect which version need to be installed before running any command. 2. Install dependencies ```sh theme={null} cd typebot.io bun install ``` 3. Set up environment variables Copy `.env.dev.example` to `.env` Check out the [Configuration guide](https://docs.typebot.io/self-hosting/configuration) if you want to enable more options 4. If you use the default DATABASE\_URL, you need a matching database running. You can do that easily with the provided `docker-compose.dev.yml` file: ```sh theme={null} docker compose -f docker-compose.dev.yml up -d ``` This will also create a minio instance to enable file uploads. 5. Start the builder and viewer ```sh theme={null} bun dev ``` Builder is available at [`http://localhost:3000`](http://localhost:3000) Viewer is available at [`http://localhost:3001`](http://localhost:3001) By default, you can easily authenticate in the builder using the "Github Sign In" button. For other options, check out the [Configuration guide](https://docs.typebot.io/self-hosting/configuration). 6. Optionnally you can also run the other available apps: For the landing page: ```sh theme={null} bunx nx dev landing-page ``` For the docs: ```sh theme={null} bunx nx dev docs ``` # Translate Source: https://docs.typebot.com/contribute/guides/translation A blue robot translating on a paper You speak a language other than English? You can help us translate the application! And it's easy! We use [Tolgee](https://tolgee.io/) to manage translations. It's a great tool that allows you to translate directly in the browser. All you need to do is to join the [Discord server](https://discord.gg/xjyQczWAXV) and ask for an access to Tolgee in the [#contributors](https://discord.com/channels/1155799591220953138/1155883114455900190) channel. You'll have a granted access and will be able to translate existing keys directly in the Tolgee platform: Tolgee translate page preview # Contribute Source: https://docs.typebot.com/contribute/overview You are considering contributing to Typebot. I and the Fair Source community thank you for this 🙏. Any contributions you make are **greatly appreciated**. There are many ways to contribute, from improving the documentation, submitting bug reports and feature requests or writing code which can be incorporated into Typebot itself. If you are considering implementing a new feature or a bug fix, please open an issue first. This will allow us to discuss the specficiation and the best way to implement it. Use the Forge. Our in-house framework to easily add new blocks on Typebot. Help us have a gigantic library of third-party native integrations on Typebot. Use our framework "The Forge" to easily implement a new block. Help us have a gigantic library of third-party native integrations on Typebot. Improve the documentation by fixing typos, adding missing information or proposing new sections. Write original content for Typebot's blog. Share your knowledge and ideas to a wider audience. The author will be credited. Report issues you encounter while using Typebot. This will help us improve the product and make it even better. Engaging with the community and helping others is a great way to contribute to the project. We'd love to see you on our Discord server. ❤️ If you don't have time to contribute to the project. You can still show your appreciation for the project and sponsor my work on Github. # Action Source: https://docs.typebot.com/contribute/the-forge/action An action is what a block can do when it is executed with Typebot. A [block](./block) can have multiple actions. Here is the `sendMessage` action definition: ```ts theme={null} import { createAction, option } from "@typebot.io/forge"; import { auth } from "../auth"; export const sendMessage = createAction({ auth, name: "Send message", options: option.object({ chatId: option.string.meta({ layout: { label: "Chat ID", placeholder: "@username", } }), text: option.string.meta({ layout: { label: "Message text", input: "textarea", } }), }), }); ``` The action execution logic is defined separately in a `handlers.ts` file. See the [Run](./run) documentation for more information. Action example ## Props The name of the action. If the block requires authentication, the auth object needs to be passed to the action. If the block has options defined (see [block props](./block#props)), this needs to be provided here. The action configuration options. See Options for more information. If the action can stream content, this function should return the variable ID that will receive the streamed content. See Server function + stream for more information. If the action displays an embed bubble that waits for an event, this function should return the variable ID where the event data will be saved. See Display embed bubble for more information. A function that returns an array of variable IDs that will be set by this action. This is used for analytics and tracking purposes. An array of fetcher references used to populate dropdown options dynamically. Each fetcher should be exported from the action file and implemented in the handlers file. See Fetcher for more information. An array of block IDs that this action can be converted into. This allows users to easily switch between similar blocks while preserving their configuration. The action execution logic is now defined separately in a `handlers.ts` file using `createActionHandler()` and `createFetcherHandler()`. Check out the Run documentation for more information on how to implement handlers. # Auth Source: https://docs.typebot.com/contribute/the-forge/auth ## Encrypted credentials The authentication type. The name of the credentials. I.e. `Twitter account`, `OpenAI account`, `Stripe keys`, etc. The schema of the data that needs to be stored. See [Options](./options) for more information. Example: ```ts theme={null} option.object({ apiKey: option.string.meta({ layout: { isRequired: true, label: "API key", withVariableButton: false, } }), }); ``` ## OAuth The authentication type for OAuth 2.0 flow. The name of the credentials. I.e. `Gmail account`, `Google Drive`, `GitHub account`, etc. The authorization URL for the OAuth provider where users will be redirected to authenticate. The token endpoint URL where the authorization code will be exchanged for access tokens. An array of OAuth scopes that define the permissions your application is requesting. An object defining the default environment variable names for the OAuth client credentials. The environment variable name for the OAuth client ID. The environment variable name for the OAuth client secret. Additional parameters to include in the authorization request. Example: ```ts theme={null} const gmailScopes = [ "https://www.googleapis.com/auth/gmail.send", "https://www.googleapis.com/auth/gmail.labels", "https://www.googleapis.com/auth/userinfo.profile", "https://www.googleapis.com/auth/userinfo.email", ] as const; export const auth = createAuth({ type: "oauth", name: "Gmail account", authUrl: "https://accounts.google.com/o/oauth2/v2/auth", tokenUrl: "https://oauth2.googleapis.com/token", scopes: gmailScopes, defaultClientEnvKeys: { id: "GMAIL_CLIENT_ID", secret: "GMAIL_CLIENT_SECRET", }, extraAuthParams: { access_type: "offline", prompt: "consent", }, }); ``` # Block Source: https://docs.typebot.com/contribute/the-forge/block After using the [CLI](./cli) to create your new block. The `index.ts` file contains the block definition. It should look like: Block name and logo match ## Props The block ID. It should be unique all the other blocks. A concise name for the block. Should be short enough to fit into a small block card. Logo used on the dark mode. The full name that will be displayed as a tooltip when the mouse hovers the block card. List of strings describing the block. Used for block searching. See Auth for more information. A list of all the possible actions that this block provides. See Action for more information The dedicated documentation URL. (i.e. `https://docs.typebot.io/editor/blocks/integrations/openai`) Provide it if all the block actions share the same properties. See Options for more information. In the block settings it will then be displayed between the auth and the actions: Block options A list of fetchers used in the provided options. See Fetcher for more information. # CLI Source: https://docs.typebot.com/contribute/the-forge/cli The CLI allows you to bootstrap a new block, creating all the necessary files and folders to get started. It asks you a few questions about your block, and then creates the files and folders for you. # Fetcher Source: https://docs.typebot.com/contribute/the-forge/fetcher Your action can have a `fetchers` property that is an array of fetcher references. Fetchers allow you to populate dropdown options dynamically by fetching data from external APIs. ## Define the fetcher in your action First, export a fetcher constant and reference it in your action: **In the action file** (`actions/createChatCompletion.ts`): ```ts theme={null} import { createAction } from "@typebot.io/forge"; import { auth } from "../auth"; // Export the fetcher constant export const modelsFetcher = { id: "fetchModels", } as const; export const createChatCompletion = createAction({ name: "Create chat completion", auth, options: option.object({ model: option.string.meta({ layout: { fetcher: modelsFetcher.id, // Reference the fetcher by its id label: "Model", placeholder: "Select a model", } }), // ... other options }), fetchers: [modelsFetcher], // Register the fetcher // ... }); ``` ## Implement the fetcher handler The fetcher implementation logic should be defined in your handlers file using `createFetcherHandler`: **In the handlers file** (`handlers.ts`): ```ts theme={null} import { createActionHandler, createFetcherHandler } from "@typebot.io/forge"; import { parseUnknownError } from "@typebot.io/lib/parseUnknownError"; import { ky } from "@typebot.io/lib/ky"; import { createChatCompletion, modelsFetcher, } from "./actions/createChatCompletion"; export default [ createActionHandler(createChatCompletion, { server: async ({ credentials, options, variables, logs }) => { // Action implementation }, }), createFetcherHandler( createChatCompletion, // Pass the action as first parameter modelsFetcher.id, // Pass the fetcher id async ({ credentials, options }) => { if (!credentials?.apiKey) return { data: [], }; try { const response = await ky .get("https://api.example.com/models", { headers: { authorization: `Bearer ${credentials.apiKey}`, }, }) .json<{ data: { id: string; name: string }[] }>(); return { data: response.data.map((model) => ({ value: model.id, label: model.name, })), }; } catch (err) { return { error: await parseUnknownError({ err }), }; } } ), ]; ``` ## Fetcher response format The fetcher function must return an object with either a `data` or `error` property: * **Success**: `{ data: (string | { label: string; value: string })[] }` * **Error**: `{ error: string | { description: string; details?: string; context?: string } }` The `data` array can contain either: * Simple strings: `["model-1", "model-2", "model-3"]` * Objects with `label` and `value`: `[{ label: "GPT-4", value: "gpt-4" }, { label: "GPT-3.5", value: "gpt-3.5-turbo" }]` ## Available parameters The fetcher handler receives the following parameters: * `credentials`: The authenticated credentials for the action * `options`: The current values of all action options (useful when you have dependencies between options) By passing the action as the first parameter to `createFetcherHandler`, TypeScript will automatically infer the correct types for `credentials` and `options`. # Options Source: https://docs.typebot.com/contribute/the-forge/options The Forge library extends the [Zod](https://github.com/colinhacks/zod) library. This means that you can use any Zod schema to validate the data that you want to store for your block. The Forge stores layout metadata on schemas using Zod's `meta()` API so the Typebot editor can render the right inputs. Options extends the `z.ZodObject` schema. The Forge provide convenient functions to create the options schema for you. Even though you could provide straight Zod schemas, we highly recommend using `option` functions to create the options schema. Here is an example of how a schema can be created using the `option` helpers and `meta()`: ```ts theme={null} option.object({ token: option.string.meta({ layout: { label: 'Token', isRequired: true, placeholder: 'Type your token...', helperText: 'You can find your token [here](https://).', } }), role: option.enum(['user', 'admin']).meta({ layout: { defaultValue: 'user', label: 'Role', } }), phoneNumber: option.string.meta({ layout: { accordion: 'Advanced settings', label: 'Phone number', placeholder: 'Type your phone number...', } }), address: option.string.meta({ layout: { accordion: 'Advanced settings', label: 'Address', placeholder: 'Type your address...', } }), isTestModeEnabled: option.boolean.meta({ layout: { label: 'Test mode', defaultValue: true, helperText: 'Enable test mode to use a test account.', } }), }) ``` Layout label ## Object ```ts theme={null} option.object({ //... }) ``` ## String Example: ```ts theme={null} option.string.meta({ layout: { label: 'Name', placeholder: 'Type a name...', withVariableButton: false, } }) ``` Layout string example ## Number Example: ```ts theme={null} option.number.meta({ layout: { label: 'Temperature', defaultValue: 1, direction: 'row', } }) ``` Layout number example ## Boolean ```ts theme={null} option.boolean.meta({ layout: { label: 'Test mode', moreInfoTooltip: 'Enable test mode to use a test account.', } }) ``` Layout boolean example ## Enum Example: ```ts theme={null} option.enum(['user', 'admin']).meta({ layout: { label: 'Role', defaultValue: 'user', } }) ``` Layout enum example ## Discriminated unions Example: ```ts theme={null} option.discriminatedUnion('type', [ option.object({ type: option.literal('user'), name: option.string.meta({ layout: { placeholder: 'Type a name...' } }), }), option.object({ type: option.literal('admin'), name: option.string.meta({ layout: { placeholder: 'Type a name...' } }), phoneNumber: option.string.meta({ layout: { placeholder: 'Type a phone number...', } }), }), ]) ``` Layout discriminated union example ## Literal Used mainly for [discriminated unions](./options#discriminated-unions). It is not visible on the Typebot editor. Example: ```ts theme={null} option.literal('user') ``` ## Array Use this to collect a list of values. Example: * A list of names ```ts theme={null} option.array(option.string.meta({ layout: { placeholder: 'Type a name...' } })).meta({ layout: { label: 'Names', itemLabel: 'name', } }) ``` Layout array example ## Helpers ### Save Response Array Use this to save the response of an array of options in variables. For example if you want your user to be able to save the response of an HTTP request to variables: ```ts theme={null} option.saveResponseArray(['Message content', 'Total tokens']).meta({ layout: { accordion: 'Save response', } }) ``` You provide the list of all the possible response values to save. Layout save response array example ## Layout props The label of the option. Will often be displayed right above the input. The placeholder of the input. The helper text of the input. Will often be displayed below the input. The name of the accordion where the option will be displayed in. For example if you'd like to group 2 properties in the same accordion named "Advanced settings", you can write: ```ts theme={null} option.object({ temperature: option.number.meta({ layout: { accordion: 'Advanced settings', } }), humidity: option.number.meta({ layout: { accordion: 'Advanced settings', } }), }) ``` The direction of the input. If set to `row`, the label will be displayed on the left of the input. The default value of the input. The tooltip that will be displayed when the user hovers the info icon of the input. Whether or not to display the variable button next to the input. The type of the input to display. Whether or not the input is required. Will display a red star next to the label if set to `true`. Set this if you'd like your input to provide a dropdown of dynamically fetched items. ```ts theme={null} option.string.meta({ layout: { fetcher: 'fetchModels', } }) ``` `fetchModels` should match the `id` of the fetcher that you defined in the `fetchers` prop of the action. See [Fetcher](./fetcher) for more information. ### Array only The label of the items of an array option. Will be displayed next to the "Add" label of the add button. Whether or not the order of the items in an array schema matters. Will display "plus" buttons above and below when hovering on an item. # Overview Source: https://docs.typebot.com/contribute/the-forge/overview A retro future illustration of a forge The Forge is a framework built by Typebot, for Typebot. It allows you to easily implement a new block. This section goes through the different concepts of this framework and how to use it. # Run Source: https://docs.typebot.com/contribute/the-forge/run Action execution logic is defined in a separate `handlers.ts` file using the `createActionHandler()` and `createFetcherHandler()` functions. This separates the action definition (schema, options) from its runtime implementation. An action handler can do one of the following things: * Execute a function on the server (most common) * If block is followed by a streamable variable, stream the variable on the client. Otherwise, execute a function on the server. * Execute a function on the client * Display a custom embed bubble ## Handlers file structure All handlers for a block should be defined in `src/handlers.ts` and exported as a default array: ```ts theme={null} import { createActionHandler, createFetcherHandler } from "@typebot.io/forge"; import { sendMessage, modelsFetcher } from "./actions/sendMessage"; import { getMessage } from "./actions/getMessage"; export default [ createActionHandler(sendMessage, { server: async ({ credentials, options, variables, logs }) => { // Implementation for sendMessage }, }), createFetcherHandler( sendMessage, modelsFetcher.id, async ({ credentials, options }) => { // Implementation for fetcher return { data: ["model-1", "model-2"], }; } ), createActionHandler(getMessage, { server: async ({ credentials, options, variables, logs }) => { // Implementation for getMessage }, }), ]; ``` The handlers array can contain two types of handlers: * **Action handlers** using `createActionHandler(action, implementation)` - Execute the action logic * **Fetcher handlers** using `createFetcherHandler(action, fetcherId, implementation)` - Populate dropdown options dynamically (see [Fetcher](./fetcher) for more details) ## Server function The most common handler is to execute a function on the server. Example: ```ts theme={null} import { createActionHandler } from "@typebot.io/forge"; import { sendMessage } from "./actions/sendMessage"; import { ky } from "@typebot.io/lib/ky"; export default [ createActionHandler(sendMessage, { server: async ({ credentials: { apiKey }, options: { botId, message, responseMapping, threadId }, variables, logs, }) => { const res: ChatNodeResponse = await ky .post(apiBaseUrl + botId, { headers: { Authorization: `Bearer ${apiKey}`, }, json: { message, chat_session_id: isEmpty(threadId) ? undefined : threadId, }, }) .json(); if (res.error) logs.add({ status: "error", description: res.error, }); responseMapping?.forEach((mapping) => { if (!mapping.variableId) return; const item = mapping.item ?? "Message"; if (item === "Message") variables.set(mapping.variableId, res.message); if (item === "Thread ID") variables.set(mapping.variableId, res.chat_session_id); }); }, }), ]; ``` As you can see, the server function takes `credentials`, `options`, `variables` and `logs` as arguments. The `credentials` are the credentials that the user has entered in the credentials block. The `options` are the options that the user has entered in the options block. The `variables` object contains helpers to save and get variables if necessary. The `logs` allows you to log anything during the function execution. These logs will be displayed as toast in the preview mode or in the Results tab on production. ## Server function + stream If your block can stream a message (like OpenAI), you need to define `getStreamVariableId` in the action and implement a stream handler. **In the action definition** (`actions/createChatCompletion.ts`): ```ts theme={null} import { createAction, option } from "@typebot.io/forge"; import { auth } from "../auth"; export const createChatCompletion = createAction({ auth, name: "Create chat completion", options: option.object({ // ... options }), getStreamVariableId: (options) => options.responseMapping?.find( (res) => res.item === "Message content" || !res.item )?.variableId, }); ``` **In the handlers file** (`handlers.ts`): ```ts theme={null} import { createActionHandler } from "@typebot.io/forge"; import { createChatCompletion } from "./actions/createChatCompletion"; import { OpenAI } from "openai"; import { OpenAIStream } from "@typebot.io/ai"; export default [ createActionHandler(createChatCompletion, { server: async (params) => { // Server implementation when streaming is not available }, stream: { run: async ({ credentials: { apiKey }, options, variables }) => { const config = { apiKey, baseURL: options.baseUrl, defaultHeaders: { "api-key": apiKey, }, defaultQuery: options.apiVersion ? { "api-version": options.apiVersion, } : undefined, } satisfies ClientOptions; const openai = new OpenAI(config); const response = await openai.chat.completions.create({ model: options.model ?? defaultOpenAIOptions.model, temperature: options.temperature ? Number(options.temperature) : undefined, stream: true, messages: parseChatCompletionMessages({ options, variables }), }); return { stream: OpenAIStream(response) }; }, }, }), ]; ``` The `getStreamVariableId` function in the action definition determines which variable should be streamed. The stream `run` function needs to return `Promise<{ stream?: ReadableStream, error?: { description: string, details?: string, context?: string } }>`. ## Client function If you want to execute a function on the client instead of the server, you can use the `web` object in your handler. This makes your block only compatible with the Web runtime. It won't work on WhatsApp for example, the block will simply be skipped. Example: ```ts theme={null} import { createActionHandler } from "@typebot.io/forge"; import { shoutName } from "./actions/shoutName"; export default [ createActionHandler(shoutName, { web: { parseFunction: ({ options }) => { return { args: { name: options.name ?? null, }, content: `alert('Hello ' + name)`, }; }, }, }), ]; ``` The web function needs to return an object with `args` and `content`. `args` is an object with arguments that are passed to the `content` context. Note that the arguments can't be `undefined`. If you want to pass a not defined argument, you need to pass `null` instead. `content` is the code that will be executed on the client. It can call the arguments passed in `args`. ## Display embed bubble If you want to display a custom embed bubble, you need to define `getEmbedSaveVariableId` in the action (if you want to save event data) and implement the display embed bubble handler. See [Cal.com block](https://github.com/baptisteArno/typebot.io/blob/main/packages/forge/blocks/calCom) as an example. **In the action definition** (`actions/bookEvent.ts`): ```ts theme={null} import { createAction, option } from "@typebot.io/forge"; import { auth } from "../auth"; export const bookEvent = createAction({ auth, name: "Book event", options: option.object({ // ... options saveResultInVariableId: option.string.meta({ layout: { inputType: "variableDropdown", } }), }), getEmbedSaveVariableId: (options) => options.saveResultInVariableId, }); ``` **In the handlers file** (`handlers.ts`): ```ts theme={null} import { createActionHandler } from "@typebot.io/forge"; import { bookEvent } from "./actions/bookEvent"; export default [ createActionHandler(bookEvent, { web: { displayEmbedBubble: { parseUrl: ({ options }) => options.url, parseInitFunction: ({ options }) => ({ args: { cal: options.cal, }, content: `// Initialize embed with typebotElement`, }), waitForEvent: { parseFunction: () => ({ args: {}, content: `// Handle event with continueFlow()`, }), }, }, }, }), ]; ``` The `getEmbedSaveVariableId` function in the action definition determines which variable will store the event data. The `displayEmbedBubble` object in the handler requires: * `parseUrl`: Returns a URL to be displayed as a text bubble in runtimes where the code can't be executed (e.g., WhatsApp) * `parseInitFunction`: Returns a function to execute on initialization. The function content can use the `typebotElement` variable to get the DOM element where the block is rendered. * `waitForEvent.parseFunction` (optional): Returns a function to handle the event. The function content can use the `continueFlow` function to continue the flow with the event data. # API Source: https://docs.typebot.com/deploy/api/overview Your bot can also be executed with HTTP requests. This is useful if you want to integrate your bot with another service or if you want to use it in a different programming language. ## Test 1. All your requests need to be authenticated with an API token. [See instructions](/api-reference/authentication). 2. To start the chat, send a POST request to `https://typebot.io/api/v1/typebots//preview/startChat` The first response will contain a sessionId that you will need for subsequent requests. 3. To send replies, send POST requests to `https://typebot.io/api/v1/sessions//continueChat` With the following JSON body: ```json theme={null} { "message": "This is my reply" } ``` Check out the [Start preview chat API reference](/api-reference/chat/start-preview-chat) for more information ## Live 1. To start the chat, send a POST request to `https://typebot.io/api/v1/typebots//startChat` The first response will contain a sessionId that you will need for subsequent requests. 2. To send replies, send POST requests to `https://typebot.io/api/v1/sessions//continueChat` With the following JSON body: ```json theme={null} { "message": "This is my reply" } ``` Check out the [Start chat API reference](/api-reference/chat/start-chat) for more information # Blink Source: https://docs.typebot.com/deploy/web/blink Head over to the Share tab of your bot and click on the Blink button to get the embed instructions specific to your bot. 1. In the Blink Admin window, head over to `Content Studio > Hub`. 2. Click on the `Add Content > Form` button. 3. For the form provider, select `Other`. 4. Paste your bot URL and customize the look and feel of this new form. 5. You can optionally add Custom Variables meaning that you can [prefill the variables](/editor/variables#prefilled-variables) in your bot with the respondant's Blink data. For example you can prefill the `Name` bot variable with the `First Name` Blink variable. Blink form configuration panel # Add a custom domain Source: https://docs.typebot.com/deploy/web/custom-domain Custom domains are available on the **Pro plan** and above. If you are on Free or Starter, the option will not appear in the Share tab. See the [pricing page](https://typebot.com/pricing) for details. You can bind a custom domain to your typebot in the "Share" tab. Add my domain button To connect a new domain, follow the instructions: Add domain instructions 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. ## Troobleshooting If your domain is not properly configured or verified, you will see this error icon next to your domain link: Error icon Make sure to click on it to see what is required to do to fix the issue. # HTML & Javascript Source: https://docs.typebot.com/deploy/web/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. There, you can change the container dimensions. Here is a code example: ```html theme={null} ``` This code is creating a container with a 100% width (will match parent width) and 600px height. ```ts theme={null} type BotProps = { id?: string; typebot: string | any; isPreview?: boolean; resultId?: string; prefilledVariables?: Record; apiHost?: string; wsHost?: string; font?: | string | { type: "Google"; family?: string | undefined; } | { type: "Custom"; url?: string | undefined; family?: string | undefined; css?: string | undefined; }; progressBarRef?: HTMLDivElement; startFrom?: | { type: "group"; groupId: string; } | { type: "event"; eventId: string; }; sessionId?: string; theme?: { chatWindow?: { backgroundColor?: string; maxWidth?: string; maxHeight?: string; }; button?: { size?: "medium" | "large" | `${number}px`; backgroundColor?: string; iconColor?: string; customIconSrc?: string; customCloseIconSrc?: string; }; previewMessage?: { backgroundColor?: string; textColor?: string; closeButtonBackgroundColor?: string; closeButtonIconColor?: string; }; position?: "fixed" | "static"; // Defaults to "fixed" placement?: "left" | "right"; // Defaults to "right" }; previewMessage?: { avatarUrl?: string; message: string; autoShowDelay?: number; }; autoShowDelay?: number; onNewInputBlock?: (inputBlock: any) => void; onAnswer?: (answer: { message: string; blockId: string }) => void; onInit?: () => void; onEnd?: () => void; onNewLogs?: ( logs: { status: string; description: string; details?: unknown; }[] ) => void; onChatStatePersisted?: (isEnabled: boolean) => void; onScriptExecutionSuccess?: (message: string) => void; }; ``` ### Multiple bots If you have different bots on the same page you will have to make them distinct with an additional `id` prop: ```html theme={null} ... ``` ## 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 theme={null} ``` This code will automatically trigger the popup window after 3 seconds. ```ts theme={null} type PopupProps = { id?: string; typebot: string | any; isPreview?: boolean; resultId?: string; prefilledVariables?: Record; apiHost?: string; wsHost?: string; font?: | string | { type: "Google"; family?: string | undefined; } | { type: "Custom"; url?: string | undefined; family?: string | undefined; css?: string | undefined; }; progressBarRef?: HTMLDivElement; startFrom?: | { type: "group"; groupId: string; } | { type: "event"; eventId: string; }; sessionId?: string; theme?: { chatWindow?: { backgroundColor?: string; maxWidth?: string; maxHeight?: string; }; button?: { size?: "medium" | "large" | `${number}px`; backgroundColor?: string; iconColor?: string; customIconSrc?: string; customCloseIconSrc?: string; }; previewMessage?: { backgroundColor?: string; textColor?: string; closeButtonBackgroundColor?: string; closeButtonIconColor?: string; }; placement?: "left" | "right"; }; previewMessage?: { avatarUrl?: string; message: string; autoShowDelay?: number; }; autoShowDelay?: number; onNewInputBlock?: (inputBlock: any) => void; onAnswer?: (answer: { message: string; blockId: string }) => void; onInit?: () => void; onEnd?: () => void; onNewLogs?: ( logs: { status: string; description: string; details?: unknown; }[] ) => void; onChatStatePersisted?: ( isEnabled: boolean, { typebotId }: { typebotId: string } ) => void; onScriptExecutionSuccess?: (message: string) => void; autoShowDelay?: number; theme?: { width?: string; backgroundColor?: string; zIndex?: number; }; defaultOpen?: boolean; isOpen?: boolean; onOpen?: () => void; onClose?: () => void; }; ``` ## Bubble You can get the bubble HTML and Javascript code by clicking on the "HTML & Javascript" button in the "Share" tab of your typebot. Here is an example: ```html theme={null} ``` This code will show the bubble and let a preview message appear after 5 seconds. ```ts theme={null} type BubbleProps = { id?: string; typebot: string | any; isPreview?: boolean; resultId?: string; prefilledVariables?: Record; apiHost?: string; wsHost?: string; font?: | string | { type: "Google"; family?: string | undefined; } | { type: "Custom"; url?: string | undefined; family?: string | undefined; css?: string | undefined; }; progressBarRef?: HTMLDivElement; startFrom?: | { type: "group"; groupId: string; } | { type: "event"; eventId: string; }; sessionId?: string; theme?: { chatWindow?: { backgroundColor?: string; maxWidth?: string; maxHeight?: string; }; button?: { isHidden?: boolean; size?: "medium" | "large" | `${number}px`; backgroundColor?: string; iconColor?: string; customIconSrc?: string; customCloseIconSrc?: string; }; previewMessage?: { backgroundColor?: string; textColor?: string; closeButtonBackgroundColor?: string; closeButtonIconColor?: string; }; placement?: "left" | "right"; }; previewMessage?: { avatarUrl?: string; message: string; autoShowDelay?: number; }; autoShowDelay?: number; isOpen?: boolean; onNewInputBlock?: (inputBlock: any) => void; onAnswer?: (answer: { message: string; blockId: string }) => void; onInit?: () => void; onEnd?: () => void; onNewLogs?: ( logs: { status: string; description: string; details?: unknown; }[] ) => void; onChatStatePersisted?: (isEnabled: boolean) => void; onScriptExecutionSuccess?: (message: string) => void; onOpen?: () => void; onClose?: () => void; onPreviewMessageClick?: () => void; onPreviewMessageDismissed?: () => void; }; ``` ### 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: ```css theme={null} typebot-bubble::part(button) {   bottom: 60px; } typebot-bubble::part(bot) {   bottom: 140px; height: calc(100% - 140px) } ``` If you have a preview message, you'll also have to manually position it: ```css theme={null} typebot-bubble::part(preview-message) {   bottom: 140px; } ``` ### Hide preview message after interaction You can hide the preview message after the user has interacted with the bot. For example, this code will show the preview message only until the user has either launched the bot or dismissed the preview message: ```js theme={null} Typebot.initBubble({ typebot: "my-typebot", previewMessage: localStorage.getItem("hideBotPreviewMessage") ? undefined : { message: "I have a question for you!" }, onPreviewMessageDismissed: () => { localStorage.setItem("hideBotPreviewMessage", "true"); }, onInit: () => { localStorage.setItem("hideBotPreviewMessage", "false"); }, }); ``` This uses the `localStorage` API to remember the state of the 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.reset()`: Resets remembered state of the bot (only useful if `Remember user` is enabled), * `Typebot.setPrefilledVariables(...)`: Set prefilled variables. Example: ```js theme={null} 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. * `Typebot.submitInput()`: Submit the currently displayed input. * `Typebot.sendCommand(...)`: Send a [command](/editor/events/command) to the bot. * `Typebot.reload()`: Reload the bot. You can bind these commands on a button element, for example: ```html theme={null} ``` For each command you can pass an optional `id` prop to target a specific typebot. I.e. `Typebot.open({ id: 'my-bubble' })` ## Callbacks If you need to trigger events on your parent website when the user interact with the bot, you can use the following callbacks: ```js theme={null} Typebot.initStandard({ typebot: "my-typebot", onNewInputBlock: (inputBlock) => { console.log("New input block displayed", inputBlock.id); }, onAnswer: (answer) => { console.log("Answer received", answer.message, answer.blockId); }, onInit: () => { console.log("Bot initialized"); }, onEnd: () => { console.log("Bot ended"); }, }); ``` ## Additional configuration You can prefill the bot variable values in your embed code by adding the `prefilledVariables` option. Here is an example: ```js theme={null} Typebot.initStandard({ typebot: "my-typebot", prefilledVariables: { "Current URL": "https://my-site/account", "User name": "John Doe", }, }); ``` It will prefill the `Current URL` variable with "[https://my-site/account](https://my-site/account)" and the `User name` variable with "John Doe". More info about variables: [here](/editor/variables). Note that if your site URL contains query params (i.e. [https://typebot.io?User%20name=John%20Doe](https://typebot.io?User%20name=John%20Doe)), the variables will automatically be injected to the typebot. So you don't need to manually transfer query params to the bot embed configuration. # Iframe Source: https://docs.typebot.com/deploy/web/iframe You can easily get your typebot iframe code by clicking on the "Iframe" button in the "Share" tab of your typebot. Iframe preview Here, you can set up its width and height. A good default is a `width` of `100%` and a `height` of `600px`. # Next.js Source: https://docs.typebot.com/deploy/web/next-js ## Install ```bash theme={null} npm install @typebot.io/react ``` ## Standard ```tsx theme={null} import { Standard } from '@typebot.io/react' const App = () => { return ( ) } ``` This code is creating a container with a 100% width (will match parent width) and 600px height. ## Popup ```tsx theme={null} import { Popup } from '@typebot.io/react' const App = () => { return } ``` This code will automatically trigger the popup window after 3 seconds. ## Bubble ```tsx theme={null} import { Bubble } from '@typebot.io/react' const App = () => { return ( ) } ``` This code will show the bubble and let a preview message appear after 5 seconds. ## Additional configuration You can prefill the bot variable values in your embed code by adding the `prefilledVariables` option. Here is an example: ```tsx theme={null} import { Standard } from '@typebot.io/react' const App = () => { return ( ) } ``` It will prefill the `Current URL` variable with "[https://my-site/account](https://my-site/account)" and the `User name` variable with "John Doe". More info about variables: [here](/editor/variables). Note that if your site URL contains query params (i.e. [https://typebot.io?User%20name=John%20Doe](https://typebot.io?User%20name=John%20Doe)), the variables will automatically be injected to the typebot. So you don't need to manually transfer query params to the bot embed configuration. # Overview Source: https://docs.typebot.com/deploy/web/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. ## Standard Embeds the typebot in a box with the size of your choice anywhere on your app. This is what is used on Typebot homepage: Standard You can also set the width to `100%` and the height to `100vh` to make it take the entire page dimensions ## Popup 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 Popup ## 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". Bubble 1 # React Source: https://docs.typebot.com/deploy/web/react ## Install ```bash theme={null} npm install @typebot.io/react ``` ## Standard ```tsx theme={null} import { Standard } from '@typebot.io/react' const App = () => { return ( ) } ``` This code is creating a container with a 100% width (will match parent width) and 600px height. ## Popup ```tsx theme={null} import { Popup } from '@typebot.io/react' const App = () => { return } ``` This code will automatically trigger the popup window after 3 seconds. ## Bubble ```tsx theme={null} import { Bubble } from '@typebot.io/react' const App = () => { return ( ) } ``` This code will show the bubble and let a preview message appear after 5 seconds. ## Additional configuration You can prefill the bot variable values in your embed code by adding the `prefilledVariables` option. Here is an example: ```tsx theme={null} import { Standard } from '@typebot.io/react' const App = () => { return ( ) } ``` It will prefill the `Current URL` variable with "[https://my-site/account](https://my-site/account)" and the `User name` variable with "John Doe". More info about variables: [here](/editor/variables). Note that if your site URL contains query params (i.e. [https://typebot.io?User%20name=John%20Doe](https://typebot.io?User%20name=John%20Doe)), the variables will automatically be injected to the typebot. So you don't need to manually transfer query params to the bot embed configuration. # Script embed snippet Source: https://docs.typebot.com/deploy/web/script 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](./html-javascript) embed instructions because the script snippets are just scripts that will inject the code from the HTML & Javascript embed method. # Webflow Source: https://docs.typebot.com/deploy/web/webflow Head over to the Share tab of your bot and click on the Webflow button to get the embed instructions of your bot. ## Advanced guides ### Trigger a typebot command on a click of a button 1. Head over to the `Settings` tab of your button and add a dedicated `ID` 2. In your typebot `Embed` element, insert this code in the existing ` ``` 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](./html-javascript#commands). # WordPress Source: https://docs.typebot.com/deploy/web/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. WP plugin preview The code snippet to paste is easily configurable in the Share tab of your bot after clicking on the "Wordpress" button. ## Excluded pages The excluded pages input is a comma-separated list of pages where you don't want your typebot to appear. Examples: * `/app/*` will exclude all pages starting with `/app/` * `/app` will only exclude the `/app` page * `/app?param=1` will only exclude the `/app` page **and** with the `param` query parameter set to `1` * `/app?param=*` will exclude the page at `/app` **and** with the `param` query parameter set to anything * `/app/*?param=*` will exclude all pages starting with `/app/` **and** with the `param` query parameter set to anything ## 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. Here are the available variables from WordPress, make sure to create them in your typebot's variables dropdown: WP predefined variables The only thing you need to do to enable this is: * Use the [Wordpress Typebot plugin](https://wordpress.com/plugins/typebot) * Have the variables declared in your Typebot with the exact syntaxes. For the email for example, make sure your variable is spelled `WP Email`. These won't work: `wp Email`, `WP email`. ## Your typebot isn't showing? ### You have litespeed with "Localise Resources" enabled There is an a box where there is a list of URLs it localises, one of them was ‘[https://cdn.jsdelivr.net’](https://cdn.jsdelivr.net’). This URL should be removed from it since it is used to import the embed library. ## You have litespeed with cache enabled Make sure to insert `web.js` and `typebot` in the JS Excludes textbox and JS Deferred Excludes under Tuning Settings. ### You have a cache plugin Plugins like WP Rocket prevent Typebot to work. For WP Rocket: 1. Go to Settings > WP Rocket > Excluded Inline Javascript: WP Rocket 2. Type "typebot" 3. Save ### You have plugin that adds `defer` attribute to external scripts You need to add an exception for Typebot in the corresponding plugin config. ### Still not working Contact me on the application using the typebot at the bottom right corner # Create a WhatsApp Meta app Source: https://docs.typebot.com/deploy/whatsapp/create-meta-app ## 1. Create a Facebook Business account 1. Head over to [https://business.facebook.com](https://business.facebook.com) and log in 2. Create a new business account on the left side bar It is possible that Meta automatically restricts your newly created Business account. In that case, make sure to verify your identity to proceed. ## 2. Create a Meta app 1. Head over to [https://developers.facebook.com/apps](https://developers.facebook.com/apps) 2. Click on Create App 3. "What do you want your app to do?", select `Other`. 4. Select `Business` type 5. Give it any name and select your newly created Business Account 6. On the app page, look for `WhatsApp` product and enable it You can then follow the instructions in the Share tab of your bot to connect your Meta app to Typebot. # WhatsApp Source: https://docs.typebot.com/deploy/whatsapp/overview ## Test You can preview and test your bot by clicking on the `Test` button in the editor and change the runtime to `WhatsApp`. WhatsApp preview dropdown ### Troubleshooting This can be due to a mismatch between the WhatsApp number displayed in your WhatsApp application profile settings and the number you have typed in Typebot. For example, some Brazilians have 2 numbers, 1 with 8 digits, the other with 9 digits. In Typebot, you need to type the number that is displayed in your WhatsApp application profile settings to make sure the bot works properly. If you don't receive the preview initial message, it means that the phone number you are using is not valid or not accepted by WhatsApp. * Make sure you can actually send a message to Typebot's business phone number (+33 7 56 95 36 64). * Make sure that you have accepted WhatsApp's latest Terms of Service. * Make sure you have the latest version of WhatsApp installed on your phone. * Make sure to type the number that is displayed in your WhatsApp application profile settings to make sure you receive the preview initial message. ## Limitations WhatsApp environment have some limitations that you need to keep in mind when building the bot: * GIF and SVG image files are not supported. They won't be displayed. * Only .mp4 videos are supported (See [Supported Media Types](https://developers.facebook.com/docs/whatsapp/cloud-api/reference/media#supported-media-types) for more info). * WhatsApp only allows to display 3 buttons at a time. So we work around that by adding "..." messages to display more buttons. * Cards input block can only display 3 buttons per card at a time. * Buttons content can't be longer than 20 characters. If the content is longer, it will be truncated. * Incompatible blocks, if present, they will be skipped: * Payment input block * Chatwoot block * Script or Set Variable block with `Execute on client` option enabled * Google Analytics block * Meta Pixel blocks * Cal.com block ## Contact information 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: WhatsApp contact system variables ## Deploy on your phone number Head over to the Share tab of your bot and click on the WhatsApp button to get the integration instructions of your bot. ### Configuration You can customize how your bot behaves on WhatsApp in the `Configure integration` section WhatsApp configure integration **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. **Start bot condition**: A condition that will be evaluated when a user starts a conversation with your bot. If the condition is not met, the bot will not be triggered. ## Collect position You can ask for the user's location with a basic [Text input block](../../editor/blocks/inputs/text). It will be saved as a variable with the latitude and longitude with the following format: `, `. Position collection flow Position collection bot ## FAQ 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). Yes, you can. You will have to add a "Start bot condition" to each of your bots to make sure that the right bot is triggered when a user starts a conversation. You integrate your typebots with your own WhatsApp Business Platform which is the official service from Meta. At the moment, the first 1,000 Service conversations each month are free. For more information, refer to their documentation ## Troubleshooting ### After publishing the bot on my phone number, it doesn't reply back It can happen that you configured your WhatsApp number, you send the first message to try it out but it never replies back. To troubleshoot this we suggest you to: 1. Make sure the bot works fine in [Test mode](#test) 2. Make sure the phone number you are using is not already used in WhatsApp Business app. If it is, you won't be able to use the same number to use with Typebot. The process of associating a phone number to Typebot blocks that number from being used for a regular WhatsApp account. Even though we recommend to use a dedicated phone number number for Typebot, you can migrate your phone number registered with WhatsApp Business app by deleting your WhatsApp Business app account. It should unlock the number after 24 hours. 3. Delete the phone number configuration on Typebot and configure it again while making sure you read all the instructions thoroughly. 4. Make sure you don't have any Start conditions or that your first message is matching the condition 5. If using a test phone number, make sure the phone number you are using to send the first message is in the list of allowed numbers of that test phone number. WhatsApp allow list # Audio Source: https://docs.typebot.com/editor/blocks/bubbles/audio The Audio bubble block allows you to play a recorded audio to your user. You can upload an audio file or directly paste a URL. Audio bubble ## Troobleshooting ### The first audio bubble is not autoplaying That is expected. Most web browser have a policy that prevents audio from playing automatically. The user needs to interact with the page before the audio can be played. ### The audio is not playing on iOS / Safari It most likely means that your audio file is malformed. Depending on where the file comes from, you need to make sure the encoding is done correctly. To check if the file is correctly encoded you should be able to download it and play the file locally on your computer. # Embed Source: https://docs.typebot.com/editor/blocks/bubbles/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. 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 bubble ## 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. ## 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 theme={null} 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. Embed bubble # Image Source: https://docs.typebot.com/editor/blocks/bubbles/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. Image bubble # Text Source: https://docs.typebot.com/editor/blocks/bubbles/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: Text bubbles ## Insert a link You can insert a link in your text bubbles using the link icon in the editor: Text link icon You can insert any links starting with `http:`, `https:`, `mailto:`, `tel:` or `sms:`. It can also be a variable. # Video Source: https://docs.typebot.com/editor/blocks/bubbles/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. Video bubble ## Video service detection When you paste a video URL, Typbot will automatically detect the video service and parse it with the proper iframe settings. It currently works with: * YouTube (video and shorts) * Vimeo * TikTok * Gumlet * OneDrive Feel free to [suggest a missing service in the feedback board](https://feedback.typebot.io/). For missing services, you can instead add an Embed bubble and paste the iframe code. ### Limitations * YouTube clips are not supported as we can't transform it to embed URL automatically. To embed a YouTube clip, you can use the [Embed bubble](/editor/blocks/bubbles/embed) and paste the iframe code that can be found in Youtube under the "Share" > "Embed" button. # Buttons Source: https://docs.typebot.com/editor/blocks/inputs/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. Buttons input in flow Buttons input in bot ## Multiple choices Multiple choices in flow ## Dynamic items Instead of adding items manually, you can also display a dynamic list of items based on a variable. Dynamic items list 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. ## Item options ### Display condition Allows you to conditionally display a specific button. ### Internal value Allows you to assign an internal value for that specific button. If your user selects this button, the internal value will be saved in the variable you've set in the `Save answer` option. ## 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. 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 Condition multiple button flow # Cards Source: https://docs.typebot.com/editor/blocks/inputs/cards The Cards input block allows you to display a list of cards in a carousel. A card can contain an image, a title, a description and several buttons. Cards input block ## Display cards from variables To display cards dynamically from variables. Make sure you have list variables. For example: * `{{Images}}` => `["https://example.com/image1.png", "https://example.com/image2.png", "https://example.com/image3.png"]` * `{{Titles}}` => `["Card 1", "Card 2", "Card 3"]` * `{{Descriptions}}` => `["Description 1", "Description 2", "Description 3"]` Simply add those variables to a single card in the flow editor and the 3 cards will be displayed in the bot. ## Save answer in variables You can store parts of the selected card into variables. Open the Cards block settings and add a mapping, then choose what to extract and which variable to save it to. Add multiple rows if you want to store several fields. Fields you can save: * **Image URL**: the URL of the selected card image. * **Title**: the selected card title. * **Description**: the selected card description. * **Button**: the label of the button the user clicked on the selected card. * **Internal Value**: a hidden value defined per card, ideal for stable identifiers (IDs, slugs). Configure it in a card’s settings under "Internal value". Cards input block # Date Source: https://docs.typebot.com/editor/blocks/inputs/date The Date input block allows you to ask your user for a date. You can ask for a specific date or range and include time: Date input in flow Date input in bot The input will use the native date picker depending on the device and browser used to answer the bot. For example on Firefox it looks like this: Date native picker ## Format The `Format` setting lets you customize the picked date format. Under the hood, it is done using the [date-fns](https://date-fns.org/) library. You can use any of the [formatting tokens](https://date-fns.org/docs/format) supported by the library. Here are some examples: ```text theme={null} yyyy-MM-dd yyyy-MM-dd HH:mm:ss dd/MM/yy dd/MM/yyyy HH:mm:ss d.MM.yy ``` There are 4 tokens that cause most of the confusion: * D and DD that represent the day of a year (1, 2, ..., 365, 366) are often confused with d and dd that represent the day of a month (1, 2, ..., 31). * YY and YYYY that represent the local week-numbering year (44, 01, 00, 17) are often confused with yy and yyyy that represent the calendar year. To help with the common confusion, on Typebot by default, we interpret the tokens `D` and `Y` as `d` and `y` respectively. More information: [https://github.com/date-fns/date-fns/blob/main/docs/unicodeTokens.md](https://github.com/date-fns/date-fns/blob/main/docs/unicodeTokens.md) # Email Source: https://docs.typebot.com/editor/blocks/inputs/email The Email input block allows you to ask your user for an email. It will check if it is properly formatted. Email input in flow 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 [HTTP request block](/editor/blocks/integrations/http-request) and call an email validation service API. # File upload Source: https://docs.typebot.com/editor/blocks/inputs/file-upload The File upload input block allows you to collect files from your user. File upload input in flow File upload input 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. ## Visibility This option allows you to choose between generating public URLs for the uploaded files or keeping them private. If you choose to keep the files private, you will be able to see the file only if you are logged in to your Typebot account. Note that if you choose to keep the files private, you will not be able to use the file URL with other blocks like Attachment in the Send email block or others. These services won't be able to read the files. By default, this option is set to `Auto`. This means that the files will be public if uploaded from the web runtime but private if uploaded from the WhatsApp runtime. Because on WhatsApp, the file is already uploaded to the WhatsApp server, so there is no need to also upload it to Typebot (only if you need to make the file URL publicly accessible). ## Allowed file types You can chose to restrict accepted file types. Add file extensions in the "Allowed file types" field to set up a whitelist of file extensions. We allow any value that is accepted by the [`accept` attribute of an HTML input of type `file`](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept#unique_file_type_specifiers). All files will be allowed by default if this field is empty. # Number Source: https://docs.typebot.com/editor/blocks/inputs/number The Number input block allows you to ask your user for a number. You can configure a minimum, a maximum and a step: Number input in flow Number input in bot ## Format This only affects how the number is displayed to the user when he submitted the answer in a bot. You can choose the format for the captured number. By default, the number is formatted as a decimal value following user's locale preferences. You can override this behavior to format it as a currency, a percentage, a scientific number, etc. # Payment Source: https://docs.typebot.com/editor/blocks/inputs/payment The Payment input block allows you to collect payment. You first need to add your Stripe: ## Connect Stripe account After clicking on `Select an account > Connect new`, a configuration popup appears: Stripe configuration * Account name could be anything you'd like it's not something that has to come from Stripe. * Test keys can be found here: [https://dashboard.stripe.com/test/apikeys](https://dashboard.stripe.com/test/apikeys) * Live keys can be found here: [https://dashboard.stripe.com/apikeys](https://dashboard.stripe.com/apikeys) Test keys will be used in the preview for testing purposes. Live keys will be used in the published bot. If you'd still like to still use the test keys in the published bot you just need to also fill in the test keys into the live keys inputs. *If you would like to simulate a successful payment, use test cards from the following list in Stripe -> [https://docs.stripe.com/testing?testing-method=card-numbers#cards](https://docs.stripe.com/testing?testing-method=card-numbers#cards)* ## Input configuration Once you have a Stripe account, you can select it and configure your input: Payment input in flow Payment input in bot Make sure to enable any payment method you'd like to appear in your Stripe dashboard at this URL: [https://dashboard.stripe.com/settings/payment\_methods](https://dashboard.stripe.com/settings/payment_methods). This is where you can enable Cards, Apple Pay, Google Pay, Alipay, WeChat Pay etc. # Phone Source: https://docs.typebot.com/editor/blocks/inputs/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: Phone number input in flow Phone number input in bot # Picture choice Source: https://docs.typebot.com/editor/blocks/inputs/picture-choice The Picture choice input block allows you to offer your user predefined choices illustrated with a picture, either single choice options or multiple choices Picture choice overview For advanced configuration, check out the [Buttons block](./buttons) documentation. It works the same way. # Rating Source: https://docs.typebot.com/editor/blocks/inputs/rating The Rating input block allows you to ask your user for a rating. Rating input in flow Rating input 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: NPS configuration NPS in bot ## Custom icon To insert a custom icon, you'll need to insert SVG content. It should start with `` and end with ``. You can find great open-source icons on [Feather](https://feathericons.com/) # Text input Source: https://docs.typebot.com/editor/blocks/inputs/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: Text input Text input ## Long text input You can also ask your user for a longer text answer by enabling it in the input options: Long text input flow Long text input bot ## Input mode The input mode option allows you to specify the type of virtual keyboard that should be displayed on mobile devices. This provides a better user experience by showing the most appropriate keyboard for the expected input. Available input modes: * **text**: Shows a standard keyboard * **decimal**: Shows a numeric keypad with decimal support * **numeric**: Shows a numeric keypad for whole numbers * **tel**: Shows a telephone keypad * **search**: Shows a keyboard optimized for search inputs * **email**: Shows a keyboard optimized for email addresses * **url**: Shows a keyboard optimized for URL entry Input mode is a hint to the browser and may not be supported on all devices or browsers. It's particularly useful for mobile devices. For more information, see the [MDN documentation](https://developer.mozilla.org/docs/Web/HTML/Reference/Global_attributes/inputmode). ## Allow attachments This option, when enabled, allows users to attach files to their message. This is useful when you want to ask for a document or a picture attached to the user messages. The generated URL will be stored in the defined variable. ## Allow audio clips This option, if enabled, displays a microphone button when the text input is empty. This allows users to record a voice message and send it to the bot. If supported, the recorded file will be a WebM file. If not, it will be an MP4 file (i.e. Safari). # Time Source: https://docs.typebot.com/editor/blocks/inputs/time The Time input block allows you to ask your user for a time. You can chose between 12 hour and 24 hour format. Time input in flow Time input in bot The input will use the native time picker depending on the device and browser used to answer the bot. For example on Chrome it looks like this: Time native picker # Website Source: https://docs.typebot.com/editor/blocks/inputs/website The Website input block allows you to ask your user for a URL. It will check if it is properly formatted. Website input in flow Website 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 [HTTP request block](/editor/blocks/integrations/http-request) and call an email validation service API. # Anthropic Source: https://docs.typebot.com/editor/blocks/integrations/anthropic ## Create Message With the Anthropic block, you can create chat messages based on your user queries and display the answer back to your typebot using Claude AI. Anthropic block Similarly to the OpenAI block, this integration comes with a convenient message type called **Dialogue**. It allows you to easily pass a sequence of saved assistant / user messages history to Claude AI: Claude AI messages sequence Then you can give the Claude AI block access to this sequence of messages: Claude AI messages sequence Finally, save the response of the assistant to a variable in order to append it in the chat history and also display it on your typebot. Claude AI assistant message variable ## Vision support `Create Chat Message` and `Ask Assistant` blocks support vision. This means that Typebot automatically detects images URL in any user message provided to OpenAI and parse it. The URL needs to be isolated from the rest of the text message to be properly detected. Here is an example of a message with an image URL: If the selected model is [not compatible with vision](https://docs.anthropic.com/en/docs/vision), the image URL will be parsed as a plain text message. ``` What's in this picture? https://domain.com/image.png ``` # Blink Source: https://docs.typebot.com/editor/blocks/integrations/blink The Blink integration allows you to interact with your [Blink](https://joinblink.com) workplace communication platform directly from your typebot. You can retrieve user information and send rich feed events to keep your team informed and engaged. ## Authentication To get started, you'll need to create a Blink app and generate an API token: 1. Follow the [official Blink instructions](https://developer.joinblink.com/docs/creating-an-integration) to create your integration 2. Generate an app token from your Blink admin dashboard 3. Add your app token to the Typebot credentials section ## Get Users The "Get Users" action allows you to retrieve user information from your Blink workspace. You can filter users by either User ID or Employee ID. ### Configuration * **Filter**: Choose between filtering by "User ID" or "Employee ID" * **Save in variables**: Select which user data fields to save in your typebot variables ### Available User Data The block can retrieve the following user information: * **Email addresses** * **Company names** * **First and last names** * **Display names** * **Initials** * **Job titles** * **Profile photo IDs** * **Timezones** * **Manager IDs** * **Department names** * **Account statuses** * **User IDs** * **Employee IDs** ## Send Feed Event The "Send Feed Event" action allows you to create rich, interactive cards in your Blink feed. These cards support various content types and interactive elements. ### Basic Configuration * **Category ID**: The Blink category where the event should be posted * **Ribbon Color**: Hex color code for the card's ribbon (e.g., #FF0000) * **Allow Comments**: Enable/disable commenting on the feed event * **Allow Reactions**: Enable/disable reactions on the feed event ### Card Content Types The Blink integration supports a rich variety of content types for your feed cards. For comprehensive UI options and examples, refer to the [official Blink CardKit documentation](https://developer.joinblink.com/docs/cardkit). ### Targeting * **User IDs**: Specific users who should see this feed event * **Group IDs**: Specific groups who should see this feed event ### Push Notifications Optionally configure a push notifications to receive whenever the feed event is posted. # Chatwoot Source: https://docs.typebot.com/editor/blocks/integrations/chatwoot The Chatwoot integration block allows you to open a Chatwoot widget to allow your user to directly talk to a human. It allows you to add a Live Chat layer on your typebot. ## Requirements For this integration, you need a Chatwoot account and create a "Website" inbox: Create website inbox ## Setup Insert a Chatwoot block where you want to trigger the widget: Chatwoot block To find your website token, head over to Chatwoot in your Inbox settings: Find website token You can prefill user information by adding collected variables to the "Set user details" inputs. For example, if you set the "Email" input to "[john@gmail.com](mailto:john@gmail.com)" then Chatwoot will automatically associate this email to the current user. ## Custom attributes You can add these custom attributes that Typebot will automatically fill in for you: ### Result URL You can link the current result URL to the Chatwoot conversation by creating this custom attribute: Chatwoot custom attribute ### Set user behavior If you are prefilling user information, by default, if you leave the ID input empty, it will set the Chatwoot user ID as either the `Email` or the Result ID. Setting the `Email` as the ID allows us to avoid having contact not properly merged together ([https://github.com/chatwoot/chatwoot/issues/2811](https://github.com/chatwoot/chatwoot/issues/2811)) # Dify.AI Source: https://docs.typebot.com/editor/blocks/integrations/dify-ai This block allows you to integrate your Dify.AI's assistant in your typebot. ## Create Chat Message This action sends a user message to your agent. Then you can save `Answer` to a variable and display it in your typebot. You are expected to provide the following parameters: * `Query`: The user message you want to send to your agent. * `Conversation ID`: The conversation ID you want to use for this message. If you don't provide one, a new conversation will be created. This variable content will be updated automatically if a new conversation is created. * `User`: The user email used to identify the user in the conversation. ## Query Knowledge Base This action queries your Dify.AI's knowledge base for the most relevant documents based on a query. This query could be the last user message to look for content that is relevant to the user's reply for example. The retrieved chunks of information can be then saved into a variable that you can use in your typebot, for example you can add the chunks to the context of your AI block to help it answer the user's query. # ElevenLabs Source: https://docs.typebot.com/editor/blocks/integrations/elevenlabs This block allows you to integrate ElevenLabs API into your typebot. ## Convert text to speech Allows you to transform a text into a speech using ElevenLabs voices and models. This action automatically create a temporary link to the audio file. This link can be used in a [Audio bubble](../bubbles/audio) for example. # Gmail Source: https://docs.typebot.com/editor/blocks/integrations/gmail The Gmail integration allows you to send emails directly through your Gmail account using Google's Gmail API. This provides a more reliable and feature-rich email sending experience compared to generic SMTP. ## Authentication The Gmail integration requires OAuth2 authentication to access your Gmail account. You can connect with Typebot default OAuth app or use your own credentials. ## Configuration Options ### Basic Settings * **To**: The recipient's email address * **Subject**: The email subject line * **Body**: The email content (supports plain text and HTML) * **Attachments**: Include file attachments (variable containing file URLs) ### Advanced Settings * **Label**: Apply a Gmail label to the sent email * **From**: Specify a custom sender name and email (e.g., "John Doe \<[john.doe@gmail.com](mailto:john.doe@gmail.com)>"). By default, the sender name and email is the one of the account used to connect to Gmail. * **Reply To**: Set a different email address for replies * **Thread ID**: Send email as a reply to an existing conversation thread ## Attachments You can attach files to your Gmail emails by providing a variable that contains file URLs. The attachments can be: * A single file URL (string) * Multiple file URLs (array of strings) Gmail has a 25MB total attachment size limit. Make sure your combined attachments don't exceed this limit. ## Response Mapping The Gmail block can save response data to variables: * **Thread ID**: The conversation thread ID (useful for tracking email conversations) # Google Analytics Source: https://docs.typebot.com/editor/blocks/integrations/google-analytics The Google Analytics integration block allows you to track a Google Analytics event at a given moment in your flow. Google Analytics block When your flow contains a Google Analytics block, under the hood it: * Initialize GA and track a "Page view" event on page load. * Track the event if any when the block is executed. ## Track conversions with Google Ads To track conversions for your Google Ad, you can add a Google Analytics block whenever you'd like to trigger the conversion event with the following properties: * Event action: conversion * Send to: \ * Value (optional): a number to quantify the conversion ## Troubleshooting To help you debug how your Google Analytics behaves, I suggest you add the [Google Analytics Debugger](https://chrome.google.com/webstore/detail/google-analytics-debugger/jnkmfdileelhofjcijamephohjechhna) extension to your browser. # Google Sheets Source: https://docs.typebot.com/editor/blocks/integrations/google-sheets With the Google Sheets integration step, you can inject, update or get data from Google Spreadsheets. For an overview of how it works check out this video