diff --git a/packages/chat-headless/src/ChatHeadlessImpl.ts b/packages/chat-headless/src/ChatHeadlessImpl.ts index 4fc5050..88eacea 100644 --- a/packages/chat-headless/src/ChatHeadlessImpl.ts +++ b/packages/chat-headless/src/ChatHeadlessImpl.ts @@ -34,7 +34,10 @@ import { ChatEventPayLoad, } from "@yext/analytics"; import { getClientSdk } from "./utils/clientSdk"; -import { isChatEventClient } from "./models/clients/ChatEventClient"; +import { + ChatEventClient, + isChatEventClient, +} from "./models/clients/ChatEventClient"; const BASE_HANDOFF_CREDENTIALS_SESSION_STORAGE_KEY = "yext_chat_handoff_credentials"; @@ -186,7 +189,7 @@ export class ChatHeadlessImpl implements ChatHeadless { if (isChatEventClient(nextClient)) { try { if (this.sessionAgentCredentials) { - await nextClient.reinitializeSession(this.sessionAgentCredentials); + await this.reinitializeAgentSession(nextClient); } else { const creds = await nextClient.init({ conversationId: this.state.conversation.conversationId, @@ -208,6 +211,12 @@ export class ChatHeadlessImpl implements ChatHeadless { this.chatClient = nextClient; } + private async reinitializeAgentSession(client: ChatEventClient) { + this.setCanSendMessage(false); + await client.reinitializeSession(this.sessionAgentCredentials); + this.setCanSendMessage(true); + } + addClientSdk(additionalClientSdk: Record) { const { analyticsConfig } = this.config; this.config.analyticsConfig = { @@ -254,8 +263,12 @@ export class ChatHeadlessImpl implements ChatHeadless { ); return; } - + this.credentialsSessionStorageKey = `${BASE_HANDOFF_CREDENTIALS_SESSION_STORAGE_KEY}__${hostname}__${this.config.botId}`; + + if (this.sessionAgentCredentials) { + this.handoff(); + } } async report( @@ -352,10 +365,6 @@ export class ChatHeadlessImpl implements ChatHeadless { text?: string, source: MessageSource = MessageSource.USER ): Promise { - if(this.sessionAgentCredentials && !isChatEventClient(this.chatClient)) { - await this.handoff(); - } - const client = this.chatClient; if (isChatEventClient(client)) { const { conversationId, notes } = this.state.conversation; diff --git a/packages/chat-headless/tests/chatheadless.clients.test.ts b/packages/chat-headless/tests/chatheadless.clients.test.ts index f07b01f..8fdd465 100644 --- a/packages/chat-headless/tests/chatheadless.clients.test.ts +++ b/packages/chat-headless/tests/chatheadless.clients.test.ts @@ -207,7 +207,9 @@ it("reinitializes session using credentials saved in session storage", async () agent: agentClient, }); - expect(sessionStorage.getItem("yext_chat_handoff_credentials__localhost__botId")).toBeNull(); + expect( + sessionStorage.getItem("yext_chat_handoff_credentials__localhost__botId") + ).toBeNull(); // start with bot client, immediately trigger handoff await headless.getNextMessage(); @@ -220,11 +222,16 @@ it("reinitializes session using credentials saved in session storage", async () agent: agentClient, }); - // agent client is the active client - await headless.getNextMessage(); expect(agentClient.init).toHaveBeenCalledTimes(0); expect(agentClient.reinitializeSession).toHaveBeenCalledTimes(1); - expect(agentClient.reinitializeSession).toHaveBeenCalledWith("mock-conversation-id"); + expect(agentClient.reinitializeSession).toHaveBeenCalledWith( + "mock-conversation-id" + ); + + // process the async reinitializeSession + await jest.runAllTimersAsync(); + + await headless.getNextMessage(); expect(botClient.getNextMessage).toHaveBeenCalledTimes(1); expect(agentClient.processMessage).toHaveBeenCalledTimes(1); }); @@ -247,7 +254,9 @@ it("does not reinitialize session if saveToLocalStorage is false", async () => { expect(botClient.getNextMessage).toHaveBeenCalledTimes(1); expect(agentClient.init).toHaveBeenCalledTimes(1); - expect(sessionStorage.getItem("yext_chat_handoff_credentials__localhost__botId")).toBeNull(); + expect( + sessionStorage.getItem("yext_chat_handoff_credentials__localhost__botId") + ).toBeNull(); agentClient = createMockEventClient(callbacks); headless = provideChatHeadless(newConfig, {