From 17684ee5b712e11cb83ca1ab5ef18a3a8b48ee3d Mon Sep 17 00:00:00 2001 From: Abhirup Basu Date: Fri, 16 Aug 2024 21:40:47 +0530 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20Reset=20remembered=20state?= =?UTF-8?q?=20if=20the=20typebot=20is=20updated=20(#1675)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wipe stored chat state if a typebot is updated. Resolves #1508 Resolves #1427 https://github.com/user-attachments/assets/7668d6a7-2916-4158-b715-1cccaeaf6ddf --------- Co-authored-by: Baptiste Arnaud --- apps/docs/openapi/viewer.json | 18 ++++++++++++++-- apps/docs/settings/remember-user.mdx | 2 ++ packages/bot-engine/apiHandlers/startChat.ts | 1 + .../bot-engine/queries/findPublicTypebot.ts | 1 + packages/bot-engine/queries/findTypebot.ts | 1 + packages/bot-engine/startSession.ts | 2 ++ packages/embeds/js/package.json | 2 +- packages/embeds/js/src/components/Bot.tsx | 21 +++++++++++++++++-- packages/embeds/nextjs/package.json | 2 +- packages/embeds/react/package.json | 2 +- .../stories/assets/leadGenerationTypebot.ts | 1 + packages/schemas/features/chat/schema.ts | 2 ++ 12 files changed, 48 insertions(+), 7 deletions(-) diff --git a/apps/docs/openapi/viewer.json b/apps/docs/openapi/viewer.json index 47714bbd3..c82d5734b 100644 --- a/apps/docs/openapi/viewer.json +++ b/apps/docs/openapi/viewer.json @@ -1148,6 +1148,9 @@ }, "settings": { "$ref": "#/components/schemas/settings" + }, + "publishedAt": { + "type": "string" } }, "required": [ @@ -1986,6 +1989,9 @@ }, "settings": { "$ref": "#/components/schemas/settings" + }, + "publishedAt": { + "type": "string" } }, "required": [ @@ -5869,6 +5875,9 @@ }, "theme": { "$ref": "#/components/schemas/theme" + }, + "updatedAt": { + "type": "string" } }, "required": [ @@ -5879,7 +5888,8 @@ "edges", "variables", "settings", - "theme" + "theme", + "updatedAt" ], "title": "Typebot V5" }, @@ -7483,6 +7493,9 @@ }, "theme": { "$ref": "#/components/schemas/theme" + }, + "updatedAt": { + "type": "string" } }, "required": [ @@ -7493,7 +7506,8 @@ "edges", "variables", "settings", - "theme" + "theme", + "updatedAt" ], "title": "Typebot V6" }, diff --git a/apps/docs/settings/remember-user.mdx b/apps/docs/settings/remember-user.mdx index a995efcc7..6be85f14d 100644 --- a/apps/docs/settings/remember-user.mdx +++ b/apps/docs/settings/remember-user.mdx @@ -11,3 +11,5 @@ There are 2 storage options: - **Local storage**: The chat state will be saved in the user's web browser. It will be available only on the same device and web browser. - **Session storage**: The chat state will be saved in the user's web browser. It will be available only on the same device and web browser, but it will be deleted when the user closes the current tab or the web browser. + +Note that if you publish a new version of your typebot, saved sessions will be automatically resetted. It means that if the user has a saved session, if he refreshes the bot and that a new version is published, the bot will restart from the beginning. diff --git a/packages/bot-engine/apiHandlers/startChat.ts b/packages/bot-engine/apiHandlers/startChat.ts index 2be6c2c2f..8d3f3a80b 100644 --- a/packages/bot-engine/apiHandlers/startChat.ts +++ b/packages/bot-engine/apiHandlers/startChat.ts @@ -96,6 +96,7 @@ export const startChat = async ({ id: typebot.id, theme: typebot.theme, settings: typebot.settings, + publishedAt: typebot.publishedAt, }, messages, input, diff --git a/packages/bot-engine/queries/findPublicTypebot.ts b/packages/bot-engine/queries/findPublicTypebot.ts index 06dcf4c37..41b0631ba 100644 --- a/packages/bot-engine/queries/findPublicTypebot.ts +++ b/packages/bot-engine/queries/findPublicTypebot.ts @@ -31,5 +31,6 @@ export const findPublicTypebot = ({ publicId }: Props) => }, }, }, + updatedAt: true, }, }) diff --git a/packages/bot-engine/queries/findTypebot.ts b/packages/bot-engine/queries/findTypebot.ts index 6d7af3c9b..39554716c 100644 --- a/packages/bot-engine/queries/findTypebot.ts +++ b/packages/bot-engine/queries/findTypebot.ts @@ -18,5 +18,6 @@ export const findTypebot = ({ id, userId }: Props) => theme: true, variables: true, isArchived: true, + updatedAt: true, }, }) diff --git a/packages/bot-engine/startSession.ts b/packages/bot-engine/startSession.ts index d38c1439b..f94b1e4f8 100644 --- a/packages/bot-engine/startSession.ts +++ b/packages/bot-engine/startSession.ts @@ -278,6 +278,7 @@ export const startSession = async ({ theme: sanitizeAndParseTheme(typebot.theme, { variables: initialState.typebotsQueue[0].typebot.variables, }), + publishedAt: typebot.updatedAt, }, dynamicTheme: parseDynamicTheme(newSessionState), logs: startLogs.length > 0 ? startLogs : undefined, @@ -296,6 +297,7 @@ export const startSession = async ({ theme: sanitizeAndParseTheme(typebot.theme, { variables: initialState.typebotsQueue[0].typebot.variables, }), + publishedAt: typebot.updatedAt, }, messages, input, diff --git a/packages/embeds/js/package.json b/packages/embeds/js/package.json index c6908b42f..d381ffb27 100644 --- a/packages/embeds/js/package.json +++ b/packages/embeds/js/package.json @@ -1,6 +1,6 @@ { "name": "@typebot.io/js", - "version": "0.3.7", + "version": "0.3.8", "description": "Javascript library to display typebots on your website", "type": "module", "main": "dist/index.js", diff --git a/packages/embeds/js/src/components/Bot.tsx b/packages/embeds/js/src/components/Bot.tsx index 36c98dee6..ababab325 100644 --- a/packages/embeds/js/src/components/Bot.tsx +++ b/packages/embeds/js/src/components/Bot.tsx @@ -150,8 +150,25 @@ export const Bot = (props: BotProps & { class?: string }) => { const initialChatInStorage = getInitialChatReplyFromStorage( data.typebot.id ) - if (initialChatInStorage) { - setInitialChatReply(initialChatInStorage) + if ( + initialChatInStorage && + initialChatInStorage.typebot.publishedAt && + data.typebot.publishedAt + ) { + if ( + new Date(initialChatInStorage.typebot.publishedAt).getTime() === + new Date(data.typebot.publishedAt).getTime() + ) { + setInitialChatReply(initialChatInStorage) + } else { + // Restart chat by resetting remembered state + wipeExistingChatStateInStorage(data.typebot.id) + setInitialChatReply(data) + setInitialChatReplyInStorage(data, { + typebotId: data.typebot.id, + storage, + }) + } } else { setInitialChatReply(data) setInitialChatReplyInStorage(data, { diff --git a/packages/embeds/nextjs/package.json b/packages/embeds/nextjs/package.json index 74201b5cd..389493e7d 100644 --- a/packages/embeds/nextjs/package.json +++ b/packages/embeds/nextjs/package.json @@ -1,6 +1,6 @@ { "name": "@typebot.io/nextjs", - "version": "0.3.7", + "version": "0.3.8", "description": "Convenient library to display typebots on your Next.js website", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/embeds/react/package.json b/packages/embeds/react/package.json index 99cc1cca1..4349b8902 100644 --- a/packages/embeds/react/package.json +++ b/packages/embeds/react/package.json @@ -1,6 +1,6 @@ { "name": "@typebot.io/react", - "version": "0.3.7", + "version": "0.3.8", "description": "Convenient library to display typebots on your React app", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/embeds/react/src/stories/assets/leadGenerationTypebot.ts b/packages/embeds/react/src/stories/assets/leadGenerationTypebot.ts index aae302204..9fb62561b 100644 --- a/packages/embeds/react/src/stories/assets/leadGenerationTypebot.ts +++ b/packages/embeds/react/src/stories/assets/leadGenerationTypebot.ts @@ -12,6 +12,7 @@ export const leadGenerationTypebot: StartTypebot = { version: '3', id: 'clckrl4q5000t3b6sabwokaar', events: null, + publishedAt: new Date(), groups: [ { id: 'clckrl4q5000g3b6skizhd262', diff --git a/packages/schemas/features/chat/schema.ts b/packages/schemas/features/chat/schema.ts index 19024e2ad..7760c51a4 100644 --- a/packages/schemas/features/chat/schema.ts +++ b/packages/schemas/features/chat/schema.ts @@ -170,6 +170,7 @@ const startTypebotPick = { variables: true, settings: true, theme: true, + updatedAt: true, } as const export const startTypebotSchema = z.preprocess( preprocessTypebot, @@ -381,6 +382,7 @@ export const startChatResponseSchema = z id: z.string(), theme: themeSchema, settings: settingsSchema, + publishedAt: z.coerce.date().optional(), }), }) .merge(chatResponseBaseSchema)