Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chat-core-zendesk: add support for session reinitialization #53

Merged
merged 6 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/chat-core-aws-connect/THIRD-PARTY-NOTICES
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ The following NPM packages may be included in this product:
- @types/[email protected]
- @types/[email protected]
- @types/[email protected]
- @types/node@22.5.5
- @types/node@22.7.4
- @types/[email protected]
- @types/[email protected]
- @types/[email protected]
Expand Down Expand Up @@ -1863,7 +1863,7 @@ SOFTWARE.

The following NPM package may be included in this product:

- [email protected].12
- [email protected].13

This package contains the following license and notice below:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ export interface ChatCoreAwsConnect
| [init(messageResponse)](./chat-core-aws-connect.chatcoreawsconnect.init.md) | Initialize the Amazon Connect chat session using the credentials from the Chat API. |
| [on(eventName, cb)](./chat-core-aws-connect.chatcoreawsconnect.on.md) | Register a callback for an event triggered within the Amazon Connect chat session. Supported events are: - <code>message</code>: A new message has been received. - <code>typing</code>: The agent is typing. - <code>close</code>: The chat session has been closed. |
| [processMessage(request)](./chat-core-aws-connect.chatcoreawsconnect.processmessage.md) | Process a message sent by the user. |
| [reinitializeSession(\_)](./chat-core-aws-connect.chatcoreawsconnect.reinitializesession.md) | Reinitialize the session using existing session data. |
| [resetSession()](./chat-core-aws-connect.chatcoreawsconnect.resetsession.md) | Resets the [ChatCoreAwsConnect](./chat-core-aws-connect.chatcoreawsconnect.md) instance, clearing the underlying Amazon Connect session. |

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@yext/chat-core-aws-connect](./chat-core-aws-connect.md) &gt; [ChatCoreAwsConnect](./chat-core-aws-connect.chatcoreawsconnect.md) &gt; [reinitializeSession](./chat-core-aws-connect.chatcoreawsconnect.reinitializesession.md)

## ChatCoreAwsConnect.reinitializeSession() method

Reinitialize the session using existing session data.

**Signature:**

```typescript
reinitializeSession(_: unknown): Promise<void>;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| \_ | unknown | |

**Returns:**

Promise&lt;void&gt;

## Remarks

This is currently not supported for Amazon Connect.

Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export interface ChatCoreAwsConnect {
init(messageResponse: MessageResponse): Promise<void>;
on<T extends keyof EventMap>(eventName: T, cb: EventCallback<T>): void;
processMessage(request: MessageRequest): Promise<void>;
reinitializeSession(_: unknown): Promise<void>;
resetSession(): void;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,10 @@ export class ChatCoreAwsConnectImpl implements ChatCoreAwsConnect {
this.session.disconnectParticipant();
this.session = undefined;
}

async reinitializeSession(_: unknown): Promise<void> {
console.warn(
"Reinitializing chat session is currently not supported for AWS Connect"
);
}
}
10 changes: 10 additions & 0 deletions packages/chat-core-aws-connect/src/models/ChatCoreAwsConnect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,14 @@ export interface ChatCoreAwsConnect {
* Resets the {@link ChatCoreAwsConnect} instance, clearing the underlying Amazon Connect session.
*/
resetSession(): void;

/**
* Reinitialize the session using existing session data.
*
* @param credentials - The credentials to use to reinitialize the session.
*
* @remarks
* This is currently not supported for Amazon Connect.
*/
reinitializeSession(_: unknown): Promise<void>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ Provide the current conversation ID for the chat session.
**Signature:**

```typescript
getSession(): void;
getSession(): string | undefined;
```
**Returns:**

void
string \| undefined

Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Initialize the Amazon Connect chat session using the credentials from the Chat A
**Signature:**

```typescript
init(messageResponse: MessageResponse): Promise<void>;
init(messageResponse: MessageResponse): Promise<ChatCoreZendeskSessionCredentials>;
```

## Parameters
Expand All @@ -20,5 +20,5 @@ init(messageResponse: MessageResponse): Promise<void>;

**Returns:**

Promise&lt;void&gt;
Promise&lt;ChatCoreZendeskSessionCredentials&gt;

Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ export interface ChatCoreZendesk
| [init(messageResponse)](./chat-core-zendesk.chatcorezendesk.init.md) | Initialize the Amazon Connect chat session using the credentials from the Chat API. |
| [on(eventName, cb)](./chat-core-zendesk.chatcorezendesk.on.md) | Register a callback for an event triggered within the Zendesk chat session. Supported events are: - <code>message</code>: A new message has been received. - <code>typing</code>: The agent is typing. - <code>close</code>: The chat session has been closed (e.g. agent left or closed the ticket). |
| [processMessage(request)](./chat-core-zendesk.chatcorezendesk.processmessage.md) | Process a message sent by the user. |
| [reinitializeSession(credentials)](./chat-core-zendesk.chatcorezendesk.reinitializesession.md) | Reinitialize the session using existing session data. |
| [resetSession()](./chat-core-zendesk.chatcorezendesk.resetsession.md) | Reset the chat session by clearing the current conversation ID. |

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@yext/chat-core-zendesk](./chat-core-zendesk.md) &gt; [ChatCoreZendesk](./chat-core-zendesk.chatcorezendesk.md) &gt; [reinitializeSession](./chat-core-zendesk.chatcorezendesk.reinitializesession.md)

## ChatCoreZendesk.reinitializeSession() method

Reinitialize the session using existing session data.

**Signature:**

```typescript
reinitializeSession(credentials: ChatCoreZendeskSessionCredentials): Promise<void>;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| credentials | ChatCoreZendeskSessionCredentials | The credentials to use to reinitialize the session. |

**Returns:**

Promise&lt;void&gt;

6 changes: 4 additions & 2 deletions packages/chat-core-zendesk/etc/chat-core-zendesk.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ import { MessageResponse } from '@yext/chat-core';
// @public
export interface ChatCoreZendesk {
emit<T extends keyof EventMap>(eventName: T, data: EventMap[T]): void;
getSession(): void;
init(messageResponse: MessageResponse): Promise<void>;
getSession(): string | undefined;
// Warning: (ae-forgotten-export) The symbol "ChatCoreZendeskSessionCredentials" needs to be exported by the entry point index.d.ts
popestr marked this conversation as resolved.
Show resolved Hide resolved
init(messageResponse: MessageResponse): Promise<ChatCoreZendeskSessionCredentials>;
// Warning: (ae-forgotten-export) The symbol "EventMap" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "EventCallback" needs to be exported by the entry point index.d.ts
on<T extends keyof EventMap>(eventName: T, cb: EventCallback<T>): void;
processMessage(request: MessageRequest): Promise<void>;
reinitializeSession(credentials: ChatCoreZendeskSessionCredentials): Promise<void>;
resetSession(): void;
}

Expand Down
28 changes: 24 additions & 4 deletions packages/chat-core-zendesk/src/infra/ChatCoreZendeskImpl.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
import { MessageRequest, MessageResponse } from "@yext/chat-core";
import { ChatCoreZendesk } from "../models";

/**
* Issue 1: Smooch Version
Expand Down Expand Up @@ -32,6 +33,7 @@ const Smooch = (SmoochLib.default || SmoochLib) as typeof SmoochLib;

import { ChatCoreZendeskConfig } from "../models/ChatCoreZendeskConfig";
import { EventCallback, EventMap } from "../models/EventCallback";
import { ChatCoreZendeskSessionCredentials } from "../models/ChatCoreZendeskSessionCredentials";

const MetadataChatSDKKey = "YEXT_CHAT_SDK";

Expand All @@ -43,7 +45,7 @@ const MetadataChatSDKKey = "YEXT_CHAT_SDK";
*
* @internal
*/
export class ChatCoreZendeskImpl {
export class ChatCoreZendeskImpl implements ChatCoreZendesk {
private eventListeners: { [T in keyof EventMap]?: EventCallback<T>[] } = {};
private conversationId: string | undefined;
private integrationId: string;
Expand All @@ -63,7 +65,12 @@ export class ChatCoreZendeskImpl {
* mode on the first invocation. Subsequent calls to this method will create a
* new conversation session.
*/
async init(messageRsp: MessageResponse): Promise<void> {
async init(messageRsp: MessageResponse): Promise<ChatCoreZendeskSessionCredentials> {
await this.initializeZendeskSdk();
return this.createZendeskConversation(messageRsp);
}

private async initializeZendeskSdk(): Promise<void> {
const divId = "yext-chat-core-zendesk-container";
if (!window.document.getElementById(divId)) {
const div = window.document.createElement("div");
Expand All @@ -83,15 +90,16 @@ export class ChatCoreZendeskImpl {
}
this.setupEventListeners();
}
await this.setupSession(messageRsp);
}

/**
* Set up a new session by creating a new conversation with the Smooch SDK.
* On ticket creation, the metadata is set to include the tag "yext-chat"
* with the conversation summary as the initial message.
*/
private async setupSession(messageRsp: MessageResponse) {
private async createZendeskConversation(
messageRsp: MessageResponse
): Promise<ChatCoreZendeskSessionCredentials> {
const ticketFields: Record<string, unknown> = {};
try {
if (messageRsp.integrationDetails?.zendeskHandoff?.ticketFields) {
Expand Down Expand Up @@ -133,6 +141,10 @@ export class ChatCoreZendeskImpl {
}`,
this.conversationId
);

return {
conversationId: convo.id,
};
}

private setupEventListeners() {
Expand Down Expand Up @@ -208,6 +220,14 @@ export class ChatCoreZendeskImpl {
}

resetSession(): void {
// @ts-ignore - off() is not in the Smooch types, but does exist
Smooch.off();
this.conversationId = undefined;
popestr marked this conversation as resolved.
Show resolved Hide resolved
}

async reinitializeSession(credentials: ChatCoreZendeskSessionCredentials): Promise<void> {
this.conversationId = credentials.conversationId;
await this.initializeZendeskSdk();
await Smooch.loadConversation(credentials.conversationId);
}
}
12 changes: 10 additions & 2 deletions packages/chat-core-zendesk/src/models/ChatCoreZendesk.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { MessageRequest, MessageResponse } from "@yext/chat-core";
import { EventCallback, EventMap } from "./EventCallback";
import { ChatCoreZendeskSessionCredentials } from "./ChatCoreZendeskSessionCredentials";

/**
* Provides methods for interacting with Chat's Zendesk integration.
Expand All @@ -12,7 +13,7 @@ export interface ChatCoreZendesk {
*
* @param messageResponse - The response returned from a successful call to the Chat API.
*/
init(messageResponse: MessageResponse): Promise<void>;
init(messageResponse: MessageResponse): Promise<ChatCoreZendeskSessionCredentials>;

/**
* Register a callback for an event triggered within the Zendesk chat session.
Expand Down Expand Up @@ -46,10 +47,17 @@ export interface ChatCoreZendesk {
/**
* Provide the current conversation ID for the chat session.
*/
getSession(): void;
getSession(): string | undefined;

/**
* Reset the chat session by clearing the current conversation ID.
*/
resetSession(): void;

/**
* Reinitialize the session using existing session data.
*
* @param credentials - The credentials to use to reinitialize the session.
*/
reinitializeSession(credentials: ChatCoreZendeskSessionCredentials): Promise<void>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Credentials for the Zendesk session created by the {@link ChatCoreZendesk}.
* Used for reinitializing the session across page reloads.
*
* @public
*/
export interface ChatCoreZendeskSessionCredentials {
/**
* The conversation ID for the current chat session.
*/
conversationId: string;
}
5 changes: 3 additions & 2 deletions packages/chat-core-zendesk/tests/ChatCoreZendesk.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ jest.mock("smooch", () => ({
on: jest.fn(),
startTyping: jest.fn(),
stopTyping: jest.fn(),
off: jest.fn(),
}));

beforeEach(() => {
Expand All @@ -58,11 +59,11 @@ describe("chat session initialization", () => {
);
});

it("returns no error when successfully connecting to chat session", async () => {
it("returns convo id and no error when successfully connecting to chat session", async () => {
const chatCoreZendesk = provideChatCoreZendesk(mockConfig);
await expect(
chatCoreZendesk.init(mockMessageResponse())
).resolves.toBeUndefined();
).resolves.toStrictEqual({conversationId: "mock-conversation-id"});
});

it("avoid rendering smooch web widget on subsequent initialization", async () => {
Expand Down
Loading