From fb7ea97c457f8e19ae45e2b5e1a7e37081b6ce10 Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Thu, 20 Mar 2025 16:22:03 -0700 Subject: [PATCH 01/27] changelog --- CHANGELOG.md | 4 ++++ src/OmnichannelChatSDK.ts | 42 ++++++++++++++++++++++----------------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02c846a0..e29dabff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Fixed + +- Issue when using setDebug leading to double load of AMS + ## [1.10.15] - 2025-03-11 ### Security diff --git a/src/OmnichannelChatSDK.ts b/src/OmnichannelChatSDK.ts index 730d567f..c3390acc 100644 --- a/src/OmnichannelChatSDK.ts +++ b/src/OmnichannelChatSDK.ts @@ -37,6 +37,7 @@ import ConversationMode from "./core/ConversationMode"; import DeliveryMode from "@microsoft/omnichannel-ic3core/lib/model/DeliveryMode"; import EmailLiveChatTranscriptOptionaParams from "./core/EmailLiveChatTranscriptOptionalParams"; import EndChatOptionalParams from "./core/EndChatOptionalParams"; +import FetchChatTokenResponse from "@microsoft/ocsdk/lib/Model/FetchChatTokenResponse"; import FileMetadata from "@microsoft/omnichannel-amsclient/lib/FileMetadata"; import FileSharingProtocolType from "@microsoft/omnichannel-ic3core/lib/model/FileSharingProtocolType"; import FramedClient from "@microsoft/omnichannel-amsclient/lib/FramedClient"; @@ -109,7 +110,6 @@ import startPolling from "./commands/startPolling"; import stopPolling from "./commands/stopPolling"; import urlResolvers from "./utils/urlResolvers"; import validateOmnichannelConfig from "./validators/OmnichannelConfigValidator"; -import FetchChatTokenResponse from "@microsoft/ocsdk/lib/Model/FetchChatTokenResponse"; class OmnichannelChatSDK { private debug: boolean; @@ -276,15 +276,17 @@ class OmnichannelChatSDK { try { if (this.liveChatVersion === LiveChatVersion.V2) { this.ACSClient = new ACSClient(this.acsClientLogger); - this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADING; - - this.AMSClient = await createAMSClient({ - framedMode: isBrowser(), - multiClient: true, - debug: false, - logger: this.amsClientLogger as PluggableLogger - }); - this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADED; + if (this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED) { + + this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADING; + this.AMSClient = await createAMSClient({ + framedMode: isBrowser(), + multiClient: true, + debug: false, + logger: this.amsClientLogger as PluggableLogger + }); + this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADED; + } } else if (this.liveChatVersion === LiveChatVersion.V1) { this.IC3Client = await this.getIC3Client(); } @@ -298,7 +300,6 @@ class OmnichannelChatSDK { private async parallelInitialization(optionalParams: InitializeOptionalParams = {}) { try { - this.scenarioMarker.startScenario(TelemetryEvent.InitializeChatSDKParallel); if (this.isInitialized) { @@ -359,13 +360,18 @@ class OmnichannelChatSDK { if (this.liveChatVersion === LiveChatVersion.V2) { this.ACSClient = new ACSClient(this.acsClientLogger); - this.AMSClient = await createAMSClient({ - framedMode: isBrowser(), - multiClient: true, - debug: false, - logger: this.amsClientLogger as PluggableLogger - }); - this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADED; + + if (this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED) { + this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADING; + this.AMSClient = await createAMSClient({ + framedMode: isBrowser(), + multiClient: true, + debug: false, + logger: this.amsClientLogger as PluggableLogger + }); + this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADED; + } + } else if (this.liveChatVersion === LiveChatVersion.V1) { this.IC3Client = await this.getIC3Client(); } From b9043ea95108f933916568d4c371ed090cd6bfc3 Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Sat, 22 Mar 2025 20:02:42 -0700 Subject: [PATCH 02/27] AMS could not be loaded if customer doesnt need it --- src/OmnichannelChatSDK.ts | 24 +++++++++++++++++------- src/core/InitializeOptionalParams.ts | 1 + 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/OmnichannelChatSDK.ts b/src/OmnichannelChatSDK.ts index c3390acc..c5febbaa 100644 --- a/src/OmnichannelChatSDK.ts +++ b/src/OmnichannelChatSDK.ts @@ -212,12 +212,13 @@ class OmnichannelChatSDK { /* istanbul ignore next */ public setDebug(flag: boolean): void { - this.debug = flag; - this.getAMSClient().then((client) => client?.setDebug(flag)); - this.telemetry?.setDebug(flag); this.scenarioMarker.setDebug(flag); + + if (this.AMSClient) { + this.AMSClient.setDebug(flag); + } loggerUtils.setDebug(flag, this.ocSdkLogger, this.acsClientLogger, this.acsAdapterLogger, this.callingSdkLogger, this.amsClientLogger, this.ic3ClientLogger); } @@ -267,6 +268,8 @@ class OmnichannelChatSDK { exceptionThrowers.throwUnsupportedLiveChatVersionFailure(new Error(ChatSDKErrorName.UnsupportedLiveChatVersion), this.scenarioMarker, TelemetryEvent.InitializeComponents); } + this.ACSClient = new ACSClient(this.acsClientLogger); + this.isInitialized = true; this.scenarioMarker.completeScenario(TelemetryEvent.InitializeComponents); } @@ -275,14 +278,13 @@ class OmnichannelChatSDK { this.scenarioMarker.startScenario(TelemetryEvent.InitializeMessagingClient); try { if (this.liveChatVersion === LiveChatVersion.V2) { - this.ACSClient = new ACSClient(this.acsClientLogger); if (this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED) { this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADING; this.AMSClient = await createAMSClient({ framedMode: isBrowser(), multiClient: true, - debug: false, + debug: this.debug, logger: this.amsClientLogger as PluggableLogger }); this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADED; @@ -307,10 +309,18 @@ class OmnichannelChatSDK { return this.liveChatConfig; } + const supportedLiveChatVersions = [LiveChatVersion.V1, LiveChatVersion.V2]; + if (!supportedLiveChatVersions.includes(this.liveChatVersion)) { + exceptionThrowers.throwUnsupportedLiveChatVersionFailure(new Error(ChatSDKErrorName.UnsupportedLiveChatVersion), this.scenarioMarker, TelemetryEvent.InitializeComponents); + } + this.useCoreServicesOrgUrlIfNotSet(); await Promise.all([this.loadInitComponents(), this.loadChatConfig(optionalParams)]); // this will load ams in the background, without holding the load - this.loadAmsClient(); + + if (!optionalParams.disableAMSClient) { + this.loadAmsClient(); + } this.isInitialized = true; this.scenarioMarker.completeScenario(TelemetryEvent.InitializeChatSDKParallel); @@ -366,7 +376,7 @@ class OmnichannelChatSDK { this.AMSClient = await createAMSClient({ framedMode: isBrowser(), multiClient: true, - debug: false, + debug: this.debug, logger: this.amsClientLogger as PluggableLogger }); this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADED; diff --git a/src/core/InitializeOptionalParams.ts b/src/core/InitializeOptionalParams.ts index 479adac3..992d0b29 100644 --- a/src/core/InitializeOptionalParams.ts +++ b/src/core/InitializeOptionalParams.ts @@ -3,6 +3,7 @@ import GetLiveChatConfigOptionalParams from "./GetLiveChatConfigOptionalParams" interface InitializeOptionalParams { getLiveChatConfigOptionalParams?: GetLiveChatConfigOptionalParams; useParallelLoad?: boolean; + disableAMSClient?: boolean; } export default InitializeOptionalParams \ No newline at end of file From 5e91be683f6401de2d47b56618c75657bc774d87 Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Sat, 22 Mar 2025 20:26:12 -0700 Subject: [PATCH 03/27] set logic for off-sync load for ams client --- src/OmnichannelChatSDK.ts | 56 ++++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/src/OmnichannelChatSDK.ts b/src/OmnichannelChatSDK.ts index c5febbaa..5a66b5e3 100644 --- a/src/OmnichannelChatSDK.ts +++ b/src/OmnichannelChatSDK.ts @@ -153,6 +153,7 @@ class OmnichannelChatSDK { private AMSClientLoadCurrentState: AMSClientLoadStates = AMSClientLoadStates.NOT_LOADED; private isMaskingDisabled = false; private maskingCharacter = "#"; + private isAMSClientDisabled = false; constructor(omnichannelConfig: OmnichannelConfig, chatSDKConfig: ChatSDKConfig = defaultChatSDKConfig) { this.debug = false; @@ -241,6 +242,10 @@ class OmnichannelChatSDK { private async getAMSClient() : Promise { + if (this.isAMSClientDisabled === true) { + throw new Error("AMSClient is disabled."); + } + if (this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED && this.liveChatVersion === LiveChatVersion.V1) { return null; } @@ -270,15 +275,27 @@ class OmnichannelChatSDK { this.ACSClient = new ACSClient(this.acsClientLogger); - this.isInitialized = true; this.scenarioMarker.completeScenario(TelemetryEvent.InitializeComponents); } + public async enableAMSClient() : Promise { + this.isAMSClientDisabled = false; + // only load ams client if the SDK is up and running, otherwise it will be loaded during initialization + if (this.isInitialized){ + await this.loadAmsClient(); + } + } + + public async disableAMSClient() : Promise { + // No need to remove the AMS client , the flag will ensure any action is not performed + this.isAMSClientDisabled = true; + } + private async loadAmsClient() : Promise { this.scenarioMarker.startScenario(TelemetryEvent.InitializeMessagingClient); try { if (this.liveChatVersion === LiveChatVersion.V2) { - if (this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED) { + if (this.isAMSClientDisabled !== true && this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED) { this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADING; this.AMSClient = await createAMSClient({ @@ -303,17 +320,13 @@ class OmnichannelChatSDK { private async parallelInitialization(optionalParams: InitializeOptionalParams = {}) { try { this.scenarioMarker.startScenario(TelemetryEvent.InitializeChatSDKParallel); + this.isAMSClientDisabled = !!optionalParams.disableAMSClient; if (this.isInitialized) { this.scenarioMarker.completeScenario(TelemetryEvent.InitializeChatSDKParallel); return this.liveChatConfig; } - const supportedLiveChatVersions = [LiveChatVersion.V1, LiveChatVersion.V2]; - if (!supportedLiveChatVersions.includes(this.liveChatVersion)) { - exceptionThrowers.throwUnsupportedLiveChatVersionFailure(new Error(ChatSDKErrorName.UnsupportedLiveChatVersion), this.scenarioMarker, TelemetryEvent.InitializeComponents); - } - this.useCoreServicesOrgUrlIfNotSet(); await Promise.all([this.loadInitComponents(), this.loadChatConfig(optionalParams)]); // this will load ams in the background, without holding the load @@ -337,6 +350,7 @@ class OmnichannelChatSDK { private async sequentialInitialization(optionalParams: InitializeOptionalParams = {}) { this.scenarioMarker.startScenario(TelemetryEvent.InitializeChatSDK); + this.isAMSClientDisabled = !!optionalParams.disableAMSClient; if (this.isInitialized) { this.scenarioMarker.completeScenario(TelemetryEvent.InitializeChatSDK); @@ -371,7 +385,7 @@ class OmnichannelChatSDK { if (this.liveChatVersion === LiveChatVersion.V2) { this.ACSClient = new ACSClient(this.acsClientLogger); - if (this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED) { + if (this.isAMSClientDisabled === false && this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED) { this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADING; this.AMSClient = await createAMSClient({ framedMode: isBrowser(), @@ -1592,12 +1606,23 @@ class OmnichannelChatSDK { } public async uploadFileAttachment(fileInfo: IFileInfo | File): Promise { - const amsClient = await this.getAMSClient(); + this.scenarioMarker.startScenario(TelemetryEvent.UploadFileAttachment, { RequestId: this.requestId, ChatId: this.chatToken.chatId as string }); + if (this.isAMSClientDisabled === true) { + this.scenarioMarker.failScenario(TelemetryEvent.UploadFileAttachment, { + RequestId: this.requestId, + ChatId: this.chatToken.chatId as string, + ExceptionDetails : "AMSClient is disabled" + }); + throw new Error('AMSClient is disabled. Please enable AMSClient to upload file attachments.'); + } + + const amsClient = await this.getAMSClient(); + if (!this.isInitialized) { exceptionThrowers.throwUninitializedChatSDK(this.scenarioMarker, TelemetryEvent.UploadFileAttachment); } @@ -1710,12 +1735,23 @@ class OmnichannelChatSDK { } public async downloadFileAttachment(fileMetadata: FileMetadata | IFileMetadata): Promise { - const amsClient = await this.getAMSClient(); + this.scenarioMarker.startScenario(TelemetryEvent.DownloadFileAttachment, { RequestId: this.requestId, ChatId: this.chatToken.chatId as string }); + if (this.isAMSClientDisabled === true) { + this.scenarioMarker.failScenario(TelemetryEvent.DownloadFileAttachment, { + RequestId: this.requestId, + ChatId: this.chatToken.chatId as string, + ExceptionDetails : "AMSClient is disabled" + }); + throw new Error('AMSClient is disabled. Please enable AMSClient to download file attachments.'); + } + + const amsClient = await this.getAMSClient(); + if (!this.isInitialized) { exceptionThrowers.throwUninitializedChatSDK(this.scenarioMarker, TelemetryEvent.DownloadFileAttachment); } From 3ad7eaa5d359844e7e44fc1805959bdd4232fda4 Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Sat, 22 Mar 2025 20:34:17 -0700 Subject: [PATCH 04/27] log --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e29dabff..1f53cf3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. ### Fixed - Issue when using setDebug leading to double load of AMS +- Add mechanism to load off sync AMS and to allow customer to opt-out during initialization ## [1.10.15] - 2025-03-11 From 56706a53affe869db58d7bceef6672b0091ad343 Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Thu, 27 Mar 2025 15:31:48 -0700 Subject: [PATCH 05/27] load of ams client based on configuration --- README.md | 6 ++- src/OmnichannelChatSDK.ts | 62 +++++++++++++--------------- src/core/InitializeOptionalParams.ts | 24 ++++++++++- 3 files changed, 57 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index fd86e35a..cf3ad9cf 100644 --- a/README.md +++ b/README.md @@ -223,10 +223,14 @@ const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, cha const optionalParams = { getLiveChatConfigOptionalParams: { - sendCacheHeaders: false // Whether to send Cache-Control HTTP header to GetChatConfig call + sendCacheHeaders: false,// Whether to send Cache-Control HTTP header to GetChatConfig call + useSequentialLoad: false // Whether to use sequential load for chat config, if not present, by default uses parallel load for faster initialization + } }; + +// For the case when the widget doesnt have enabled support for attachments, AMS wont be loaded. await chatSDK.initialize(optionalParams); ``` diff --git a/src/OmnichannelChatSDK.ts b/src/OmnichannelChatSDK.ts index 4d9075c8..ca34b6d0 100644 --- a/src/OmnichannelChatSDK.ts +++ b/src/OmnichannelChatSDK.ts @@ -153,7 +153,7 @@ class OmnichannelChatSDK { private AMSClientLoadCurrentState: AMSClientLoadStates = AMSClientLoadStates.NOT_LOADED; private isMaskingDisabled = false; private maskingCharacter = "#"; - private isAMSClientDisabled = false; + private isAMSClientAllowed = false; constructor(omnichannelConfig: OmnichannelConfig, chatSDKConfig: ChatSDKConfig = defaultChatSDKConfig) { this.debug = false; @@ -220,6 +220,7 @@ class OmnichannelChatSDK { if (this.AMSClient) { this.AMSClient.setDebug(flag); } + loggerUtils.setDebug(flag, this.ocSdkLogger, this.acsClientLogger, this.acsAdapterLogger, this.callingSdkLogger, this.amsClientLogger, this.ic3ClientLogger); } @@ -242,8 +243,9 @@ class OmnichannelChatSDK { private async getAMSClient() : Promise { - if (this.isAMSClientDisabled === true) { - throw new Error("AMSClient is disabled."); + //return null to do not break promisse creation + if (this.isAMSClientAllowed === false) { + return null; } if (this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED && this.liveChatVersion === LiveChatVersion.V1) { @@ -274,29 +276,27 @@ class OmnichannelChatSDK { } this.ACSClient = new ACSClient(this.acsClientLogger); - this.scenarioMarker.completeScenario(TelemetryEvent.InitializeComponents); } - public async enableAMSClient() : Promise { - this.isAMSClientDisabled = false; - // only load ams client if the SDK is up and running, otherwise it will be loaded during initialization - if (this.isInitialized){ - await this.loadAmsClient(); + private isAMSLoadAllowed(): boolean { + // it will load AMS only if enabled for Customer or Agent support for attachments, based on configuration + if (this.liveChatConfig.LiveWSAndLiveChatEngJoin.msdyn_enablefileattachmentsforcustomers || + this.liveChatConfig.LiveWSAndLiveChatEngJoin.msdyn_enablefileattachmentsforagents) { + if (this.liveChatVersion === LiveChatVersion.V2) { + //override of this value, since it will be needed to control access to attachment operations + this.isAMSClientAllowed = true; + return this.isAMSClientAllowed; + } } - } - - public async disableAMSClient() : Promise { - // No need to remove the AMS client , the flag will ensure any action is not performed - this.isAMSClientDisabled = true; + return this.isAMSClientAllowed; } private async loadAmsClient() : Promise { this.scenarioMarker.startScenario(TelemetryEvent.InitializeMessagingClient); try { - if (this.liveChatVersion === LiveChatVersion.V2) { - if (this.isAMSClientDisabled !== true && this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED) { - + if (this.isAMSLoadAllowed()) { + if (this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED) { this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADING; this.AMSClient = await createAMSClient({ framedMode: isBrowser(), @@ -306,8 +306,6 @@ class OmnichannelChatSDK { }); this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADED; } - } else if (this.liveChatVersion === LiveChatVersion.V1) { - this.IC3Client = await this.getIC3Client(); } this.scenarioMarker.completeScenario(TelemetryEvent.InitializeMessagingClient); @@ -320,7 +318,6 @@ class OmnichannelChatSDK { private async parallelInitialization(optionalParams: InitializeOptionalParams = {}) { try { this.scenarioMarker.startScenario(TelemetryEvent.InitializeChatSDKParallel); - this.isAMSClientDisabled = !!optionalParams.disableAMSClient; if (this.isInitialized) { this.scenarioMarker.completeScenario(TelemetryEvent.InitializeChatSDKParallel); @@ -331,9 +328,7 @@ class OmnichannelChatSDK { await Promise.all([this.loadInitComponents(), this.loadChatConfig(optionalParams)]); // this will load ams in the background, without holding the load - if (!optionalParams.disableAMSClient) { - this.loadAmsClient(); - } + this.loadAmsClient(); this.isInitialized = true; this.scenarioMarker.completeScenario(TelemetryEvent.InitializeChatSDKParallel); @@ -350,7 +345,6 @@ class OmnichannelChatSDK { private async sequentialInitialization(optionalParams: InitializeOptionalParams = {}) { this.scenarioMarker.startScenario(TelemetryEvent.InitializeChatSDK); - this.isAMSClientDisabled = !!optionalParams.disableAMSClient; if (this.isInitialized) { this.scenarioMarker.completeScenario(TelemetryEvent.InitializeChatSDK); @@ -385,7 +379,7 @@ class OmnichannelChatSDK { if (this.liveChatVersion === LiveChatVersion.V2) { this.ACSClient = new ACSClient(this.acsClientLogger); - if (this.isAMSClientDisabled === false && this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED) { + if (this.isAMSLoadAllowed() && this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED) { this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADING; this.AMSClient = await createAMSClient({ framedMode: isBrowser(), @@ -417,12 +411,14 @@ class OmnichannelChatSDK { */ public async initialize(optionalParams: InitializeOptionalParams = {}): Promise { - const { useParallelLoad } = optionalParams; + const { useSequentialLoad } = optionalParams; - if (useParallelLoad === true) { - return await this.parallelInitialization(optionalParams) + // default to use parallel load , and support for legacy definition + if ( useSequentialLoad === true) { + return await this.sequentialInitialization(optionalParams); } - return await this.sequentialInitialization(optionalParams); + + return await this.parallelInitialization(optionalParams) } private async loadChatConfig(optionalParams: InitializeOptionalParams = {}) : Promise { @@ -1624,11 +1620,11 @@ class OmnichannelChatSDK { ChatId: this.chatToken.chatId as string }); - if (this.isAMSClientDisabled === true) { + if (this.isAMSClientAllowed === false) { this.scenarioMarker.failScenario(TelemetryEvent.UploadFileAttachment, { RequestId: this.requestId, ChatId: this.chatToken.chatId as string, - ExceptionDetails : "AMSClient is disabled" + ExceptionDetails : "AMSClient is not loaded, please check widget configuration to allow attachments" }); throw new Error('AMSClient is disabled. Please enable AMSClient to upload file attachments.'); } @@ -1753,13 +1749,13 @@ class OmnichannelChatSDK { ChatId: this.chatToken.chatId as string }); - if (this.isAMSClientDisabled === true) { + if (this.isAMSClientAllowed === false) { this.scenarioMarker.failScenario(TelemetryEvent.DownloadFileAttachment, { RequestId: this.requestId, ChatId: this.chatToken.chatId as string, ExceptionDetails : "AMSClient is disabled" }); - throw new Error('AMSClient is disabled. Please enable AMSClient to download file attachments.'); + throw new Error('AMSClient is not loaded, Enable support for attachment scenarios in the widget configuration.'); } const amsClient = await this.getAMSClient(); diff --git a/src/core/InitializeOptionalParams.ts b/src/core/InitializeOptionalParams.ts index 992d0b29..3c1797e7 100644 --- a/src/core/InitializeOptionalParams.ts +++ b/src/core/InitializeOptionalParams.ts @@ -1,9 +1,31 @@ import GetLiveChatConfigOptionalParams from "./GetLiveChatConfigOptionalParams" +/** + * Interface representing optional parameters for initialization. + * + * @property getLiveChatConfigOptionalParams - Optional parameters for retrieving the live chat configuration. + * @property useParallelLoad - deprecated. this is not longer evaluated but was not removed for backward compatibility. + * @property useSequentialLoad - Indicates whether to load resources sequentially. If set to `true`, resources will be loaded one after another in sequence. + */ interface InitializeOptionalParams { + /** + * Optional parameters for retrieving the live chat configuration. + */ getLiveChatConfigOptionalParams?: GetLiveChatConfigOptionalParams; + + /** + * @deprecated + * Indicates whether to load resources in parallel. + * Not longer evaluated but was not removed for backward compatibility. + */ useParallelLoad?: boolean; - disableAMSClient?: boolean; + + /** + * Indicates whether to load resources sequentially. + * If set to `true`, resources will be loaded one after another in sequence. + */ + useSequentialLoad?: boolean; + } export default InitializeOptionalParams \ No newline at end of file From f883979f84a4463b0f06b739a0140a48e84f90d9 Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Thu, 27 Mar 2025 17:06:26 -0700 Subject: [PATCH 06/27] config boolean are coming as strings --- src/OmnichannelChatSDK.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/OmnichannelChatSDK.ts b/src/OmnichannelChatSDK.ts index ca34b6d0..ae72370c 100644 --- a/src/OmnichannelChatSDK.ts +++ b/src/OmnichannelChatSDK.ts @@ -281,8 +281,8 @@ class OmnichannelChatSDK { private isAMSLoadAllowed(): boolean { // it will load AMS only if enabled for Customer or Agent support for attachments, based on configuration - if (this.liveChatConfig.LiveWSAndLiveChatEngJoin.msdyn_enablefileattachmentsforcustomers || - this.liveChatConfig.LiveWSAndLiveChatEngJoin.msdyn_enablefileattachmentsforagents) { + if (this.liveChatConfig.LiveWSAndLiveChatEngJoin?.msdyn_enablefileattachmentsforcustomers === "true" || + this.liveChatConfig.LiveWSAndLiveChatEngJoin?.msdyn_enablefileattachmentsforagents === "true" ) { if (this.liveChatVersion === LiveChatVersion.V2) { //override of this value, since it will be needed to control access to attachment operations this.isAMSClientAllowed = true; @@ -296,6 +296,7 @@ class OmnichannelChatSDK { this.scenarioMarker.startScenario(TelemetryEvent.InitializeMessagingClient); try { if (this.isAMSLoadAllowed()) { + console.log("AMS ALLOWED"); if (this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED) { this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADING; this.AMSClient = await createAMSClient({ @@ -306,6 +307,8 @@ class OmnichannelChatSDK { }); this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADED; } + } else { + console.log("AMS NOT LOADED"); } this.scenarioMarker.completeScenario(TelemetryEvent.InitializeMessagingClient); From 6f2f301969a4d66b81d01d806c13802f0144e473 Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Thu, 27 Mar 2025 18:33:06 -0700 Subject: [PATCH 07/27] working on it --- src/OmnichannelChatSDK.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/OmnichannelChatSDK.ts b/src/OmnichannelChatSDK.ts index ae72370c..29b43006 100644 --- a/src/OmnichannelChatSDK.ts +++ b/src/OmnichannelChatSDK.ts @@ -256,12 +256,10 @@ class OmnichannelChatSDK { return this.AMSClient; case AMSClientLoadStates.LOADING: return await this.retryLoadAMSClient(); - case AMSClientLoadStates.ERROR: case AMSClientLoadStates.NOT_LOADED: await this.loadAmsClient(); return this.AMSClient; - default: return null; } @@ -281,8 +279,8 @@ class OmnichannelChatSDK { private isAMSLoadAllowed(): boolean { // it will load AMS only if enabled for Customer or Agent support for attachments, based on configuration - if (this.liveChatConfig.LiveWSAndLiveChatEngJoin?.msdyn_enablefileattachmentsforcustomers === "true" || - this.liveChatConfig.LiveWSAndLiveChatEngJoin?.msdyn_enablefileattachmentsforagents === "true" ) { + if (this.liveChatConfig?.LiveWSAndLiveChatEngJoin?.msdyn_enablefileattachmentsforcustomers === "true" || + this.liveChatConfig?.LiveWSAndLiveChatEngJoin?.msdyn_enablefileattachmentsforagents === "true" ) { if (this.liveChatVersion === LiveChatVersion.V2) { //override of this value, since it will be needed to control access to attachment operations this.isAMSClientAllowed = true; @@ -307,8 +305,6 @@ class OmnichannelChatSDK { }); this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADED; } - } else { - console.log("AMS NOT LOADED"); } this.scenarioMarker.completeScenario(TelemetryEvent.InitializeMessagingClient); From dd67c45061f2f8fd9869ba2b7d4a5e97aa8b827b Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Thu, 27 Mar 2025 19:01:35 -0700 Subject: [PATCH 08/27] reverse this change --- src/OmnichannelChatSDK.ts | 79 +++++++++++++++------------- src/core/InitializeOptionalParams.ts | 8 --- 2 files changed, 43 insertions(+), 44 deletions(-) diff --git a/src/OmnichannelChatSDK.ts b/src/OmnichannelChatSDK.ts index 29b43006..f829df12 100644 --- a/src/OmnichannelChatSDK.ts +++ b/src/OmnichannelChatSDK.ts @@ -149,7 +149,7 @@ class OmnichannelChatSDK { private isPersistentChat = false; private isChatReconnect = false; private reconnectId: null | string = null; - private refreshTokenTimer: NodeJS.Timeout | string |number | null = null; + private refreshTokenTimer: NodeJS.Timeout | string | number | null = null; private AMSClientLoadCurrentState: AMSClientLoadStates = AMSClientLoadStates.NOT_LOADED; private isMaskingDisabled = false; private maskingCharacter = "#"; @@ -224,7 +224,7 @@ class OmnichannelChatSDK { loggerUtils.setDebug(flag, this.ocSdkLogger, this.acsClientLogger, this.acsAdapterLogger, this.callingSdkLogger, this.amsClientLogger, this.ic3ClientLogger); } - private async retryLoadAMSClient() : Promise { + private async retryLoadAMSClient(): Promise { // Constants for retry logic const RETRY_DELAY_MS = 1000; const MAX_RETRY_COUNT = 5; @@ -232,19 +232,22 @@ class OmnichannelChatSDK { while (retryCount < MAX_RETRY_COUNT) { if (this.AMSClient) { + console.log("AMSClient loaded successfully after retrying."); return this.AMSClient; } await sleep(RETRY_DELAY_MS); retryCount++; } + console.error("Failed to load AMSClient after multiple attempts."); return null; } - private async getAMSClient() : Promise { + private async getAMSClient(): Promise { //return null to do not break promisse creation if (this.isAMSClientAllowed === false) { + console.log("AMSClient is not allowed, returning null"); return null; } @@ -252,20 +255,23 @@ class OmnichannelChatSDK { return null; } switch (this.AMSClientLoadCurrentState) { - case AMSClientLoadStates.LOADED: - return this.AMSClient; - case AMSClientLoadStates.LOADING: - return await this.retryLoadAMSClient(); - case AMSClientLoadStates.ERROR: - case AMSClientLoadStates.NOT_LOADED: - await this.loadAmsClient(); - return this.AMSClient; - default: - return null; + case AMSClientLoadStates.LOADED: + console.log("AMSClient is already loaded"); + return this.AMSClient; + case AMSClientLoadStates.LOADING: + console.log("AMSClient is loading, waiting for it to be ready"); + return await this.retryLoadAMSClient(); + case AMSClientLoadStates.ERROR: + case AMSClientLoadStates.NOT_LOADED: + console.log("AMSClient is not loaded, loading now"); + await this.loadAmsClient(); + return this.AMSClient; + default: + return null; } } - private async loadInitComponents() : Promise{ + private async loadInitComponents(): Promise { this.scenarioMarker.startScenario(TelemetryEvent.InitializeComponents); const supportedLiveChatVersions = [LiveChatVersion.V1, LiveChatVersion.V2]; @@ -280,7 +286,7 @@ class OmnichannelChatSDK { private isAMSLoadAllowed(): boolean { // it will load AMS only if enabled for Customer or Agent support for attachments, based on configuration if (this.liveChatConfig?.LiveWSAndLiveChatEngJoin?.msdyn_enablefileattachmentsforcustomers === "true" || - this.liveChatConfig?.LiveWSAndLiveChatEngJoin?.msdyn_enablefileattachmentsforagents === "true" ) { + this.liveChatConfig?.LiveWSAndLiveChatEngJoin?.msdyn_enablefileattachmentsforagents === "true") { if (this.liveChatVersion === LiveChatVersion.V2) { //override of this value, since it will be needed to control access to attachment operations this.isAMSClientAllowed = true; @@ -290,12 +296,13 @@ class OmnichannelChatSDK { return this.isAMSClientAllowed; } - private async loadAmsClient() : Promise { + private async loadAmsClient(): Promise { this.scenarioMarker.startScenario(TelemetryEvent.InitializeMessagingClient); try { if (this.isAMSLoadAllowed()) { console.log("AMS ALLOWED"); if (this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED) { + console.log("AMS NOT LOADED, LOADING NOW"); this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADING; this.AMSClient = await createAMSClient({ framedMode: isBrowser(), @@ -305,6 +312,8 @@ class OmnichannelChatSDK { }); this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADED; } + } else { + console.log("AMS NOT ALLOWED"); } this.scenarioMarker.completeScenario(TelemetryEvent.InitializeMessagingClient); @@ -410,17 +419,15 @@ class OmnichannelChatSDK { */ public async initialize(optionalParams: InitializeOptionalParams = {}): Promise { - const { useSequentialLoad } = optionalParams; + const { useParallelLoad } = optionalParams; - // default to use parallel load , and support for legacy definition - if ( useSequentialLoad === true) { - return await this.sequentialInitialization(optionalParams); + if (useParallelLoad === true) { + return await this.parallelInitialization(optionalParams) } - - return await this.parallelInitialization(optionalParams) + return await this.sequentialInitialization(optionalParams); } - private async loadChatConfig(optionalParams: InitializeOptionalParams = {}) : Promise { + private async loadChatConfig(optionalParams: InitializeOptionalParams = {}): Promise { this.scenarioMarker.startScenario(TelemetryEvent.InitializeLoadChatConfig); const useCoreServices = isCoreServicesOrgUrl(this.omnichannelConfig.orgUrl); @@ -828,7 +835,7 @@ class OmnichannelChatSDK { } }; - const attachmentClientPromise = async () : Promise => { + const attachmentClientPromise = async (): Promise => { try { const amsClient = await this.getAMSClient(); if (this.liveChatVersion === LiveChatVersion.V2) { @@ -1623,7 +1630,7 @@ class OmnichannelChatSDK { this.scenarioMarker.failScenario(TelemetryEvent.UploadFileAttachment, { RequestId: this.requestId, ChatId: this.chatToken.chatId as string, - ExceptionDetails : "AMSClient is not loaded, please check widget configuration to allow attachments" + ExceptionDetails: "AMSClient is not loaded, please check widget configuration to allow attachments" }); throw new Error('AMSClient is disabled. Please enable AMSClient to upload file attachments.'); } @@ -1752,7 +1759,7 @@ class OmnichannelChatSDK { this.scenarioMarker.failScenario(TelemetryEvent.DownloadFileAttachment, { RequestId: this.requestId, ChatId: this.chatToken.chatId as string, - ExceptionDetails : "AMSClient is disabled" + ExceptionDetails: "AMSClient is disabled" }); throw new Error('AMSClient is not loaded, Enable support for attachment scenarios in the widget configuration.'); } @@ -2358,7 +2365,7 @@ class OmnichannelChatSDK { } } - private async setPrechatConfigurations(liveWSAndLiveChatEngJoin: LiveWSAndLiveChatEngJoin) : Promise { + private async setPrechatConfigurations(liveWSAndLiveChatEngJoin: LiveWSAndLiveChatEngJoin): Promise { const isPreChatEnabled = parseLowerCaseString(liveWSAndLiveChatEngJoin.msdyn_prechatenabled) === "true"; @@ -2369,7 +2376,7 @@ class OmnichannelChatSDK { } } - private async setDataMaskingConfiguration(dataMaskingConfig: DataMaskingInfo) : Promise { + private async setDataMaskingConfiguration(dataMaskingConfig: DataMaskingInfo): Promise { if (dataMaskingConfig.setting.msdyn_maskforcustomer) { if (dataMaskingConfig.dataMaskingRules) { @@ -2383,7 +2390,7 @@ class OmnichannelChatSDK { } } - private async setAuthSettingConfig(authSettings: AuthSettings) : Promise { + private async setAuthSettingConfig(authSettings: AuthSettings): Promise { if (authSettings) { this.authSettings = authSettings; @@ -2394,7 +2401,7 @@ class OmnichannelChatSDK { } } - private async setPersistentChatConfiguration(liveWSAndLiveChatEngJoin: LiveWSAndLiveChatEngJoin) : Promise { + private async setPersistentChatConfiguration(liveWSAndLiveChatEngJoin: LiveWSAndLiveChatEngJoin): Promise { const isChatReconnectEnabled = parseLowerCaseString(liveWSAndLiveChatEngJoin.msdyn_enablechatreconnect) === "true"; if (liveWSAndLiveChatEngJoin.msdyn_conversationmode?.toString() === ConversationMode.PersistentChat.toString()) { this.isPersistentChat = true; @@ -2405,17 +2412,17 @@ class OmnichannelChatSDK { } } - private async setLocaleIdConfiguration(chatWidgetLanguage: ChatWidgetLanguage) : Promise { + private async setLocaleIdConfiguration(chatWidgetLanguage: ChatWidgetLanguage): Promise { this.localeId = chatWidgetLanguage.msdyn_localeid || defaultLocaleId; } - private async setCallingOptionConfiguration(liveWSAndLiveChatEngJoin: LiveWSAndLiveChatEngJoin) : Promise { + private async setCallingOptionConfiguration(liveWSAndLiveChatEngJoin: LiveWSAndLiveChatEngJoin): Promise { const { msdyn_callingoptions } = liveWSAndLiveChatEngJoin; this.callingOption = msdyn_callingoptions?.trim().length > 0 ? Number(msdyn_callingoptions) : CallingOptionsOptionSetNumber.NoCalling; } - private async setLiveChatVersionConfiguration(liveChatVersion: number) : Promise { + private async setLiveChatVersionConfiguration(liveChatVersion: number): Promise { this.liveChatVersion = liveChatVersion || LiveChatVersion.V2; } @@ -2452,7 +2459,7 @@ class OmnichannelChatSDK { } // eslint-disable-next-line @typescript-eslint/no-explicit-any - private async buildConfigurations(liveChatConfig: any) : Promise { + private async buildConfigurations(liveChatConfig: any): Promise { const { DataMaskingInfo: dataMaskingConfig, @@ -2515,7 +2522,7 @@ class OmnichannelChatSDK { } } - private async setAuthTokenProvider(provider: ChatSDKConfig["getAuthToken"], optionalParams: SetAuthTokenProviderOptionalParams = {}) : Promise { + private async setAuthTokenProvider(provider: ChatSDKConfig["getAuthToken"], optionalParams: SetAuthTokenProviderOptionalParams = {}): Promise { this.scenarioMarker.startScenario(TelemetryEvent.GetAuthToken); this.chatSDKConfig.getAuthToken = provider; @@ -2572,7 +2579,7 @@ class OmnichannelChatSDK { } } - private useCoreServicesOrgUrlIfNotSet() : void { + private useCoreServicesOrgUrlIfNotSet(): void { /* Perform orgUrl conversion to CoreServices only if orgUrl is not a CoreServices orgUrl. * Feature should be enabled by default. `createCoreServicesOrgUrlAtRuntime` set to `false` * would disable the orgUrl conversion and should only be used as fallback only. diff --git a/src/core/InitializeOptionalParams.ts b/src/core/InitializeOptionalParams.ts index 3c1797e7..f02460d0 100644 --- a/src/core/InitializeOptionalParams.ts +++ b/src/core/InitializeOptionalParams.ts @@ -14,18 +14,10 @@ interface InitializeOptionalParams { getLiveChatConfigOptionalParams?: GetLiveChatConfigOptionalParams; /** - * @deprecated * Indicates whether to load resources in parallel. * Not longer evaluated but was not removed for backward compatibility. */ useParallelLoad?: boolean; - - /** - * Indicates whether to load resources sequentially. - * If set to `true`, resources will be loaded one after another in sequence. - */ - useSequentialLoad?: boolean; - } export default InitializeOptionalParams \ No newline at end of file From 5318a41cb8370e5e4d4a415841ef4ca20511ac10 Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Thu, 27 Mar 2025 19:05:42 -0700 Subject: [PATCH 09/27] test fix --- __tests__/OmnichannelChatSDKParallel.web.spec.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/__tests__/OmnichannelChatSDKParallel.web.spec.ts b/__tests__/OmnichannelChatSDKParallel.web.spec.ts index 4a993cbb..db3fa324 100644 --- a/__tests__/OmnichannelChatSDKParallel.web.spec.ts +++ b/__tests__/OmnichannelChatSDKParallel.web.spec.ts @@ -40,6 +40,7 @@ describe('Omnichannel Chat SDK (Web)', () => { it('ChatSDK.startChat() with sendDefaultInitContext should pass getContext to OCClient.sessionInit()', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); @@ -77,7 +78,7 @@ describe('Omnichannel Chat SDK (Web)', () => { it('ChatSDK.startChat() with sendDefaultInitContext should throw an error if not used on Web Platform', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); while (chatSDK.AMSClient === null) { @@ -113,7 +114,7 @@ describe('Omnichannel Chat SDK (Web)', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); while (chatSDK.AMSClient === null) { @@ -142,7 +143,7 @@ describe('Omnichannel Chat SDK (Web)', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); while (chatSDK.AMSClient === null) { @@ -174,7 +175,7 @@ describe('Omnichannel Chat SDK (Web)', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); while (chatSDK.AMSClient === null) { From baf2d94fd1ed41feae9c21024fdb7a34ec3ebb14 Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Mon, 31 Mar 2025 14:29:36 -0700 Subject: [PATCH 10/27] component working as expected, delay noticed --- src/OmnichannelChatSDK.ts | 66 +++++++++++++++++++--------------- src/core/ChatSDKError.ts | 6 +++- src/utils/exceptionThrowers.ts | 6 ++-- 3 files changed, 47 insertions(+), 31 deletions(-) diff --git a/src/OmnichannelChatSDK.ts b/src/OmnichannelChatSDK.ts index f829df12..4d9074a2 100644 --- a/src/OmnichannelChatSDK.ts +++ b/src/OmnichannelChatSDK.ts @@ -227,7 +227,7 @@ class OmnichannelChatSDK { private async retryLoadAMSClient(): Promise { // Constants for retry logic const RETRY_DELAY_MS = 1000; - const MAX_RETRY_COUNT = 5; + const MAX_RETRY_COUNT = 30; let retryCount = 0; while (retryCount < MAX_RETRY_COUNT) { @@ -255,19 +255,19 @@ class OmnichannelChatSDK { return null; } switch (this.AMSClientLoadCurrentState) { - case AMSClientLoadStates.LOADED: - console.log("AMSClient is already loaded"); - return this.AMSClient; - case AMSClientLoadStates.LOADING: - console.log("AMSClient is loading, waiting for it to be ready"); - return await this.retryLoadAMSClient(); - case AMSClientLoadStates.ERROR: - case AMSClientLoadStates.NOT_LOADED: - console.log("AMSClient is not loaded, loading now"); - await this.loadAmsClient(); - return this.AMSClient; - default: - return null; + case AMSClientLoadStates.LOADED: + console.log("AMSClient is already loaded"); + return this.AMSClient; + case AMSClientLoadStates.LOADING: + console.log("AMSClient is loading, waiting for it to be ready"); + return await this.retryLoadAMSClient(); + case AMSClientLoadStates.ERROR: + case AMSClientLoadStates.NOT_LOADED: + console.log("AMSClient is not loaded, loading now"); + await this.loadAmsClient(); + return this.AMSClient; + default: + return null; } } @@ -278,12 +278,16 @@ class OmnichannelChatSDK { if (!supportedLiveChatVersions.includes(this.liveChatVersion)) { exceptionThrowers.throwUnsupportedLiveChatVersionFailure(new Error(ChatSDKErrorName.UnsupportedLiveChatVersion), this.scenarioMarker, TelemetryEvent.InitializeComponents); } - - this.ACSClient = new ACSClient(this.acsClientLogger); + // we need this version validation, until we remove all v1 code, pending task. + if (this.liveChatVersion === LiveChatVersion.V2) { + this.ACSClient = new ACSClient(this.acsClientLogger); + } else { + this.IC3Client = await this.getIC3Client(); + } this.scenarioMarker.completeScenario(TelemetryEvent.InitializeComponents); } - private isAMSLoadAllowed(): boolean { + private evaluateAMSAvailability(): boolean { // it will load AMS only if enabled for Customer or Agent support for attachments, based on configuration if (this.liveChatConfig?.LiveWSAndLiveChatEngJoin?.msdyn_enablefileattachmentsforcustomers === "true" || this.liveChatConfig?.LiveWSAndLiveChatEngJoin?.msdyn_enablefileattachmentsforagents === "true") { @@ -299,7 +303,7 @@ class OmnichannelChatSDK { private async loadAmsClient(): Promise { this.scenarioMarker.startScenario(TelemetryEvent.InitializeMessagingClient); try { - if (this.isAMSLoadAllowed()) { + if (this.isAMSClientAllowed) { console.log("AMS ALLOWED"); if (this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED) { console.log("AMS NOT LOADED, LOADING NOW"); @@ -315,7 +319,6 @@ class OmnichannelChatSDK { } else { console.log("AMS NOT ALLOWED"); } - this.scenarioMarker.completeScenario(TelemetryEvent.InitializeMessagingClient); } catch (e) { this.AMSClientLoadCurrentState = AMSClientLoadStates.ERROR; @@ -335,9 +338,7 @@ class OmnichannelChatSDK { this.useCoreServicesOrgUrlIfNotSet(); await Promise.all([this.loadInitComponents(), this.loadChatConfig(optionalParams)]); // this will load ams in the background, without holding the load - this.loadAmsClient(); - this.isInitialized = true; this.scenarioMarker.completeScenario(TelemetryEvent.InitializeChatSDKParallel); } catch (error) { @@ -387,7 +388,7 @@ class OmnichannelChatSDK { if (this.liveChatVersion === LiveChatVersion.V2) { this.ACSClient = new ACSClient(this.acsClientLogger); - if (this.isAMSLoadAllowed() && this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED) { + if (this.isAMSClientAllowed && this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED) { this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADING; this.AMSClient = await createAMSClient({ framedMode: isBrowser(), @@ -442,6 +443,8 @@ class OmnichannelChatSDK { try { const { getLiveChatConfigOptionalParams } = optionalParams; await this.getChatConfig(getLiveChatConfigOptionalParams || {}); + // once we have the config, we can check if we need to load AMS + this.evaluateAMSAvailability(); } catch (e) { exceptionThrowers.throwChatConfigRetrievalFailure(e, this.scenarioMarker, TelemetryEvent.InitializeLoadChatConfig); } @@ -837,6 +840,9 @@ class OmnichannelChatSDK { const attachmentClientPromise = async (): Promise => { try { + if (!this.isAMSClientAllowed) return; + + // will wait till the AMSClient is loaded, and then initialize it const amsClient = await this.getAMSClient(); if (this.liveChatVersion === LiveChatVersion.V2) { await amsClient?.initialize({ chatToken: this.chatToken as OmnichannelChatToken }); @@ -1621,6 +1627,8 @@ class OmnichannelChatSDK { public async uploadFileAttachment(fileInfo: IFileInfo | File): Promise { + console.log("AMS : uploadFileAttachment"); + this.scenarioMarker.startScenario(TelemetryEvent.UploadFileAttachment, { RequestId: this.requestId, ChatId: this.chatToken.chatId as string @@ -1635,12 +1643,12 @@ class OmnichannelChatSDK { throw new Error('AMSClient is disabled. Please enable AMSClient to upload file attachments.'); } - const amsClient = await this.getAMSClient(); - if (!this.isInitialized) { exceptionThrowers.throwUninitializedChatSDK(this.scenarioMarker, TelemetryEvent.UploadFileAttachment); } + const amsClient = await this.getAMSClient(); + if (this.liveChatVersion === LiveChatVersion.V2) { const createObjectResponse: any = await amsClient?.createObject(this.chatToken?.chatId as string, fileInfo as any); // eslint-disable-line @typescript-eslint/no-explicit-any const documentId = createObjectResponse.id; @@ -1750,11 +1758,17 @@ class OmnichannelChatSDK { public async downloadFileAttachment(fileMetadata: FileMetadata | IFileMetadata): Promise { + console.log("AMS : downloadFileAttachment"); + this.scenarioMarker.startScenario(TelemetryEvent.DownloadFileAttachment, { RequestId: this.requestId, ChatId: this.chatToken.chatId as string }); + if (!this.isInitialized) { + exceptionThrowers.throwUninitializedChatSDK(this.scenarioMarker, TelemetryEvent.DownloadFileAttachment); + } + if (this.isAMSClientAllowed === false) { this.scenarioMarker.failScenario(TelemetryEvent.DownloadFileAttachment, { RequestId: this.requestId, @@ -1766,10 +1780,6 @@ class OmnichannelChatSDK { const amsClient = await this.getAMSClient(); - if (!this.isInitialized) { - exceptionThrowers.throwUninitializedChatSDK(this.scenarioMarker, TelemetryEvent.DownloadFileAttachment); - } - if (this.liveChatVersion === LiveChatVersion.V2) { try { const response: any = await amsClient?.getViewStatus(fileMetadata); // eslint-disable-line @typescript-eslint/no-explicit-any diff --git a/src/core/ChatSDKError.ts b/src/core/ChatSDKError.ts index 6015a74d..31af1c8a 100644 --- a/src/core/ChatSDKError.ts +++ b/src/core/ChatSDKError.ts @@ -1,3 +1,5 @@ +import ChatSDKExceptionDetails from "./ChatSDKExceptionDetails"; + /** * Enum of ChatSDK standard errors. * @@ -64,10 +66,12 @@ export enum ChatSDKErrorName { export class ChatSDKError { public message: ChatSDKErrorName; public httpResponseStatusCode: number | undefined; + public exceptionDetails: ChatSDKExceptionDetails | undefined; - constructor(message: ChatSDKErrorName, httpResponseStatusCode?: number) { + constructor(message: ChatSDKErrorName, httpResponseStatusCode?: number, exceptionDetails?: ChatSDKExceptionDetails) { this.message = message; this.httpResponseStatusCode = httpResponseStatusCode; + this.exceptionDetails = exceptionDetails; } toString(): string { diff --git a/src/utils/exceptionThrowers.ts b/src/utils/exceptionThrowers.ts index 7d687faf..646a2e55 100644 --- a/src/utils/exceptionThrowers.ts +++ b/src/utils/exceptionThrowers.ts @@ -12,7 +12,8 @@ * Stack trace should only be logged and not printed. */ -import { ChatSDKErrorName, ChatSDKError } from "../core/ChatSDKError"; +import { ChatSDKError, ChatSDKErrorName } from "../core/ChatSDKError"; + import ChatSDKExceptionDetails from "../core/ChatSDKExceptionDetails"; import ScenarioMarker from "../telemetry/ScenarioMarker"; import TelemetryEvent from "../telemetry/TelemetryEvent"; @@ -39,7 +40,8 @@ export const throwChatSDKError = (chatSDKError: ChatSDKErrorName, e: unknown, sc throw new ChatSDKError( chatSDKError, // eslint-disable-next-line @typescript-eslint/no-explicit-any - ((e as any)?.isAxiosError && (e as any)?.response?.status) ? (e as any)?.response?.status : undefined + ((e as any)?.isAxiosError && (e as any)?.response?.status) ? (e as any)?.response?.status : undefined, + exceptionDetails ); } From 1327067e5fcb13b6e0ee0bd1e5d5e6a40a1b8c6a Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Mon, 31 Mar 2025 15:35:19 -0700 Subject: [PATCH 11/27] tests working --- __tests__/OmnichannelChatSDK.node.spec.ts | 3 + __tests__/OmnichannelChatSDK.spec.ts | 85 ++++++++++- .../OmnichannelChatSDKParallel.node.spec.ts | 3 +- __tests__/OmnichannelChatSDKParallel.spec.ts | 142 +++++++++--------- src/OmnichannelChatSDK.ts | 48 +++--- 5 files changed, 188 insertions(+), 93 deletions(-) diff --git a/__tests__/OmnichannelChatSDK.node.spec.ts b/__tests__/OmnichannelChatSDK.node.spec.ts index 24e41734..e4b341e8 100644 --- a/__tests__/OmnichannelChatSDK.node.spec.ts +++ b/__tests__/OmnichannelChatSDK.node.spec.ts @@ -36,6 +36,7 @@ describe('Omnichannel Chat SDK (Node), Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -82,6 +83,7 @@ describe('Omnichannel Chat SDK (Node), Sequential', () => { }; chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -113,6 +115,7 @@ describe('Omnichannel Chat SDK (Node), Sequential', () => { }; chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); diff --git a/__tests__/OmnichannelChatSDK.spec.ts b/__tests__/OmnichannelChatSDK.spec.ts index b42ef565..ed3c340e 100644 --- a/__tests__/OmnichannelChatSDK.spec.ts +++ b/__tests__/OmnichannelChatSDK.spec.ts @@ -521,6 +521,8 @@ describe('Omnichannel Chat SDK, Sequential', () => { chatSDK.SDKProvider = SDKProvider; try { + chatSDK["isAMSClientAllowed"] = true; + await chatSDK.initialize(); fail(); } catch (e: any ) { @@ -537,6 +539,8 @@ describe('Omnichannel Chat SDK, Sequential', () => { chatSDK.getChatConfig = jest.fn(() => {throw Error()}); try { + chatSDK["isAMSClientAllowed"] = true; + await chatSDK.initialize(); fail(); } catch (e: any ) { @@ -552,6 +556,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const getLiveChatConfigOptionalParams = { sendCacheHeaders: true }; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({getLiveChatConfigOptionalParams}); @@ -585,6 +590,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { chatSDK.liveChatVersion = LiveChatVersion.V1; jest.spyOn(chatSDK, 'getIC3Client'); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); await chatSDK.initialize(); @@ -790,6 +796,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.authSettings = {}; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -816,6 +823,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.authSettings = {}; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -847,6 +855,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.authSettings = {}; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -883,6 +892,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.authSettings = {}; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -920,6 +930,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.authSettings = {}; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -1014,6 +1025,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { }; chatSDK.dataMaskingRules = { rules : [dataMaskingRule]} as MaskingRules; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -1063,6 +1075,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { // global.fetch = jest.fn(); const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -1092,6 +1105,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { it('ChatSDK.startChat() should throw an error if OCClient.sessionInit() fails', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -1120,6 +1134,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { it('ChatSDK.startChat() should not call OCClient.sessionInit() if OCClient.getChatToken() fails', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -1139,7 +1154,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { it('ChatSDK.startChat() should throw a \'WidgetUseOutsideOperatingHour\' error if OCClient.sessionInit() fails with \'705\' error code', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); chatSDK.ACSClient.initialize = jest.fn(); @@ -1176,6 +1191,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.liveChatVersion = LiveChatVersion.V1; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -1235,6 +1251,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { it('ChatSDK.startChat() should throw an exception if ACSClient.initialize() fails', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -1265,6 +1282,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { it('ChatSDK.startChat() should throw an exception if AMSClient.initialize() fails', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -1295,6 +1313,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { it('ChatSDK.startChat() should throw an exception if ACSClient.joinConversation() fails', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -1325,6 +1344,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { it('ChatSDK.startchat() with existing liveChatContext should not call OCClient.getChatToken() & OCClient.sessionInit()', async() => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); jest.spyOn(chatSDK.OCClient, 'getChatToken').mockResolvedValue(Promise.resolve({ @@ -1364,6 +1384,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { it('ChatSDK.startChat() with invalid liveChatContext should throw an error', async() => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); jest.spyOn(chatSDK.OCClient, 'getChatToken').mockResolvedValue(Promise.resolve({ @@ -1397,6 +1418,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { it('ChatSDK.startChat() with liveChatContext of a closed conversation should throw an error', async() => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); jest.spyOn(chatSDK.OCClient, 'getChatToken').mockResolvedValue(Promise.resolve({ @@ -1492,6 +1514,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.liveChatVersion = LiveChatVersion.V1; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -1533,6 +1556,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -1556,6 +1580,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.liveChatVersion = LiveChatVersion.V1; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -1600,6 +1625,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.liveChatVersion = LiveChatVersion.V1; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -1662,6 +1688,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const oldGetChatConfig = chatSDK.getChatConfig; chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -1745,6 +1772,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); chatSDK.liveChatVersion = LiveChatVersion.V1; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -1826,6 +1854,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { it('ChatSDK.getCurrentLiveChatContext() with empty chatToken should return an empty chat session data', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -1852,6 +1881,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { it('ChatSDK.getConversationDetails() should call OCClient.getLWIDetails()', async() => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -1874,6 +1904,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { it('ChatSDK.getConversationDetails() should return "{}" and not throw exception if OCClient.getLWIDetails() fails ', async() => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -1893,6 +1924,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -1942,6 +1974,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.isChatReconnect = true; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -1988,6 +2021,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { chatSDK.isPersistentChat = true; global.setInterval = jest.fn() as unknown as typeof setInterval; chatSDK.liveChatVersion = LiveChatVersion.V1; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -2022,6 +2056,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { it("ChatSDK.getConversationDetails() with liveChatContext should fetch conversation details from liveChatContext", async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -2086,6 +2121,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -2283,6 +2319,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -2353,6 +2390,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; chatSDK.liveChatVersion = LiveChatVersion.V1; @@ -2399,6 +2437,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -2459,6 +2498,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -2522,6 +2562,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); chatSDK.OCClient = { @@ -2550,6 +2591,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -2580,6 +2622,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -2614,6 +2657,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -2668,6 +2712,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); chatSDK.ACSClient.initialize = jest.fn(); @@ -2717,6 +2762,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -2742,6 +2788,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -2792,6 +2839,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -2848,6 +2896,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { jest.spyOn(platform, 'isBrowser').mockReturnValue(false); jest.spyOn(chatSDK, 'getIC3Client'); jest.spyOn(IC3SDKProvider, 'getSDK'); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -2891,6 +2940,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -2919,6 +2969,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -2947,6 +2998,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -2985,6 +3037,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3012,6 +3065,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); chatSDK.liveChatVersion = LiveChatVersion.V1; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3037,6 +3091,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3096,6 +3151,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3126,6 +3182,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3158,6 +3215,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3190,6 +3248,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3222,6 +3281,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3256,6 +3316,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3347,6 +3408,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.isPersistentChat = true; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3422,6 +3484,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { chatSDK.isPersistentChat = true; chatSDK.updateChatToken = jest.fn(); global.setInterval = jest.fn() as unknown as typeof setInterval; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3460,6 +3523,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { chatSDK.isPersistentChat = true; chatSDK.liveChatVersion = LiveChatVersion.V1; global.setInterval = jest.fn() as unknown as typeof setInterval; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3554,6 +3618,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.isChatReconnect = true; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3583,6 +3648,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.isChatReconnect = true; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); chatSDK.ACSClient.initialize = jest.fn(); @@ -3621,6 +3687,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); chatSDK.isChatReconnect = true; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3656,6 +3723,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { chatSDK.getChatConfig = jest.fn(); chatSDK.isChatReconnect = true; chatSDK.authenticatedUserToken = 'token'; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3690,6 +3758,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { chatSDK.getChatConfig = jest.fn(); chatSDK.isChatReconnect = true; chatSDK.authenticatedUserToken = 'token'; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3731,6 +3800,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { chatSDK.getChatConfig = jest.fn(); chatSDK.isChatReconnect = true; chatSDK.authenticatedUserToken = 'token'; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3766,6 +3836,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.isChatReconnect = true; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3795,6 +3866,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.isChatReconnect = true; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3830,6 +3902,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { chatSDK.getChatConfig = jest.fn(); chatSDK.isChatReconnect = true; chatSDK.authenticatedUserToken = 'token'; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3846,7 +3919,6 @@ describe('Omnichannel Chat SDK, Sequential', () => { expect(chatSDK.OCClient.getReconnectableChats).toHaveBeenCalledTimes(1); }); - it('ChatSDK.getChatReconnectContext() should fail if OCClient.getReconnectAvailability() fails', async () => { const chatSDKConfig = { telemetry: { @@ -3860,6 +3932,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.isChatReconnect = true; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3900,6 +3973,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3941,6 +4015,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -3985,6 +4060,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -4032,6 +4108,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -4081,6 +4158,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -4132,6 +4210,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); @@ -4187,6 +4266,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); chatSDK.authSettings = {}; @@ -4229,6 +4309,7 @@ describe('Omnichannel Chat SDK, Sequential', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize(); diff --git a/__tests__/OmnichannelChatSDKParallel.node.spec.ts b/__tests__/OmnichannelChatSDKParallel.node.spec.ts index 7ed3efd8..81c30128 100644 --- a/__tests__/OmnichannelChatSDKParallel.node.spec.ts +++ b/__tests__/OmnichannelChatSDKParallel.node.spec.ts @@ -81,6 +81,7 @@ describe('Omnichannel Chat SDK (Node) Parallel initialization', () => { chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); chatSDK.ACSClient.initialize = jest.fn(); @@ -118,7 +119,7 @@ describe('Omnichannel Chat SDK (Node) Parallel initialization', () => { }; chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); while (chatSDK.AMSClient === null) { diff --git a/__tests__/OmnichannelChatSDKParallel.spec.ts b/__tests__/OmnichannelChatSDKParallel.spec.ts index f1e7fa73..e249164d 100644 --- a/__tests__/OmnichannelChatSDKParallel.spec.ts +++ b/__tests__/OmnichannelChatSDKParallel.spec.ts @@ -36,6 +36,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { if (global.window.document) { (global as any).window.document = undefined; } + }); describe('Configurations', () => { @@ -373,7 +374,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); // eslint-disable-next-line @typescript-eslint/no-var-requires const version = require("../package.json").version; @@ -396,7 +397,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); // eslint-disable-next-line @typescript-eslint/no-var-requires const version = require("../package.json").version; @@ -424,6 +425,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { chatSDK.liveChatVersion = 'invalid'; try { + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); } catch (e: any ) { expect(e.message).toBe("UnsupportedLiveChatVersion"); @@ -433,7 +435,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { it('ChatSDK.initialize() should instantiate OCSDK & ACSClient & AMSClient', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -461,6 +463,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { chatSDK.SDKProvider = SDKProvider; try { + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); fail(); } catch (e: any ) { expect(e.message).toBe("OmnichannelClientInitializationFailure"); @@ -476,6 +479,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { chatSDK.getChatConfig = jest.fn(() => { throw Error() }); try { + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); fail(); } catch (e: any ) { expect(e.message).toBe("ChatConfigRetrievalFailure"); @@ -490,7 +494,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const getLiveChatConfigOptionalParams = { sendCacheHeaders: true, }; - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true, getLiveChatConfigOptionalParams }); jest.spyOn(chatSDK.OCClient, 'getChatConfig') @@ -714,7 +718,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.authSettings = {}; - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); jest.spyOn(chatSDK, 'setAuthTokenProvider'); jest.spyOn(chatSDK.scenarioMarker, 'failScenario'); @@ -738,7 +742,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.authSettings = {}; - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); jest.spyOn(chatSDK, 'setAuthTokenProvider'); jest.spyOn(chatSDK.scenarioMarker, 'failScenario'); @@ -768,7 +772,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.authSettings = {}; - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); jest.spyOn(chatSDK, 'setAuthTokenProvider'); jest.spyOn(chatSDK.scenarioMarker, 'failScenario'); @@ -803,7 +807,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.authSettings = {}; - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); while (chatSDK.AMSClient === null) { await new Promise(resolve => setTimeout(resolve, 2000)); @@ -843,7 +847,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.authSettings = {}; - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -946,7 +950,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { chatSDK.dataMaskingRules = { rules : [ dataMaskingRules ] } as MaskingRules; - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); const maskingRules : MaskingRules = await chatSDK.getDataMaskingRules(); expect(maskingRules.rules[0]).toBe(dataMaskingRules); @@ -967,7 +971,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { // global.fetch = jest.fn(); const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1002,7 +1006,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { it('ChatSDK.startChat() should throw an error if OCClient.sessionInit() fails', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1037,7 +1041,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { it('ChatSDK.startChat() should not call OCClient.sessionInit() if OCClient.getChatToken() fails', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); jest.spyOn(chatSDK.OCClient, 'getChatToken').mockResolvedValue(new Error("Async error message")); jest.spyOn(chatSDK.OCClient, 'sessionInit').mockRejectedValue(Promise.resolve()); @@ -1055,7 +1059,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { it('ChatSDK.startChat() should throw a \'WidgetUseOutsideOperatingHour\' error if OCClient.sessionInit() fails with \'705\' error code', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1098,7 +1102,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { it('ChatSDK.startChat() should throw an exception if ACSClient.initialize() fails', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1135,7 +1139,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { it('ChatSDK.startChat() should throw an exception if AMSClient.initialize() fails', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1171,7 +1175,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { it('ChatSDK.startChat() should throw an exception if ACSClient.joinConversation() fails', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1207,7 +1211,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { it('ChatSDK.startchat() with existing liveChatContext should not call OCClient.getChatToken() & OCClient.sessionInit()', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1254,7 +1258,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { it('ChatSDK.startChat() with invalid liveChatContext should throw an error', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1295,7 +1299,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { it('ChatSDK.startChat() with liveChatContext of a closed conversation should throw an error', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1404,7 +1408,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1433,7 +1437,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { it('ChatSDK.getCurrentLiveChatContext() with empty chatToken should return an empty chat session data', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1466,7 +1470,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { it('ChatSDK.getConversationDetails() should call OCClient.getLWIDetails()', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1495,7 +1499,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { it('ChatSDK.getConversationDetails() should return "{}" and not throw exception if OCClient.getLWIDetails() fails ', async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1529,7 +1533,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1585,7 +1589,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.isChatReconnect = true; - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1625,7 +1629,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { it("ChatSDK.getConversationDetails() with liveChatContext should fetch conversation details from liveChatContext", async () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1670,7 +1674,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1706,7 +1710,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1745,7 +1749,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1780,7 +1784,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1819,7 +1823,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1855,7 +1859,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1892,7 +1896,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1933,7 +1937,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -1994,7 +1998,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -2053,7 +2057,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); while (chatSDK.AMSClient === null) { await new Promise(resolve => setTimeout(resolve, 2000)); @@ -2081,7 +2085,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -2139,6 +2143,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -2188,7 +2193,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -2222,7 +2227,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -2268,7 +2273,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -2302,7 +2307,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); while (chatSDK.AMSClient === null) { @@ -2334,7 +2339,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -2371,7 +2376,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -2410,7 +2415,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -2450,7 +2455,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -2488,7 +2493,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -2527,7 +2532,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -2565,7 +2570,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -2619,7 +2624,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -2700,7 +2705,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.isPersistentChat = true; - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); chatSDK.reconnectId = 'reconnectId'; @@ -2733,6 +2738,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { chatSDK.updateChatToken = jest.fn(); global.setInterval = jest.fn() as unknown as typeof setInterval; + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); while (chatSDK.AMSClient === null) { await new Promise(resolve => setTimeout(resolve, 2000)); @@ -2835,7 +2841,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.isChatReconnect = true; - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); chatSDK.reconnectId = 'reconnectId'; @@ -2863,7 +2869,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.isChatReconnect = true; - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -2909,7 +2915,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { chatSDK.getChatConfig = jest.fn(); chatSDK.getChatToken = jest.fn(); chatSDK.isChatReconnect = true; - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); let retryCount = 0; const maxRetries = 3; @@ -2951,7 +2957,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { chatSDK.getChatConfig = jest.fn(); chatSDK.isChatReconnect = true; chatSDK.authenticatedUserToken = 'token'; - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); const mockedResponse = { reconnectid: 'reconnectid' @@ -2984,7 +2990,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { chatSDK.getChatConfig = jest.fn(); chatSDK.isChatReconnect = true; chatSDK.authenticatedUserToken = 'token'; - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); const mockedResponse = { reconnectid: 'reconnectid' @@ -3024,7 +3030,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { chatSDK.getChatConfig = jest.fn(); chatSDK.isChatReconnect = true; chatSDK.authenticatedUserToken = 'token'; - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); const mockedResponse = { reconnectid: 'reconnectid' @@ -3058,7 +3064,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.isChatReconnect = true; - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); jest.spyOn(chatSDK.OCClient, 'getReconnectAvailability').mockResolvedValue(Promise.resolve()); @@ -3086,7 +3092,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.isChatReconnect = true; - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); const mockedResponse = { isReconnectAvailable: false, @@ -3120,7 +3126,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { chatSDK.getChatConfig = jest.fn(); chatSDK.isChatReconnect = true; chatSDK.authenticatedUserToken = 'token'; - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); jest.spyOn(chatSDK.OCClient, 'getReconnectableChats').mockResolvedValue(Promise.reject()); jest.spyOn(console, 'error'); @@ -3147,7 +3153,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); chatSDK.isChatReconnect = true; - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); jest.spyOn(chatSDK.OCClient, 'getReconnectAvailability').mockResolvedValue(Promise.reject()); jest.spyOn(console, 'error'); @@ -3185,7 +3191,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); chatSDK.liveChatConfig = dummyConfig; jest.spyOn(chatSDK, 'getConversationDetails').mockResolvedValue({ @@ -3225,7 +3231,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); chatSDK.liveChatConfig = dummyConfig; jest.spyOn(chatSDK, 'getConversationDetails').mockResolvedValue({ @@ -3268,7 +3274,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); chatSDK.liveChatConfig = dummyConfig; jest.spyOn(chatSDK, 'getConversationDetails').mockResolvedValue({ @@ -3314,7 +3320,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); chatSDK.liveChatConfig = dummyConfig; jest.spyOn(chatSDK, 'getConversationDetails').mockResolvedValue({ @@ -3365,7 +3371,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); chatSDK.liveChatConfig = dummyConfig; jest.spyOn(chatSDK, 'getConversationDetails').mockResolvedValue({ @@ -3418,7 +3424,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); chatSDK.liveChatConfig = dummyConfig; jest.spyOn(chatSDK, 'getConversationDetails').mockResolvedValue({ @@ -3476,7 +3482,7 @@ describe('Omnichannel Chat SDK, Parallel initialization', () => { const chatSDK = new OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); chatSDK.getChatConfig = jest.fn(); - + chatSDK["isAMSClientAllowed"] = true; await chatSDK.initialize({ useParallelLoad: true }); chatSDK.authSettings = {}; chatSDK.authenticatedUserToken = {}; chatSDK.conversation = {}; diff --git a/src/OmnichannelChatSDK.ts b/src/OmnichannelChatSDK.ts index 4d9074a2..8188dea4 100644 --- a/src/OmnichannelChatSDK.ts +++ b/src/OmnichannelChatSDK.ts @@ -288,6 +288,7 @@ class OmnichannelChatSDK { } private evaluateAMSAvailability(): boolean { + // it will load AMS only if enabled for Customer or Agent support for attachments, based on configuration if (this.liveChatConfig?.LiveWSAndLiveChatEngJoin?.msdyn_enablefileattachmentsforcustomers === "true" || this.liveChatConfig?.LiveWSAndLiveChatEngJoin?.msdyn_enablefileattachmentsforagents === "true") { @@ -308,12 +309,15 @@ class OmnichannelChatSDK { if (this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED) { console.log("AMS NOT LOADED, LOADING NOW"); this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADING; + console.time("ams_creation"); this.AMSClient = await createAMSClient({ framedMode: isBrowser(), multiClient: true, debug: this.debug, logger: this.amsClientLogger as PluggableLogger }); + console.timeEnd("ams_creation"); + console.log("AMS Loaded"); this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADED; } } else { @@ -1634,22 +1638,23 @@ class OmnichannelChatSDK { ChatId: this.chatToken.chatId as string }); - if (this.isAMSClientAllowed === false) { - this.scenarioMarker.failScenario(TelemetryEvent.UploadFileAttachment, { - RequestId: this.requestId, - ChatId: this.chatToken.chatId as string, - ExceptionDetails: "AMSClient is not loaded, please check widget configuration to allow attachments" - }); - throw new Error('AMSClient is disabled. Please enable AMSClient to upload file attachments.'); - } - if (!this.isInitialized) { exceptionThrowers.throwUninitializedChatSDK(this.scenarioMarker, TelemetryEvent.UploadFileAttachment); } - const amsClient = await this.getAMSClient(); - if (this.liveChatVersion === LiveChatVersion.V2) { + + if (this.isAMSClientAllowed === false) { + this.scenarioMarker.failScenario(TelemetryEvent.UploadFileAttachment, { + RequestId: this.requestId, + ChatId: this.chatToken.chatId as string, + ExceptionDetails: "AMSClient is not loaded, please check widget configuration to allow attachments" + }); + throw new Error('AMSClient is disabled. Please enable AMSClient to upload file attachments.'); + } + + const amsClient = await this.getAMSClient(); + const createObjectResponse: any = await amsClient?.createObject(this.chatToken?.chatId as string, fileInfo as any); // eslint-disable-line @typescript-eslint/no-explicit-any const documentId = createObjectResponse.id; const uploadDocumentResponse: any = await amsClient?.uploadDocument(documentId, fileInfo as any); // eslint-disable-line @typescript-eslint/no-explicit-any @@ -1769,19 +1774,18 @@ class OmnichannelChatSDK { exceptionThrowers.throwUninitializedChatSDK(this.scenarioMarker, TelemetryEvent.DownloadFileAttachment); } - if (this.isAMSClientAllowed === false) { - this.scenarioMarker.failScenario(TelemetryEvent.DownloadFileAttachment, { - RequestId: this.requestId, - ChatId: this.chatToken.chatId as string, - ExceptionDetails: "AMSClient is disabled" - }); - throw new Error('AMSClient is not loaded, Enable support for attachment scenarios in the widget configuration.'); - } - - const amsClient = await this.getAMSClient(); - if (this.liveChatVersion === LiveChatVersion.V2) { try { + if (this.isAMSClientAllowed === false) { + this.scenarioMarker.failScenario(TelemetryEvent.DownloadFileAttachment, { + RequestId: this.requestId, + ChatId: this.chatToken.chatId as string, + ExceptionDetails: "AMSClient is disabled" + }); + throw new Error('AMSClient is not loaded, Enable support for attachment scenarios in the widget configuration.'); + } + const amsClient = await this.getAMSClient(); + const response: any = await amsClient?.getViewStatus(fileMetadata); // eslint-disable-line @typescript-eslint/no-explicit-any const { view_location } = response; const viewResponse: any = await amsClient?.getView(fileMetadata, view_location); // eslint-disable-line @typescript-eslint/no-explicit-any From fbe8236a97f208b54e408b5b2e30a50193ef9892 Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Mon, 31 Mar 2025 15:46:46 -0700 Subject: [PATCH 12/27] logs cleanup --- src/OmnichannelChatSDK.ts | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/OmnichannelChatSDK.ts b/src/OmnichannelChatSDK.ts index 8188dea4..c66eab97 100644 --- a/src/OmnichannelChatSDK.ts +++ b/src/OmnichannelChatSDK.ts @@ -232,10 +232,8 @@ class OmnichannelChatSDK { while (retryCount < MAX_RETRY_COUNT) { if (this.AMSClient) { - console.log("AMSClient loaded successfully after retrying."); return this.AMSClient; } - await sleep(RETRY_DELAY_MS); retryCount++; } @@ -247,7 +245,6 @@ class OmnichannelChatSDK { //return null to do not break promisse creation if (this.isAMSClientAllowed === false) { - console.log("AMSClient is not allowed, returning null"); return null; } @@ -256,14 +253,14 @@ class OmnichannelChatSDK { } switch (this.AMSClientLoadCurrentState) { case AMSClientLoadStates.LOADED: - console.log("AMSClient is already loaded"); + this.debug && console.log("AMSClient is already loaded"); return this.AMSClient; case AMSClientLoadStates.LOADING: - console.log("AMSClient is loading, waiting for it to be ready"); + this.debug && console.log("AMSClient is loading, waiting for it to be ready"); return await this.retryLoadAMSClient(); case AMSClientLoadStates.ERROR: case AMSClientLoadStates.NOT_LOADED: - console.log("AMSClient is not loaded, loading now"); + this.debug && console.log("AMSClient is not loaded, loading now"); await this.loadAmsClient(); return this.AMSClient; default: @@ -305,24 +302,22 @@ class OmnichannelChatSDK { this.scenarioMarker.startScenario(TelemetryEvent.InitializeMessagingClient); try { if (this.isAMSClientAllowed) { - console.log("AMS ALLOWED"); + if (this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED) { - console.log("AMS NOT LOADED, LOADING NOW"); this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADING; - console.time("ams_creation"); + this.debug && console.time("ams_creation"); this.AMSClient = await createAMSClient({ framedMode: isBrowser(), multiClient: true, debug: this.debug, logger: this.amsClientLogger as PluggableLogger }); - console.timeEnd("ams_creation"); + this.debug && console.timeEnd("ams_creation"); console.log("AMS Loaded"); this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADED; } - } else { - console.log("AMS NOT ALLOWED"); } + this.scenarioMarker.completeScenario(TelemetryEvent.InitializeMessagingClient); } catch (e) { this.AMSClientLoadCurrentState = AMSClientLoadStates.ERROR; @@ -394,12 +389,14 @@ class OmnichannelChatSDK { if (this.isAMSClientAllowed && this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED) { this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADING; + this.debug && console.time("ams_seq_creation"); this.AMSClient = await createAMSClient({ framedMode: isBrowser(), multiClient: true, debug: this.debug, logger: this.amsClientLogger as PluggableLogger }); + this.debug && console.timeEnd("ams_seq_creation"); this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADED; } @@ -844,12 +841,13 @@ class OmnichannelChatSDK { const attachmentClientPromise = async (): Promise => { try { - if (!this.isAMSClientAllowed) return; - - // will wait till the AMSClient is loaded, and then initialize it - const amsClient = await this.getAMSClient(); if (this.liveChatVersion === LiveChatVersion.V2) { + if (!this.isAMSClientAllowed) return; + // will wait till the AMSClient is loaded, and then initialize it + this.debug && console.time("ams_promise_initialization"); + const amsClient = await this.getAMSClient(); await amsClient?.initialize({ chatToken: this.chatToken as OmnichannelChatToken }); + this.debug && console.timeEnd("ams_promise_initialization"); } } catch (error) { const telemetryData = { @@ -1763,8 +1761,6 @@ class OmnichannelChatSDK { public async downloadFileAttachment(fileMetadata: FileMetadata | IFileMetadata): Promise { - console.log("AMS : downloadFileAttachment"); - this.scenarioMarker.startScenario(TelemetryEvent.DownloadFileAttachment, { RequestId: this.requestId, ChatId: this.chatToken.chatId as string From 1dde753bdc2895dbcb5bca0188b4c93fb61fdea8 Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Mon, 31 Mar 2025 15:53:09 -0700 Subject: [PATCH 13/27] AMS changgelog --- CHANGELOG.md | 6 ++++++ package.json | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 55446bf2..6335655a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ All notable changes to this project will be documented in this file. - Load AMS based on config. +### Fixed +- Fix for methos receiving exceptionDetails , but not logging it in telemetry +- Fix to prevent double load of AMS +- Fix to prevent startchat to finish before AMS client loads. (latency detected, future work to be part of AMS client enhancements) + + ## [1.10.16] - 2025-03-27 ### Added diff --git a/package.json b/package.json index 75220dd1..43d21faf 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,9 @@ "postbuild:tsc": "node ./scripts/copy_files.js", "prebuild:tsc": "eslint src --ext .ts", "test": "npm run test:jsdom && npm run test:node", - "test:jsdom": "jest --config jest.config.jsdom.js", - "test:node": "jest --config jest.config.node.js", + "test:jsdom": "jest --config jest.config.jsdom.js --verbose", + "test:node": "jest --config jest.config.node.js --verbose", + "watch": "tsc --watch", "lint": "eslint src --ext .ts" }, "author": "Microsoft Corporation", From d02225edc08526e3537e86c538c88ea3d5da236e Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Tue, 1 Apr 2025 12:38:37 -0700 Subject: [PATCH 14/27] clean log --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6335655a..1bf6842c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,11 +9,11 @@ All notable changes to this project will be documented in this file. - Load AMS based on config. ### Fixed -- Fix for methos receiving exceptionDetails , but not logging it in telemetry + +- Fix for methods receiving exceptionDetails , but not logging it in telemetry - Fix to prevent double load of AMS - Fix to prevent startchat to finish before AMS client loads. (latency detected, future work to be part of AMS client enhancements) - ## [1.10.16] - 2025-03-27 ### Added From 3f5f052b3cddfc28259345c1e7744edf52365c79 Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Tue, 1 Apr 2025 12:39:51 -0700 Subject: [PATCH 15/27] remove logs --- src/OmnichannelChatSDK.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/OmnichannelChatSDK.ts b/src/OmnichannelChatSDK.ts index c66eab97..fa7353b8 100644 --- a/src/OmnichannelChatSDK.ts +++ b/src/OmnichannelChatSDK.ts @@ -313,7 +313,6 @@ class OmnichannelChatSDK { logger: this.amsClientLogger as PluggableLogger }); this.debug && console.timeEnd("ams_creation"); - console.log("AMS Loaded"); this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADED; } } @@ -1629,8 +1628,6 @@ class OmnichannelChatSDK { public async uploadFileAttachment(fileInfo: IFileInfo | File): Promise { - console.log("AMS : uploadFileAttachment"); - this.scenarioMarker.startScenario(TelemetryEvent.UploadFileAttachment, { RequestId: this.requestId, ChatId: this.chatToken.chatId as string From a8152a0f3cdc584495627f4990a22d2e97a8939f Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Tue, 1 Apr 2025 16:04:41 -0700 Subject: [PATCH 16/27] cosmetic --- package.json | 2 +- src/OmnichannelChatSDK.ts | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 43d21faf..1ccaa4ce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/omnichannel-chat-sdk", - "version": "1.10.17-0", + "version": "1.10.17-0-LOPEZ-1", "description": "Microsoft Omnichannel Chat SDK", "files": [ "lib/**/*" diff --git a/src/OmnichannelChatSDK.ts b/src/OmnichannelChatSDK.ts index fa7353b8..b8006064 100644 --- a/src/OmnichannelChatSDK.ts +++ b/src/OmnichannelChatSDK.ts @@ -302,7 +302,6 @@ class OmnichannelChatSDK { this.scenarioMarker.startScenario(TelemetryEvent.InitializeMessagingClient); try { if (this.isAMSClientAllowed) { - if (this.AMSClientLoadCurrentState === AMSClientLoadStates.NOT_LOADED) { this.AMSClientLoadCurrentState = AMSClientLoadStates.LOADING; this.debug && console.time("ams_creation"); @@ -853,7 +852,6 @@ class OmnichannelChatSDK { RequestId: this.requestId, ChatId: this.chatToken.chatId as string, }; - exceptionThrowers.throwMessagingClientInitializationFailure(error, this.scenarioMarker, TelemetryEvent.StartChat, telemetryData); } }; @@ -1645,7 +1643,7 @@ class OmnichannelChatSDK { ChatId: this.chatToken.chatId as string, ExceptionDetails: "AMSClient is not loaded, please check widget configuration to allow attachments" }); - throw new Error('AMSClient is disabled. Please enable AMSClient to upload file attachments.'); + exceptionThrowers.throwFeatureDisabled(this.scenarioMarker, TelemetryEvent.UploadFileAttachment, "Enable support for attachment upload and receive in the widget configuration."); } const amsClient = await this.getAMSClient(); @@ -1775,7 +1773,7 @@ class OmnichannelChatSDK { ChatId: this.chatToken.chatId as string, ExceptionDetails: "AMSClient is disabled" }); - throw new Error('AMSClient is not loaded, Enable support for attachment scenarios in the widget configuration.'); + exceptionThrowers.throwFeatureDisabled(this.scenarioMarker, TelemetryEvent.DownloadFileAttachment, "Enable support for attachment upload and receive in the widget configuration."); } const amsClient = await this.getAMSClient(); From 42f37f0ab0588e902d4c49ffa180d67934cb6821 Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Fri, 4 Apr 2025 09:56:32 -0700 Subject: [PATCH 17/27] adding check nulls --- src/OmnichannelChatSDK.ts | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/OmnichannelChatSDK.ts b/src/OmnichannelChatSDK.ts index b8006064..52157730 100644 --- a/src/OmnichannelChatSDK.ts +++ b/src/OmnichannelChatSDK.ts @@ -237,7 +237,6 @@ class OmnichannelChatSDK { await sleep(RETRY_DELAY_MS); retryCount++; } - console.error("Failed to load AMSClient after multiple attempts."); return null; } @@ -857,9 +856,13 @@ class OmnichannelChatSDK { }; if (!this.chatSDKConfig.useCreateConversation?.disable) { + console.log("useCreateConversation"); await createConversationPromise(); - await Promise.all([messagingClientPromise(), attachmentClientPromise()]); + await Promise.all([messagingClientPromise(),attachmentClientPromise()]); + } else { + console.log("ELSE useCreateConversation"); + await Promise.all([sessionInitPromise(), messagingClientPromise(), attachmentClientPromise()]); } @@ -1648,6 +1651,14 @@ class OmnichannelChatSDK { const amsClient = await this.getAMSClient(); + if (amsClient === null || amsClient === undefined) { + this.scenarioMarker.failScenario(TelemetryEvent.UploadFileAttachment, { + RequestId: this.requestId, + ChatId: this.chatToken.chatId as string, + ExceptionDetails: "AMSClient is not loaded, please check widget configuration to allow attachments" + }); + } + const createObjectResponse: any = await amsClient?.createObject(this.chatToken?.chatId as string, fileInfo as any); // eslint-disable-line @typescript-eslint/no-explicit-any const documentId = createObjectResponse.id; const uploadDocumentResponse: any = await amsClient?.uploadDocument(documentId, fileInfo as any); // eslint-disable-line @typescript-eslint/no-explicit-any @@ -1777,6 +1788,14 @@ class OmnichannelChatSDK { } const amsClient = await this.getAMSClient(); + if (amsClient === null || amsClient === undefined) { + this.scenarioMarker.failScenario(TelemetryEvent.DownloadFileAttachment, { + RequestId: this.requestId, + ChatId: this.chatToken.chatId as string, + ExceptionDetails: "AMSClient is not loaded, please check widget configuration to allow attachments" + }); + } + const response: any = await amsClient?.getViewStatus(fileMetadata); // eslint-disable-line @typescript-eslint/no-explicit-any const { view_location } = response; const viewResponse: any = await amsClient?.getView(fileMetadata, view_location); // eslint-disable-line @typescript-eslint/no-explicit-any From 32e25ee8d059d6e11b7c54f5e6707a0e4a7f8131 Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Fri, 4 Apr 2025 10:14:11 -0700 Subject: [PATCH 18/27] adding throw --- src/OmnichannelChatSDK.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/OmnichannelChatSDK.ts b/src/OmnichannelChatSDK.ts index 52157730..15d023dc 100644 --- a/src/OmnichannelChatSDK.ts +++ b/src/OmnichannelChatSDK.ts @@ -1655,8 +1655,9 @@ class OmnichannelChatSDK { this.scenarioMarker.failScenario(TelemetryEvent.UploadFileAttachment, { RequestId: this.requestId, ChatId: this.chatToken.chatId as string, - ExceptionDetails: "AMSClient is not loaded, please check widget configuration to allow attachments" + ExceptionDetails: "AMSClient is null, no action can be perfored" }); + throw new Error('AMS client is null, no action can be performed'); } const createObjectResponse: any = await amsClient?.createObject(this.chatToken?.chatId as string, fileInfo as any); // eslint-disable-line @typescript-eslint/no-explicit-any @@ -1792,8 +1793,9 @@ class OmnichannelChatSDK { this.scenarioMarker.failScenario(TelemetryEvent.DownloadFileAttachment, { RequestId: this.requestId, ChatId: this.chatToken.chatId as string, - ExceptionDetails: "AMSClient is not loaded, please check widget configuration to allow attachments" + ExceptionDetails: "AMS client is null, no action can be performed" }); + throw new Error('AMS client is null, no action can be performed'); } const response: any = await amsClient?.getViewStatus(fileMetadata); // eslint-disable-line @typescript-eslint/no-explicit-any From 57fe245411570ae200f1644fea624f931d8221f7 Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Fri, 4 Apr 2025 12:04:24 -0700 Subject: [PATCH 19/27] adding error --- src/core/ChatSDKError.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/core/ChatSDKError.ts b/src/core/ChatSDKError.ts index 31af1c8a..f4571787 100644 --- a/src/core/ChatSDKError.ts +++ b/src/core/ChatSDKError.ts @@ -1,5 +1,3 @@ -import ChatSDKExceptionDetails from "./ChatSDKExceptionDetails"; - /** * Enum of ChatSDK standard errors. * @@ -61,17 +59,17 @@ export enum ChatSDKErrorName { /** Send message failure */ ChatSDKSendMessageFailed = "ChatSDKSendMessageFailed", + AMSClientNotLoaded = "AMSClientNotLoaded", + } export class ChatSDKError { public message: ChatSDKErrorName; public httpResponseStatusCode: number | undefined; - public exceptionDetails: ChatSDKExceptionDetails | undefined; - constructor(message: ChatSDKErrorName, httpResponseStatusCode?: number, exceptionDetails?: ChatSDKExceptionDetails) { + constructor(message: ChatSDKErrorName, httpResponseStatusCode?: number) { this.message = message; this.httpResponseStatusCode = httpResponseStatusCode; - this.exceptionDetails = exceptionDetails; } toString(): string { From c435cf642dc7597c0fe0de7e326b4371ecf8b760 Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Fri, 4 Apr 2025 12:09:09 -0700 Subject: [PATCH 20/27] adding fix --- src/core/ChatSDKError.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/ChatSDKError.ts b/src/core/ChatSDKError.ts index f4571787..fc771095 100644 --- a/src/core/ChatSDKError.ts +++ b/src/core/ChatSDKError.ts @@ -1,3 +1,5 @@ +import ChatSDKExceptionDetails from "./ChatSDKExceptionDetails"; + /** * Enum of ChatSDK standard errors. * @@ -66,10 +68,12 @@ export enum ChatSDKErrorName { export class ChatSDKError { public message: ChatSDKErrorName; public httpResponseStatusCode: number | undefined; + public exceptionDetails: ChatSDKExceptionDetails | undefined; - constructor(message: ChatSDKErrorName, httpResponseStatusCode?: number) { + constructor(message: ChatSDKErrorName, httpResponseStatusCode?: number, exceptionDetails?: ChatSDKExceptionDetails) { this.message = message; this.httpResponseStatusCode = httpResponseStatusCode; + this.exceptionDetails = exceptionDetails; } toString(): string { From be5b4660e248a1908cc8ebaf793527e260a30a1a Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Fri, 4 Apr 2025 12:25:17 -0700 Subject: [PATCH 21/27] adding throw handling --- src/OmnichannelChatSDK.ts | 23 +++-------------------- src/utils/exceptionThrowers.ts | 15 +++++++++------ 2 files changed, 12 insertions(+), 26 deletions(-) diff --git a/src/OmnichannelChatSDK.ts b/src/OmnichannelChatSDK.ts index 15d023dc..e1f4ebc5 100644 --- a/src/OmnichannelChatSDK.ts +++ b/src/OmnichannelChatSDK.ts @@ -11,6 +11,7 @@ import { SDKProvider as OCSDKProvider, uuidv4 } from "@microsoft/ocsdk"; import { createACSAdapter, createDirectLine, createIC3Adapter } from "./utils/chatAdapterCreators"; import { createCoreServicesOrgUrl, getCoreServicesGeoName, isCoreServicesOrgUrl, unqOrgUrlPattern } from "./utils/CoreServicesUtils"; import { defaultLocaleId, getLocaleStringFromId } from "./utils/locale"; +import exceptionThrowers, { throwAMSLoadFailure } from "./utils/exceptionThrowers"; import { getRuntimeId, isClientIdNotFoundErrorMessage, isCustomerMessage } from "./utils/utilities"; import { loadScript, removeElementById, sleep } from "./utils/WebUtils"; import platform, { isBrowser } from "./utils/platform"; @@ -99,7 +100,6 @@ import createTelemetry from "./utils/createTelemetry"; import createVoiceVideoCalling from "./api/createVoiceVideoCalling"; import { defaultMessageTags } from "./core/messaging/MessageTags"; import exceptionSuppressors from "./utils/exceptionSuppressors"; -import exceptionThrowers from "./utils/exceptionThrowers"; import { getLocationInfo } from "./utils/location"; import { isCoreServicesOrgUrlDNSError } from "./utils/internalUtils"; import loggerUtils from "./utils/loggerUtils"; @@ -1641,23 +1641,12 @@ class OmnichannelChatSDK { if (this.liveChatVersion === LiveChatVersion.V2) { if (this.isAMSClientAllowed === false) { - this.scenarioMarker.failScenario(TelemetryEvent.UploadFileAttachment, { - RequestId: this.requestId, - ChatId: this.chatToken.chatId as string, - ExceptionDetails: "AMSClient is not loaded, please check widget configuration to allow attachments" - }); exceptionThrowers.throwFeatureDisabled(this.scenarioMarker, TelemetryEvent.UploadFileAttachment, "Enable support for attachment upload and receive in the widget configuration."); } - const amsClient = await this.getAMSClient(); if (amsClient === null || amsClient === undefined) { - this.scenarioMarker.failScenario(TelemetryEvent.UploadFileAttachment, { - RequestId: this.requestId, - ChatId: this.chatToken.chatId as string, - ExceptionDetails: "AMSClient is null, no action can be perfored" - }); - throw new Error('AMS client is null, no action can be performed'); + throwAMSLoadFailure(this.scenarioMarker, TelemetryEvent.UploadFileAttachment, "AMS client is null, no action can be performed"); } const createObjectResponse: any = await amsClient?.createObject(this.chatToken?.chatId as string, fileInfo as any); // eslint-disable-line @typescript-eslint/no-explicit-any @@ -1712,7 +1701,6 @@ class OmnichannelChatSDK { return messageToSend; } catch (error) { console.error("OmnichannelChatSDK/uploadFileAttachment/sendMessage/error"); - this.scenarioMarker.failScenario(TelemetryEvent.UploadFileAttachment, { RequestId: this.requestId, ChatId: this.chatToken.chatId as string @@ -1790,12 +1778,7 @@ class OmnichannelChatSDK { const amsClient = await this.getAMSClient(); if (amsClient === null || amsClient === undefined) { - this.scenarioMarker.failScenario(TelemetryEvent.DownloadFileAttachment, { - RequestId: this.requestId, - ChatId: this.chatToken.chatId as string, - ExceptionDetails: "AMS client is null, no action can be performed" - }); - throw new Error('AMS client is null, no action can be performed'); + throwAMSLoadFailure(this.scenarioMarker, TelemetryEvent.DownloadFileAttachment, "AMS client is null, no action can be performed"); } const response: any = await amsClient?.getViewStatus(fileMetadata); // eslint-disable-line @typescript-eslint/no-explicit-any diff --git a/src/utils/exceptionThrowers.ts b/src/utils/exceptionThrowers.ts index 646a2e55..b024ddb5 100644 --- a/src/utils/exceptionThrowers.ts +++ b/src/utils/exceptionThrowers.ts @@ -18,7 +18,7 @@ import ChatSDKExceptionDetails from "../core/ChatSDKExceptionDetails"; import ScenarioMarker from "../telemetry/ScenarioMarker"; import TelemetryEvent from "../telemetry/TelemetryEvent"; -export const throwChatSDKError = (chatSDKError: ChatSDKErrorName, e: unknown, scenarioMarker: ScenarioMarker, telemetryEvent: TelemetryEvent, telemetryData: {[key: string]: string} = {}, message = ""): void => { +export const throwChatSDKError = (chatSDKError: ChatSDKErrorName, e: unknown, scenarioMarker: ScenarioMarker, telemetryEvent: TelemetryEvent, telemetryData: { [key: string]: string } = {}, message?: string): void => { const exceptionDetails: ChatSDKExceptionDetails = { response: chatSDKError }; @@ -27,16 +27,15 @@ export const throwChatSDKError = (chatSDKError: ChatSDKErrorName, e: unknown, sc exceptionDetails.errorObject = `${e}`; } + if (message) { + exceptionDetails.message = message; + } + scenarioMarker.failScenario(telemetryEvent, { ...telemetryData, ExceptionDetails: JSON.stringify(exceptionDetails) }); - if (message) { - exceptionDetails.message = message; - console.error(message); - } - throw new ChatSDKError( chatSDKError, // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -45,6 +44,10 @@ export const throwChatSDKError = (chatSDKError: ChatSDKErrorName, e: unknown, sc ); } +export const throwAMSLoadFailure = (scenarioMarker: ScenarioMarker, telemetryEvent: TelemetryEvent, message: string): void => { + throwChatSDKError(ChatSDKErrorName.AMSClientNotLoaded, undefined, scenarioMarker, telemetryEvent, {}, message); +}; + export const throwScriptLoadFailure = (e: unknown, scenarioMarker: ScenarioMarker, telemetryEvent: TelemetryEvent): void => { throwChatSDKError(ChatSDKErrorName.ScriptLoadFailure, e, scenarioMarker, telemetryEvent); }; From c6f6955ab079f4e8860702889c75ac57148a8f13 Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Fri, 4 Apr 2025 12:32:12 -0700 Subject: [PATCH 22/27] fix --- README.md | 110 ++++++++++++++++++++++---------------- package.json | 2 +- src/OmnichannelChatSDK.ts | 2 +- 3 files changed, 65 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index cf3ad9cf..b830d03f 100644 --- a/README.md +++ b/README.md @@ -14,48 +14,49 @@ Headless Chat SDK to build your own chat widget against Dynamics 365 Omnichannel Please make sure you have a chat widget configured before using this package or you can follow this [link](https://docs.microsoft.com/en-us/dynamics365/customer-service/add-chat-widget) ## Table of Contents + - [Live Chat Widget vs. Chat SDK](#live-chat-widget-vs-chat-sdk) - [Releases](#releases) - [Installation](#installation) - [Installation on React Native](#installation-on-react-native) - [SDK Methods](#sdk-methods) - - [Initialization](#initialization) - - [Start Chat](#start-chat) - - [End Chat](#end-chat) - - [Get Pre-Chat Survey](#get-pre-chat-survey) - - [Get Live Chat Config](#get-live-chat-config) - - [Get Current Live Chat Context](#get-current-live-chat-context) - - [Get Data Masking Rules](#get-data-masking-rules) - - [Get Chat Reconnect Context](#get-chat-reconnect-context) - - [Get Conversation Details](#get-conversation-details) - - [Get Chat Token](#get-chat-token) - - [Get Calling Token](#get-calling-token) - - [Get Messages](#get-messages) - - [Send Messages](#send-messages) - - [On New Message](#on-new-message) - - [On Typing Event](#on-typing-event) - - [On Agent End Session](#on-agent-end-session) - - [Send Typing Event](#send-typing-event) - - [Email Live Chat Transcript](#email-live-chat-transcript) - - [Get Live Chat Transcript](#get-live-chat-transcript) - - [Upload File Attachment](#upload-file-attachment) - - [Download File Attachment](#download-file-attachment) - - [Create Chat Adapter](#create-chat-adapter) - - [Get Voice & Video Calling](#get-voice--video-calling) - - [Get Post Chat Survey Context](#get-post-chat-survey-context) + - [Initialization](#initialization) + - [Start Chat](#start-chat) + - [End Chat](#end-chat) + - [Get Pre-Chat Survey](#get-pre-chat-survey) + - [Get Live Chat Config](#get-live-chat-config) + - [Get Current Live Chat Context](#get-current-live-chat-context) + - [Get Data Masking Rules](#get-data-masking-rules) + - [Get Chat Reconnect Context](#get-chat-reconnect-context) + - [Get Conversation Details](#get-conversation-details) + - [Get Chat Token](#get-chat-token) + - [Get Calling Token](#get-calling-token) + - [Get Messages](#get-messages) + - [Send Messages](#send-messages) + - [On New Message](#on-new-message) + - [On Typing Event](#on-typing-event) + - [On Agent End Session](#on-agent-end-session) + - [Send Typing Event](#send-typing-event) + - [Email Live Chat Transcript](#email-live-chat-transcript) + - [Get Live Chat Transcript](#get-live-chat-transcript) + - [Upload File Attachment](#upload-file-attachment) + - [Download File Attachment](#download-file-attachment) + - [Create Chat Adapter](#create-chat-adapter) + - [Get Voice & Video Calling](#get-voice--video-calling) + - [Get Post Chat Survey Context](#get-post-chat-survey-context) - [Common Scenarios](#common-scenarios) - - [Using BotFramework-WebChat](#using-botframework-webchat) - - [Escalation to Voice & Video](#escalation-to-voice--video) - - [Pre-Chat Survey](#pre-chat-survey) - - [Post-Chat Survey](#post-chat-survey) - - [Reconnect to existing Chat](#reconnect-to-existing-chat) - - [Authenticated Chat](#authenticated-chat) - - [Persistent Chat](#persistent-chat) - - [Chat Reconnect with Authenticated User](#chat-reconnect-with-authenticated-user) - - [Chat Reconnect with Unauthenticated User](#chat-reconnect-with-unauthenticated-user) - - [Handling chat Disconnect on Mobile platform](#handling-chat-disconnect-on-mobile-platform) - - [Operating Hours](#operating-hours) - - [Single Sign-on for Bots](/docs/scenarios/SINGLE_SIGN_ON_FOR_BOTS.md) + - [Using BotFramework-WebChat](#using-botframework-webchat) + - [Escalation to Voice & Video](#escalation-to-voice--video) + - [Pre-Chat Survey](#pre-chat-survey) + - [Post-Chat Survey](#post-chat-survey) + - [Reconnect to existing Chat](#reconnect-to-existing-chat) + - [Authenticated Chat](#authenticated-chat) + - [Persistent Chat](#persistent-chat) + - [Chat Reconnect with Authenticated User](#chat-reconnect-with-authenticated-user) + - [Chat Reconnect with Unauthenticated User](#chat-reconnect-with-unauthenticated-user) + - [Handling chat Disconnect on Mobile platform](#handling-chat-disconnect-on-mobile-platform) + - [Operating Hours](#operating-hours) + - [Single Sign-on for Bots](/docs/scenarios/SINGLE_SIGN_ON_FOR_BOTS.md) - [Sample Apps](https://github.com/microsoft/omnichannel-chat-sdk-samples) - [Feature Comparisons](#feature-comparisons) - [Telemetry](#telemetry) @@ -65,6 +66,7 @@ Please make sure you have a chat widget configured before using this package or ## Live Chat Widget vs. Chat SDK Omnichannel offers a live chat widget (LCW) by default. You can use the Chat SDK to build your custom chat widget if: + - You want to fully customize the user interface of the chat widget to conform with your branding. - You want to integrate Omnichannel into your mobile app using React Native. - You want to integrate additional functionalities that LCW does not offer. @@ -151,31 +153,37 @@ npm install @microsoft/omnichannel-chat-sdk --save The following steps will be required to run Omnichannel Chat SDK on React Native: 1. Install `node-libs-react-native` + ``` npm install node-libs-react-native --save-dev ``` 1. Install `react-native-randomBytes` + ``` npm install react-native-randombytes --save-dev ``` 1. Install `react-native-get-random-values` + ``` npm install react-native-get-random-values --save-dev ``` 1. Install `react-native-url-polyfill` + ``` npm install react-native-url-polyfill --save-dev ``` 1. Install `@azure/core-asynciterator-polyfill` + ``` npm install @azure/core-asynciterator-polyfill --save-dev ``` 1. Update *metro.config.js* to use React Native compatible Node Core modules + ```ts module.exports = { // ... @@ -190,6 +198,7 @@ The following steps will be required to run Omnichannel Chat SDK on React Native ``` 1. Add the following *import* on top of your entry point file + ```ts import 'node-libs-react-native/globals'; import 'react-native-get-random-values'; @@ -230,7 +239,7 @@ const optionalParams = { }; -// For the case when the widget doesnt have enabled support for attachments, AMS wont be loaded. +// For the case when the widget doesnt have enabled support for attachments, Upload/download operations wont be supported await chatSDK.initialize(optionalParams); ``` @@ -398,6 +407,7 @@ chatSDK.onNewMessage((message) => { console.log(message); }, optionalParams); ``` + ### On Typing Event It subscribes to an agent typing event. @@ -516,6 +526,7 @@ try { } } ``` + ### Get Post Chat Survey Context It gets the participant type that should be used for the survey and both the default and bot survey details. @@ -536,7 +547,7 @@ const agentAvailability = await chatSDK.getAgentAvailability(); ### Pre-Chat Survey -> See https://docs.microsoft.com/en-us/dynamics365/customer-service/configure-pre-chat-survey?tabs=customerserviceadmincenter on how to set up pre-conversation surveys +> See on how to set up pre-conversation surveys ```ts import * as AdaptiveCards, { Action } from "adaptivecards"; @@ -571,7 +582,7 @@ const agentAvailability = await chatSDK.getAgentAvailability(); ### Post-Chat Survey -> See https://docs.microsoft.com/en-us/dynamics365/customer-service/configure-post-conversation-survey?tabs=customerserviceadmincenter on how to set up post-conversation surveys +> See on how to set up post-conversation surveys > ❗ `chatSDK.getPostChatSurveyContext()` needs to be called before `chatSDK.endChat()` is called @@ -630,7 +641,7 @@ messages.reverse().forEach((message: any) => renderMessage(message)); // Logic t ### Authenticated Chat -> See https://docs.microsoft.com/en-us/dynamics365/customer-service/create-chat-auth-settings?tabs=customerserviceadmincenter#create-a-chat-authentication-setting-record on how to set up an authenticated chat +> See on how to set up an authenticated chat ```ts const chatSDKConfig = { @@ -653,7 +664,7 @@ await chatSDK.initialize(); ### Persistent Chat -> See https://docs.microsoft.com/en-us/dynamics365/customer-service/persistent-chat on how to set up persistent chat +> See on how to set up persistent chat ```ts const chatSDKConfig = { @@ -677,9 +688,10 @@ await chatSDK.initialize(); // from this point, this acts like a persistent chat ``` + ### Chat Reconnect with Authenticated User -> See https://docs.microsoft.com/en-us/dynamics365/customer-service/configure-reconnect-chat?tabs=customerserviceadmincenter#enable-reconnection-to-a-previous-chat-session on how to set up chat reconnect +> See on how to set up chat reconnect ```ts const chatSDKConfig = { @@ -719,7 +731,7 @@ chatSDK.startChat(); ### Chat Reconnect with Unauthenticated User -> See https://docs.microsoft.com/en-us/dynamics365/customer-service/configure-reconnect-chat?tabs=customerserviceadmincenter#enable-reconnection-to-a-previous-chat-session on how to set up chat reconnect +> See on how to set up chat reconnect ```ts const chatSDKConfig = { @@ -763,7 +775,7 @@ if (chatReconnectContext.reconnectId) { ### Operating Hours -> See https://docs.microsoft.com/en-us/dynamics365/customer-service/create-operating-hours?tabs=customerserviceadmincenter on how to set up operating hours +> See on how to set up operating hours ```ts const chatConfig = await chatSDK.getLiveChatConfig(); @@ -800,11 +812,12 @@ window.addEventListener("visibilitychange", async () => { }); ``` - ### Using [BotFramework-WebChat](https://github.com/microsoft/BotFramework-WebChat) +> > :warning: Currently supported on web only Minimum Requirement Checklist + 1. [ ] Initialize ChatSDK 1. [ ] Start new conversation 1. [ ] Create Chat Adapter @@ -842,9 +855,10 @@ const store = createStore( ``` ### Escalation to Voice & Video +> > :warning: Currently supported on web only -> See https://docs.microsoft.com/en-us/dynamics365/customer-service/call-options-visual-engagement on how to set up calling options +> See on how to set up calling options ```ts import OmnichannelChatSDK from '@microsoft/omnichannel-chat-sdk'; @@ -952,6 +966,7 @@ if (VoiceVideoCallingSDK) { ## Feature Comparisons ### Web + | | Custom Control | WebChat Control | | --- | --- | --- | | **Features** | | | @@ -963,6 +978,7 @@ if (VoiceVideoCallingSDK) { | Incoming messages handling | IC3 protocol message data | DirectLine activity data | ### React Native + | | Custom Control | Gifted Chat Control | WebChat Control | | --- | --- | --- | --- | | **Features** | | | Currently not supported | @@ -1011,7 +1027,7 @@ await chatSDK.initialize(); This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us -the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. +the rights to use your contribution. For details, visit . When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions diff --git a/package.json b/package.json index 1ccaa4ce..43d21faf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/omnichannel-chat-sdk", - "version": "1.10.17-0-LOPEZ-1", + "version": "1.10.17-0", "description": "Microsoft Omnichannel Chat SDK", "files": [ "lib/**/*" diff --git a/src/OmnichannelChatSDK.ts b/src/OmnichannelChatSDK.ts index e1f4ebc5..f86d4c51 100644 --- a/src/OmnichannelChatSDK.ts +++ b/src/OmnichannelChatSDK.ts @@ -242,7 +242,7 @@ class OmnichannelChatSDK { private async getAMSClient(): Promise { - //return null to do not break promisse creation + //return null to do not break promise creation if (this.isAMSClientAllowed === false) { return null; } From d7189c9638021681dfd5405739ea87f365757f35 Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Fri, 4 Apr 2025 12:35:28 -0700 Subject: [PATCH 23/27] remove logs --- src/OmnichannelChatSDK.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/OmnichannelChatSDK.ts b/src/OmnichannelChatSDK.ts index f86d4c51..49d506e3 100644 --- a/src/OmnichannelChatSDK.ts +++ b/src/OmnichannelChatSDK.ts @@ -856,13 +856,9 @@ class OmnichannelChatSDK { }; if (!this.chatSDKConfig.useCreateConversation?.disable) { - console.log("useCreateConversation"); await createConversationPromise(); await Promise.all([messagingClientPromise(),attachmentClientPromise()]); - } else { - console.log("ELSE useCreateConversation"); - await Promise.all([sessionInitPromise(), messagingClientPromise(), attachmentClientPromise()]); } From f0610d45be70e266809fd996a0df994e7510a5bb Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Fri, 4 Apr 2025 12:44:04 -0700 Subject: [PATCH 24/27] fix --- src/utils/exceptionThrowers.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils/exceptionThrowers.ts b/src/utils/exceptionThrowers.ts index b024ddb5..42818060 100644 --- a/src/utils/exceptionThrowers.ts +++ b/src/utils/exceptionThrowers.ts @@ -29,6 +29,7 @@ export const throwChatSDKError = (chatSDKError: ChatSDKErrorName, e: unknown, sc if (message) { exceptionDetails.message = message; + console.error(message); } scenarioMarker.failScenario(telemetryEvent, { From 5913aa8aef8563945bd3046a905942cb64ac9458 Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Fri, 4 Apr 2025 13:26:48 -0700 Subject: [PATCH 25/27] fix for sequential load --- src/OmnichannelChatSDK.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OmnichannelChatSDK.ts b/src/OmnichannelChatSDK.ts index 49d506e3..1a1ae619 100644 --- a/src/OmnichannelChatSDK.ts +++ b/src/OmnichannelChatSDK.ts @@ -442,7 +442,6 @@ class OmnichannelChatSDK { const { getLiveChatConfigOptionalParams } = optionalParams; await this.getChatConfig(getLiveChatConfigOptionalParams || {}); // once we have the config, we can check if we need to load AMS - this.evaluateAMSAvailability(); } catch (e) { exceptionThrowers.throwChatConfigRetrievalFailure(e, this.scenarioMarker, TelemetryEvent.InitializeLoadChatConfig); } @@ -2441,6 +2440,7 @@ class OmnichannelChatSDK { liveChatConfig = await this.OCClient.getChatConfig(this.requestId, bypassCache); this.liveChatConfig = liveChatConfig; + this.evaluateAMSAvailability(); this.buildConfigurations(liveChatConfig); /* istanbul ignore next */ this.debug && console.log(`[OmnichannelChatSDK][getChatConfig][liveChatVersion] ${this.liveChatVersion}`); From 3c5e832f9e40a8c7b67fee60c738750fa2d4f776 Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Mon, 7 Apr 2025 14:16:43 -0700 Subject: [PATCH 26/27] fix comments --- README.md | 44 +++++++++---------- __tests__/OmnichannelChatSDK.web.spec.ts | 1 + .../OmnichannelChatSDKParallel.web.spec.ts | 1 + src/OmnichannelChatSDK.ts | 10 ++--- src/core/ChatSDKError.ts | 2 +- src/utils/exceptionThrowers.ts | 2 +- 6 files changed, 31 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index b830d03f..0fa99757 100644 --- a/README.md +++ b/README.md @@ -77,24 +77,24 @@ Omnichannel offers a live chat widget (LCW) by default. You can use the Chat SDK | Feature | Live Chat Widget | Chat SDK | Notes | | ----- | ----- | ----- | ----- | | Bring Your Own Widget | ❌ | ✔ | | -| Web Support | ✔ | ✔ | -| React Native Support | ❌ | ✔ | +| Web Support | ✔ | ✔ || +| React Native Support | ❌ | ✔ | | | Escalation to Voice & Video | ✔ | ✔ | Only supported on Web | | Co-browse | ✔ | 3rd party add-on | Only supported on Web | | Screen Sharing | ✔ | 3rd party add-on | Only supported on Web | -| Authenticated Chat | ✔ | ✔ | -| Pre-chat Survey | ✔ | ✔ | -| Post-chat Survey | ✔ | ✔ | -| Download Transcript | ✔ | ✔ | -| Email Transcript | ✔ | ✔ | -| Data Masking | ✔ | ✔ | -| File Attachments | ✔ | ✔ | -| Custom Context | ✔ | ✔ | -| Proactive Chat | ✔ | BYOI **\*** | -| Persistent Chat | ✔ | ✔ | -| Chat Reconnect | ✔ | ✔ | -| Operating Hours | ✔ | ✔ | -| Get Agent Availability | ✔ | ✔ | +| Authenticated Chat | ✔ | ✔ | | +| Pre-chat Survey | ✔ | ✔ | | +| Post-chat Survey | ✔ | ✔ | | +| Download Transcript | ✔ | ✔ | | +| Email Transcript | ✔ | ✔ | | +| Data Masking | ✔ | ✔ | | +| File Attachments | ✔ | ✔ | | +| Custom Context | ✔ | ✔ | | +| Proactive Chat | ✔ | BYOI **\*** | | +| Persistent Chat | ✔ | ✔ | | +| Chat Reconnect | ✔ | ✔ | | +| Operating Hours | ✔ | ✔ | | +| Get Agent Availability | ✔ | ✔ | | | Queue Position | ✔ | ✔ | No SDK method. Handled as *system message* | | Average Wait Time | ✔ | ✔ | No SDK method. Handled as *system message* | @@ -144,7 +144,7 @@ New releases are published on a regular basis to ensure the product quality. ## Installation -``` +```console npm install @microsoft/omnichannel-chat-sdk --save ``` @@ -154,31 +154,31 @@ The following steps will be required to run Omnichannel Chat SDK on React Native 1. Install `node-libs-react-native` - ``` + ```console npm install node-libs-react-native --save-dev ``` 1. Install `react-native-randomBytes` - ``` + ```console npm install react-native-randombytes --save-dev ``` 1. Install `react-native-get-random-values` - ``` + ```console npm install react-native-get-random-values --save-dev ``` 1. Install `react-native-url-polyfill` - ``` + ```console npm install react-native-url-polyfill --save-dev ``` 1. Install `@azure/core-asynciterator-polyfill` - ``` + ```console npm install @azure/core-asynciterator-polyfill --save-dev ``` @@ -973,7 +973,7 @@ if (VoiceVideoCallingSDK) { | Chat Widget UI | Not provided | Basic chat client provided | | Data Masking | Embedded | Requires `Data Masking Middleware` implementation | | Send Typing indicator | Embedded | Requires `sendTypingIndicator` flag set to `true` | -| PreChat Survey | Requires Adaptive Cards renderer | Requires Adaptive Cards renderer +| PreChat Survey | Requires Adaptive Cards renderer | Requires Adaptive Cards renderer| | Display Attachments | Requires implementation | Basic interface provided & Customizable | | Incoming messages handling | IC3 protocol message data | DirectLine activity data | diff --git a/__tests__/OmnichannelChatSDK.web.spec.ts b/__tests__/OmnichannelChatSDK.web.spec.ts index cb3cee7d..7968f28b 100644 --- a/__tests__/OmnichannelChatSDK.web.spec.ts +++ b/__tests__/OmnichannelChatSDK.web.spec.ts @@ -95,6 +95,7 @@ describe('Omnichannel Chat SDK (Web), Sequential', () => { try { await chatSDK.startChat(optionalParams); + fail("Error expected"); } catch (error : any ) { expect(error.message).toEqual(ChatSDKErrorName.UnsupportedPlatform); expect(console.error).toHaveBeenCalledWith("sendDefaultInitContext is only supported on browser"); diff --git a/__tests__/OmnichannelChatSDKParallel.web.spec.ts b/__tests__/OmnichannelChatSDKParallel.web.spec.ts index db3fa324..17048399 100644 --- a/__tests__/OmnichannelChatSDKParallel.web.spec.ts +++ b/__tests__/OmnichannelChatSDKParallel.web.spec.ts @@ -104,6 +104,7 @@ describe('Omnichannel Chat SDK (Web)', () => { try { await chatSDK.startChat(optionalParams); + fail("Error expected"); } catch (error : any ) { expect(error.message).toEqual(ChatSDKErrorName.UnsupportedPlatform); expect(console.error).toHaveBeenCalledWith("sendDefaultInitContext is only supported on browser"); diff --git a/src/OmnichannelChatSDK.ts b/src/OmnichannelChatSDK.ts index 1a1ae619..b958d563 100644 --- a/src/OmnichannelChatSDK.ts +++ b/src/OmnichannelChatSDK.ts @@ -252,14 +252,14 @@ class OmnichannelChatSDK { } switch (this.AMSClientLoadCurrentState) { case AMSClientLoadStates.LOADED: - this.debug && console.log("AMSClient is already loaded"); + this.debug && console.log("Attachment handler is already loaded"); return this.AMSClient; case AMSClientLoadStates.LOADING: - this.debug && console.log("AMSClient is loading, waiting for it to be ready"); + this.debug && console.log("Attachment handler is loading, waiting for it to be ready"); return await this.retryLoadAMSClient(); case AMSClientLoadStates.ERROR: case AMSClientLoadStates.NOT_LOADED: - this.debug && console.log("AMSClient is not loaded, loading now"); + this.debug && console.log("Attachment handler is not loaded, loading now"); await this.loadAmsClient(); return this.AMSClient; default: @@ -1641,7 +1641,7 @@ class OmnichannelChatSDK { const amsClient = await this.getAMSClient(); if (amsClient === null || amsClient === undefined) { - throwAMSLoadFailure(this.scenarioMarker, TelemetryEvent.UploadFileAttachment, "AMS client is null, no action can be performed"); + throwAMSLoadFailure(this.scenarioMarker, TelemetryEvent.UploadFileAttachment, "Attachment handler client is null, no action can be performed"); } const createObjectResponse: any = await amsClient?.createObject(this.chatToken?.chatId as string, fileInfo as any); // eslint-disable-line @typescript-eslint/no-explicit-any @@ -1773,7 +1773,7 @@ class OmnichannelChatSDK { const amsClient = await this.getAMSClient(); if (amsClient === null || amsClient === undefined) { - throwAMSLoadFailure(this.scenarioMarker, TelemetryEvent.DownloadFileAttachment, "AMS client is null, no action can be performed"); + throwAMSLoadFailure(this.scenarioMarker, TelemetryEvent.DownloadFileAttachment, "Attachment handler is null, no action can be performed"); } const response: any = await amsClient?.getViewStatus(fileMetadata); // eslint-disable-line @typescript-eslint/no-explicit-any diff --git a/src/core/ChatSDKError.ts b/src/core/ChatSDKError.ts index fc771095..30b45836 100644 --- a/src/core/ChatSDKError.ts +++ b/src/core/ChatSDKError.ts @@ -61,7 +61,7 @@ export enum ChatSDKErrorName { /** Send message failure */ ChatSDKSendMessageFailed = "ChatSDKSendMessageFailed", - AMSClientNotLoaded = "AMSClientNotLoaded", + AttachmentClientNotLoaded = "AttachmentClientNotLoaded", } diff --git a/src/utils/exceptionThrowers.ts b/src/utils/exceptionThrowers.ts index 42818060..da1106a7 100644 --- a/src/utils/exceptionThrowers.ts +++ b/src/utils/exceptionThrowers.ts @@ -46,7 +46,7 @@ export const throwChatSDKError = (chatSDKError: ChatSDKErrorName, e: unknown, sc } export const throwAMSLoadFailure = (scenarioMarker: ScenarioMarker, telemetryEvent: TelemetryEvent, message: string): void => { - throwChatSDKError(ChatSDKErrorName.AMSClientNotLoaded, undefined, scenarioMarker, telemetryEvent, {}, message); + throwChatSDKError(ChatSDKErrorName.AttachmentClientNotLoaded, undefined, scenarioMarker, telemetryEvent, {}, message); }; export const throwScriptLoadFailure = (e: unknown, scenarioMarker: ScenarioMarker, telemetryEvent: TelemetryEvent): void => { From 04fcce100a92d6d7caecc20cfea52b49f463bdd6 Mon Sep 17 00:00:00 2001 From: Edgar Lopez Date: Mon, 7 Apr 2025 14:24:58 -0700 Subject: [PATCH 27/27] changes --- src/core/InitializeOptionalParams.ts | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/core/InitializeOptionalParams.ts b/src/core/InitializeOptionalParams.ts index f02460d0..479adac3 100644 --- a/src/core/InitializeOptionalParams.ts +++ b/src/core/InitializeOptionalParams.ts @@ -1,22 +1,7 @@ import GetLiveChatConfigOptionalParams from "./GetLiveChatConfigOptionalParams" -/** - * Interface representing optional parameters for initialization. - * - * @property getLiveChatConfigOptionalParams - Optional parameters for retrieving the live chat configuration. - * @property useParallelLoad - deprecated. this is not longer evaluated but was not removed for backward compatibility. - * @property useSequentialLoad - Indicates whether to load resources sequentially. If set to `true`, resources will be loaded one after another in sequence. - */ interface InitializeOptionalParams { - /** - * Optional parameters for retrieving the live chat configuration. - */ getLiveChatConfigOptionalParams?: GetLiveChatConfigOptionalParams; - - /** - * Indicates whether to load resources in parallel. - * Not longer evaluated but was not removed for backward compatibility. - */ useParallelLoad?: boolean; }