🧑‍💻 Add reload embed command

This commit is contained in:
Baptiste Arnaud 2025-05-22 08:38:49 +02:00
parent 0552d14053
commit c94266dbff
No known key found for this signature in database
13 changed files with 87 additions and 40 deletions

View File

@ -401,6 +401,7 @@ Here are the commands you can use to trigger your embedded typebot:
- `Typebot.setInputValue(...)`: Set the value in 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:

View File

@ -1,6 +1,6 @@
{
"name": "@typebot.io/js",
"version": "0.5.0",
"version": "0.6.0",
"description": "Javascript library to display typebots on your website",
"license": "FSL-1.1-ALv2",
"type": "module",

View File

@ -129,6 +129,9 @@ export const Bubble = (props: BubbleProps) => {
case "unmount":
unmountBubble();
break;
case "reload":
reloadBot();
break;
}
};
@ -151,6 +154,11 @@ export const Bubble = (props: BubbleProps) => {
isOpen() ? closeBot() : openBot();
};
const reloadBot = () => {
setHasOpenedOnce(false);
setHasOpenedOnce(true);
};
const handlePreviewMessageClick = () => {
bubbleProps.onPreviewMessageClick?.();
openBot();

View File

@ -8,3 +8,4 @@ export * from "./utils/setPrefilledVariables";
export * from "./utils/hidePreviewMessage";
export * from "./utils/sendCommand";
export * from "./types";
export * from "./utils/reload";

View File

@ -8,7 +8,13 @@ export type CommandData = CommandArgs & {
isFromTypebot: boolean;
} & (
| {
command: "open" | "toggle" | "close" | "hidePreviewMessage" | "unmount";
command:
| "open"
| "toggle"
| "close"
| "hidePreviewMessage"
| "unmount"
| "reload";
}
| ShowMessageCommandData
| SetPrefilledVariablesCommandData

View File

@ -0,0 +1,10 @@
import type { CommandArgs, CommandData } from "../types";
export const reload = ({ id }: CommandArgs = {}) => {
const message: CommandData = {
isFromTypebot: true,
command: "reload",
id,
};
window.postMessage(message);
};

View File

@ -88,14 +88,26 @@ export const Popup = (props: PopupProps) => {
const processIncomingEvent = (event: MessageEvent<CommandData>) => {
const { data } = event;
if (!data.isFromTypebot || (data.id && botProps.id !== data.id)) return;
if (data.command === "open") openBot();
if (data.command === "close") closeBot();
if (data.command === "toggle") toggleBot();
if (data.command === "setPrefilledVariables")
setPrefilledVariables((existingPrefilledVariables) => ({
...existingPrefilledVariables,
...data.variables,
}));
switch (data.command) {
case "open":
openBot();
break;
case "close":
closeBot();
break;
case "toggle":
toggleBot();
break;
case "setPrefilledVariables":
setPrefilledVariables((existingPrefilledVariables) => ({
...existingPrefilledVariables,
...data.variables,
}));
break;
case "reload":
reloadBot();
break;
}
};
const openBot = () => {
@ -117,6 +129,11 @@ export const Popup = (props: PopupProps) => {
isBotOpened() ? closeBot() : openBot();
};
const reloadBot = () => {
setIsBotOpened(false);
setIsBotOpened(true);
};
const handleOnChatStatePersisted = (isPersisted: boolean) => {
botProps.onChatStatePersisted?.(isPersisted);
if (isPersisted) setBotOpenedStateInStorage();

View File

@ -27,6 +27,13 @@ export const Standard = (
setIsBotDisplayed(true);
};
const reloadBot = () => {
setIsBotDisplayed(false);
setTimeout(() => {
setIsBotDisplayed(true);
}, 1);
};
const botLauncherObserver = new IntersectionObserver((intersections) => {
if (intersections.some((intersection) => intersection.isIntersecting))
launchBot();
@ -48,11 +55,17 @@ export const Standard = (
const processIncomingEvent = (event: MessageEvent<CommandData>) => {
const { data } = event;
if (!data.isFromTypebot || (data.id && props.id !== data.id)) return;
if (data.command === "setPrefilledVariables")
setPrefilledVariables((existingPrefilledVariables) => ({
...existingPrefilledVariables,
...data.variables,
}));
switch (data.command) {
case "setPrefilledVariables":
setPrefilledVariables((existingPrefilledVariables) => ({
...existingPrefilledVariables,
...data.variables,
}));
break;
case "reload":
reloadBot();
break;
}
};
onCleanup(() => {

View File

@ -7,6 +7,7 @@ export * from "./features/commands/utils/unmount";
export * from "./features/commands/utils/setPrefilledVariables";
export * from "./features/commands/utils/hidePreviewMessage";
export * from "./features/commands/utils/sendCommand";
export * from "./features/commands/utils/reload";
export * from "./features/commands/types";
export type { BotProps } from "./components/Bot";

View File

@ -9,7 +9,7 @@ import { showPreviewMessage } from "./features/commands/utils/showPreviewMessage
import { toggle } from "./features/commands/utils/toggle";
import { unmount } from "./features/commands/utils/unmount";
import type { PopupProps } from "./features/popup/components/Popup";
import type { BotProps } from "./index";
import { type BotProps, reload } from "./index";
export const initStandard = (props: BotProps & { id?: string }) => {
const standardElement = props.id
@ -32,27 +32,6 @@ export const initBubble = (props: BubbleProps) => {
document.body.prepend(bubbleElement);
};
type Typebot = {
initStandard: typeof initStandard;
initPopup: typeof initPopup;
initBubble: typeof initBubble;
close: typeof close;
hidePreviewMessage: typeof hidePreviewMessage;
open: typeof open;
setPrefilledVariables: typeof setPrefilledVariables;
showPreviewMessage: typeof showPreviewMessage;
toggle: typeof toggle;
setInputValue: typeof setInputValue;
unmount: typeof unmount;
sendCommand: typeof sendCommand;
};
declare const window:
| {
Typebot: Typebot | undefined;
}
| undefined;
export const parseTypebot = () => ({
initStandard,
initPopup,
@ -66,8 +45,17 @@ export const parseTypebot = () => ({
setInputValue,
unmount,
sendCommand,
reload,
});
type Typebot = ReturnType<typeof parseTypebot>;
declare const window:
| {
Typebot: Typebot;
}
| undefined;
export const injectTypebotInWindow = (typebot: Typebot) => {
if (typeof window === "undefined") return;
window.Typebot = { ...typebot };

View File

@ -1,6 +1,6 @@
{
"name": "@typebot.io/nextjs",
"version": "0.5.0",
"version": "0.6.0",
"license": "FSL-1.1-ALv2",
"description": "Convenient library to display typebots on your Next.js website",
"type": "module",

View File

@ -1,6 +1,6 @@
{
"name": "@typebot.io/react",
"version": "0.5.0",
"version": "0.6.0",
"description": "Convenient library to display typebots on your React app",
"license": "FSL-1.1-ALv2",
"type": "module",

View File

@ -3,6 +3,7 @@ import {
close,
hidePreviewMessage,
open,
reload,
sendCommand,
setInputValue,
setPrefilledVariables,
@ -20,6 +21,7 @@ export const Default = () => {
<button onClick={toggle}>Toggle chat window</button>
<button onClick={open}>Open chat window</button>
<button onClick={close}>Close chat window</button>
<button onClick={reload}>Reload chat</button>
<button onClick={() => showPreviewMessage()}>
Show Preview Message
</button>
@ -34,7 +36,7 @@ export const Default = () => {
</button>
</div>
<Bubble
typebot="my-typebot-hearhbv"
typebot="lead-generation-hdb7t54"
apiHost="http://localhost:3001"
wsHost="localhost:1999"
prefilledVariables={{