diff --git a/packages/typebot-js/package.json b/packages/typebot-js/package.json index 21c6cd3ba..f50eba38e 100644 --- a/packages/typebot-js/package.json +++ b/packages/typebot-js/package.json @@ -1,6 +1,6 @@ { "name": "typebot-js", - "version": "2.2.12", + "version": "2.2.13", "main": "dist/index.js", "unpkg": "dist/index.global.js", "license": "AGPL-3.0-or-later", diff --git a/packages/typebot-js/src/iframe/index.ts b/packages/typebot-js/src/iframe/index.ts index a7a7b6fa0..6b74ff558 100644 --- a/packages/typebot-js/src/iframe/index.ts +++ b/packages/typebot-js/src/iframe/index.ts @@ -1,3 +1,4 @@ +import { closeIframe } from '../embedTypes/chat/iframe' import { TypebotPostMessageData, IframeCallbacks, IframeParams } from '../types' import './style.css' @@ -55,6 +56,15 @@ export const listenForTypebotMessages = (callbacks: IframeCallbacks) => { }) } +const closeChatBubbleIfExisting = () => { + const bubble = document.querySelector('#typebot-bubble') as + | HTMLDivElement + | undefined + if (!bubble) return + const iframe = bubble.querySelector('.typebot-iframe') as HTMLIFrameElement + closeIframe(bubble, iframe) +} + const processMessage = ( data: TypebotPostMessageData, callbacks: IframeCallbacks @@ -63,4 +73,5 @@ const processMessage = ( if (data.newVariableValue && callbacks.onNewVariableValue) callbacks.onNewVariableValue(data.newVariableValue) if (data.codeToExecute) Function(data.codeToExecute)() + if (data.closeChatBubble) closeChatBubbleIfExisting() } diff --git a/packages/typebot-js/src/types.ts b/packages/typebot-js/src/types.ts index 7552344b0..6f1fde6b7 100644 --- a/packages/typebot-js/src/types.ts +++ b/packages/typebot-js/src/types.ts @@ -55,6 +55,7 @@ export type TypebotPostMessageData = { redirectUrl?: string newVariableValue?: Variable codeToExecute?: string + closeChatBubble?: boolean } export const localStorageKeys = { diff --git a/packages/typebot-js/tests/iframe.spec.ts b/packages/typebot-js/tests/iframe.spec.ts index f48f433d3..412a6cf2e 100644 --- a/packages/typebot-js/tests/iframe.spec.ts +++ b/packages/typebot-js/tests/iframe.spec.ts @@ -1,4 +1,6 @@ import { createIframe } from '../src/iframe' +import * as Typebot from '../src' +import { TypebotPostMessageData } from '../src' describe('createIframe', () => { it('should create a valid iframe element', () => { @@ -111,4 +113,27 @@ describe('createIframe', () => { expect(n).toBeUndefined() expect(v).toBeUndefined() }) + + it('should close chat when receive close command', async () => { + expect.assertions(2) + const { open } = Typebot.initBubble({ + url: 'https://typebot.io/typebot-id2', + }) + const bubble = document.getElementById('typebot-bubble') + open() + await new Promise((resolve) => setTimeout(resolve, 50)) + expect(bubble?.classList.contains('iframe-opened')).toBe(true) + const messageData: TypebotPostMessageData = { + closeChatBubble: true, + } + window.postMessage( + { + from: 'typebot', + ...messageData, + }, + '*' + ) + await new Promise((resolve) => setTimeout(resolve, 50)) + expect(bubble?.classList.contains('iframe-opened')).toBe(false) + }) })