@microsoft/omnichannel-chat-sdk 2.0.0-main.983bdbd → 2.0.0-main.be72877

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -22,7 +22,6 @@ Please make sure you have a chat widget configured before using this package or
22
22
  - [SDK Methods](#sdk-methods)
23
23
  - [Initialization](#initialization)
24
24
  - [Start Chat](#start-chat)
25
- - [Authenticate Chat](#authenticate-chat)
26
25
  - [End Chat](#end-chat)
27
26
  - [Get Pre-Chat Survey](#get-pre-chat-survey)
28
27
  - [Get Live Chat Config](#get-live-chat-config)
@@ -135,7 +134,7 @@ The npm `latest` dist-tag can point to a `main` prerelease. Use the exact versio
135
134
 
136
135
  Regenerate the application lockfile after the update. Then run the application build and tests on Node.js 22.
137
136
 
138
- Version `2.0.0` adds progressive bot-message streaming, mid-conversation authentication, read receipts, and unread-message counts. Existing `onNewMessage` handlers continue to receive final streaming messages.
137
+ Version `2.0.0` adds progressive bot-message streaming, read receipts, and unread-message counts. Existing `onNewMessage` handlers continue to receive final streaming messages.
139
138
 
140
139
  See the [2.0 migration guide](docs/MIGRATION_2.0.md) for the complete upgrade and validation procedure.
141
140
 
@@ -331,32 +330,6 @@ const optionalParams = {
331
330
  await chatSDK.startChat(optionalParams);
332
331
  ```
333
332
 
334
- ### Authenticate Chat
335
-
336
- It authenticates an active unauthenticated conversation. Enable optional authenticated sign-in for the workstream before you use this method.
337
-
338
- Call `initialize()` and `startChat()` before `authenticateChat()`. The first argument can be a token or an asynchronous token provider.
339
-
340
- ```ts
341
- await chatSDK.initialize();
342
- await chatSDK.startChat();
343
-
344
- await chatSDK.authenticateChat(async () => {
345
- const response = await fetch("https://contoso.example/token");
346
- if (!response.ok) {
347
- throw new Error("Token request failed");
348
- }
349
-
350
- return response.text();
351
- }, {
352
- refreshChatToken: true
353
- });
354
- ```
355
-
356
- Set `refreshChatToken` to `true` when subsequent SDK calls must use a refreshed authenticated chat token.
357
-
358
- The method throws `InvalidConversation` when no conversation is active. It throws `MidConversationAuthFailure` when token resolution or authentication fails.
359
-
360
333
  ### End Chat
361
334
 
362
335
  It ends the current Omnichannel conversation.
@@ -503,7 +476,7 @@ chatSDK.onNewMessage((message) => {
503
476
 
504
477
  ### On Streaming Message
505
478
 
506
- It subscribes to progressive ACS bot-message updates. This API is available only for Live Chat version 2.
479
+ It subscribes to progressive ACS bot-message updates.
507
480
 
508
481
  Enable streaming when you start the conversation. Then register the handler after `startChat()` completes.
509
482
 
@@ -531,7 +504,7 @@ await chatSDK.onStreamingMessage((message) => {
531
504
 
532
505
  `streamingMessageType` can be `start`, `informative`, `streaming`, or `final`. A final message also reaches existing `onNewMessage` handlers.
533
506
 
534
- Calling this method before `startChat()` throws `UninitializedConversation`. Calling it for another Live Chat version throws `UnsupportedLiveChatVersion`.
507
+ Calling this method before `startChat()` throws `UninitializedConversation`. If the conversation does not use ACS, this method throws `UnsupportedLiveChatVersion`.
535
508
 
536
509
  ### On Typing Event
537
510
 
@@ -690,7 +663,7 @@ const agentAvailability = await chatSDK.getAgentAvailability();
690
663
 
691
664
  Logs a particular message (and all previous messages) as read by the user. Read indicators will appear for Contact Center Representatives and Admins in the Admin Center.
692
665
 
693
- Authenticated chat sends the receipt through Messaging Runtime. Unauthenticated chat sends it through ACS and requires Live Chat version 2.
666
+ Authenticated chat sends the receipt through Messaging Runtime. Unauthenticated chat sends the receipt through ACS.
694
667
 
695
668
  ```ts
696
669
  await chatSDK.sendReadReceipt(messageId: string);
@@ -109,6 +109,7 @@ var startPolling_1 = require("./commands/startPolling");
109
109
  var stopPolling_1 = require("./commands/stopPolling");
110
110
  var urlResolvers_1 = require("./utils/urlResolvers");
111
111
  var OmnichannelConfigValidator_1 = require("./validators/OmnichannelConfigValidator");
112
+ var prefetchedConfigValidator_1 = require("./validators/prefetchedConfigValidator");
112
113
  var OmnichannelChatSDK = /** @class */ (function () {
113
114
  function OmnichannelChatSDK(omnichannelConfig, chatSDKConfig) {
114
115
  if (chatSDKConfig === void 0) { chatSDKConfig = SDKConfigValidators_1.defaultChatSDKConfig; }
@@ -1281,10 +1282,10 @@ var OmnichannelChatSDK = /** @class */ (function () {
1281
1282
  };
1282
1283
  OmnichannelChatSDK.prototype.closeChat = function (endChatOptionalParams) {
1283
1284
  return __awaiter(this, void 0, void 0, function () {
1284
- var cleanupMetadata, sessionCloseOptionalParams, isReconnectChat, isChatReconnect, error_14;
1285
- var _a, _b;
1286
- return __generator(this, function (_c) {
1287
- switch (_c.label) {
1285
+ var cleanupMetadata, sessionCloseOptionalParams, sessionCloseRequestId, isReconnectChat, isChatReconnect, error_14;
1286
+ var _a, _b, _c, _d, _e, _f;
1287
+ return __generator(this, function (_g) {
1288
+ switch (_g.label) {
1288
1289
  case 0:
1289
1290
  cleanupMetadata = {
1290
1291
  RequestId: this.requestId,
@@ -1294,34 +1295,43 @@ var OmnichannelChatSDK = /** @class */ (function () {
1294
1295
  // in case a session was ended by agent or disconnected, there is no need to close the session
1295
1296
  this.scenarioMarker.startScenario(TelemetryEvent_1.default.CloseChatSession, cleanupMetadata);
1296
1297
  if (!!(endChatOptionalParams === null || endChatOptionalParams === void 0 ? void 0 : endChatOptionalParams.isSessionEnded)) return [3 /*break*/, 5];
1297
- _c.label = 1;
1298
+ _g.label = 1;
1298
1299
  case 1:
1299
- _c.trys.push([1, 3, , 4]);
1300
+ _g.trys.push([1, 3, , 4]);
1300
1301
  sessionCloseOptionalParams = {};
1302
+ sessionCloseRequestId = this.requestId;
1301
1303
  if (this.isPersistentChat && !((_a = this.chatSDKConfig.persistentChat) === null || _a === void 0 ? void 0 : _a.disable)) {
1302
1304
  isReconnectChat = this.reconnectId !== null ? true : false;
1303
1305
  sessionCloseOptionalParams.isPersistentChat = this.isPersistentChat;
1304
1306
  sessionCloseOptionalParams.isReconnectChat = isReconnectChat;
1307
+ if ((0, parsers_1.parseLowerCaseString)((_c = (_b = this.liveChatConfig) === null || _b === void 0 ? void 0 : _b.LiveWSAndLiveChatEngJoin) === null || _c === void 0 ? void 0 : _c.msdyn_enablecustomerclosepersistentchat) === "true" &&
1308
+ isReconnectChat &&
1309
+ typeof this.reconnectId === "string" &&
1310
+ this.reconnectId.length > 0 &&
1311
+ (0, parsers_1.parseLowerCaseString)((_e = (_d = this.liveChatConfig) === null || _d === void 0 ? void 0 : _d.LcwFcbConfiguration) === null || _e === void 0 ? void 0 : _e.lcwPersistentChatCustomerEndEnabled) === "true") {
1312
+ sessionCloseRequestId = this.reconnectId;
1313
+ }
1305
1314
  }
1306
- if (this.isChatReconnect && !((_b = this.chatSDKConfig.chatReconnect) === null || _b === void 0 ? void 0 : _b.disable) && !this.isPersistentChat) {
1315
+ if (this.isChatReconnect && !((_f = this.chatSDKConfig.chatReconnect) === null || _f === void 0 ? void 0 : _f.disable) && !this.isPersistentChat) {
1307
1316
  isChatReconnect = this.reconnectId !== null ? true : false;
1308
1317
  this.requestId = isChatReconnect ? this.reconnectId : this.requestId; // Chat Reconnect session to close
1318
+ sessionCloseRequestId = this.requestId;
1309
1319
  sessionCloseOptionalParams.isReconnectChat = isChatReconnect;
1310
1320
  }
1311
1321
  if (this.authenticatedUserToken) {
1312
1322
  sessionCloseOptionalParams.authenticatedUserToken = this.authenticatedUserToken;
1313
1323
  }
1314
- return [4 /*yield*/, this.OCClient.sessionClose(this.requestId, sessionCloseOptionalParams)];
1324
+ return [4 /*yield*/, this.OCClient.sessionClose(sessionCloseRequestId, sessionCloseOptionalParams)];
1315
1325
  case 2:
1316
- _c.sent();
1326
+ _g.sent();
1317
1327
  return [3 /*break*/, 4];
1318
1328
  case 3:
1319
- error_14 = _c.sent();
1329
+ error_14 = _g.sent();
1320
1330
  exceptionThrowers_1.default.throwConversationClosureFailure(error_14, this.scenarioMarker, TelemetryEvent_1.default.CloseChatSession, __assign(__assign({}, cleanupMetadata), { isSessionEnded: String(!(endChatOptionalParams === null || endChatOptionalParams === void 0 ? void 0 : endChatOptionalParams.isSessionEnded)) }));
1321
1331
  return [3 /*break*/, 4];
1322
1332
  case 4:
1323
1333
  this.scenarioMarker.completeScenario(TelemetryEvent_1.default.CloseChatSession, cleanupMetadata);
1324
- _c.label = 5;
1334
+ _g.label = 5;
1325
1335
  case 5: return [2 /*return*/];
1326
1336
  }
1327
1337
  });
@@ -3395,53 +3405,95 @@ var OmnichannelChatSDK = /** @class */ (function () {
3395
3405
  };
3396
3406
  OmnichannelChatSDK.prototype.getChatConfig = function () {
3397
3407
  return __awaiter(this, arguments, void 0, function (optionalParams) {
3398
- var sendCacheHeaders, bypassCache, liveChatConfig, startTime, error_30, clientElapsedMs, _a;
3399
- var _b, _c;
3408
+ var sendCacheHeaders, _a, prefetchedLiveChatConfig, prefetchedConfigAttestation, bypassCache, prefetchAttempted, prefetchResult, prefetchError_1, liveChatConfig, startTime, error_30, clientElapsedMs, _b;
3409
+ var _c, _d;
3400
3410
  if (optionalParams === void 0) { optionalParams = {}; }
3401
- return __generator(this, function (_d) {
3402
- switch (_d.label) {
3411
+ return __generator(this, function (_e) {
3412
+ switch (_e.label) {
3403
3413
  case 0:
3404
3414
  sendCacheHeaders = optionalParams.sendCacheHeaders;
3415
+ _a = optionalParams, prefetchedLiveChatConfig = _a.prefetchedLiveChatConfig, prefetchedConfigAttestation = _a.prefetchedConfigAttestation;
3405
3416
  bypassCache = sendCacheHeaders === true;
3406
- startTime = typeof performance !== 'undefined' ? performance.now() : undefined;
3407
- _d.label = 1;
3417
+ prefetchAttempted = prefetchedLiveChatConfig !== undefined && prefetchedLiveChatConfig !== null;
3418
+ if (!prefetchAttempted) return [3 /*break*/, 5];
3419
+ _e.label = 1;
3408
3420
  case 1:
3409
- _d.trys.push([1, 3, , 8]);
3410
- return [4 /*yield*/, this.OCClient.getChatConfig(this.requestId, bypassCache)];
3421
+ _e.trys.push([1, 4, , 5]);
3422
+ prefetchResult = (0, prefetchedConfigValidator_1.default)(prefetchedLiveChatConfig, prefetchedConfigAttestation, { orgId: this.omnichannelConfig.orgId, widgetId: this.omnichannelConfig.widgetId }, bypassCache, this.omnichannelConfig.orgUrl);
3423
+ if (!prefetchResult.accepted) return [3 /*break*/, 3];
3424
+ // Ordered so nothing is latched from a payload we may still
3425
+ // reject: building the configuration is the step that can
3426
+ // throw, and evaluating attachment support flips a flag that
3427
+ // is never turned back off.
3428
+ return [4 /*yield*/, this.buildConfigurations(prefetchedLiveChatConfig)];
3411
3429
  case 2:
3412
- liveChatConfig = _d.sent();
3430
+ // Ordered so nothing is latched from a payload we may still
3431
+ // reject: building the configuration is the step that can
3432
+ // throw, and evaluating attachment support flips a flag that
3433
+ // is never turned back off.
3434
+ _e.sent();
3435
+ this.liveChatConfig = prefetchedLiveChatConfig;
3436
+ this.evaluateAMSAvailability();
3437
+ this.scenarioMarker.singleRecord(TelemetryEvent_1.default.PrefetchedLiveChatConfigUsed, {
3438
+ RequestId: this.requestId || ""
3439
+ });
3440
+ return [2 /*return*/, this.liveChatConfig];
3441
+ case 3:
3442
+ this.scenarioMarker.singleRecord(TelemetryEvent_1.default.PrefetchedLiveChatConfigRejected, {
3443
+ RequestId: this.requestId || "",
3444
+ ExceptionDetails: JSON.stringify({ reason: prefetchResult.reason })
3445
+ });
3446
+ return [3 /*break*/, 5];
3447
+ case 4:
3448
+ prefetchError_1 = _e.sent();
3449
+ // Adoption itself failed (e.g. buildConfigurations rejected the
3450
+ // payload). Fall through rather than surface it: the network fetch
3451
+ // below is the correct, working behavior.
3452
+ this.scenarioMarker.singleRecord(TelemetryEvent_1.default.PrefetchedLiveChatConfigRejected, {
3453
+ RequestId: this.requestId || "",
3454
+ ExceptionDetails: JSON.stringify({ reason: "Exception", error: "".concat(prefetchError_1) })
3455
+ });
3456
+ return [3 /*break*/, 5];
3457
+ case 5:
3458
+ startTime = typeof performance !== 'undefined' ? performance.now() : undefined;
3459
+ _e.label = 6;
3460
+ case 6:
3461
+ _e.trys.push([6, 8, , 13]);
3462
+ return [4 /*yield*/, this.OCClient.getChatConfig(this.requestId, bypassCache)];
3463
+ case 7:
3464
+ liveChatConfig = _e.sent();
3413
3465
  this.liveChatConfig = liveChatConfig;
3414
3466
  this.evaluateAMSAvailability();
3415
3467
  this.buildConfigurations(liveChatConfig);
3416
3468
  /* istanbul ignore next */
3417
3469
  this.debug && console.log("[OmnichannelChatSDK][getChatConfig][liveChatVersion] ".concat(this.liveChatVersion));
3418
3470
  return [2 /*return*/, this.liveChatConfig];
3419
- case 3:
3420
- error_30 = _d.sent();
3471
+ case 8:
3472
+ error_30 = _e.sent();
3421
3473
  clientElapsedMs = startTime !== undefined
3422
3474
  ? Math.round(performance.now() - startTime)
3423
3475
  : undefined;
3424
3476
  // Attach timing info to error object for outer catch blocks to use
3425
3477
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
3426
3478
  error_30.__chatConfigElapsedMs = clientElapsedMs;
3427
- if (!(0, internalUtils_1.isCoreServicesOrgUrlDNSError)(error_30, this.coreServicesOrgUrl, this.dynamicsLocationCode)) return [3 /*break*/, 6];
3479
+ if (!(0, internalUtils_1.isCoreServicesOrgUrlDNSError)(error_30, this.coreServicesOrgUrl, this.dynamicsLocationCode)) return [3 /*break*/, 11];
3428
3480
  this.omnichannelConfig.orgUrl = this.unqServicesOrgUrl;
3429
- _a = this;
3481
+ _b = this;
3430
3482
  return [4 /*yield*/, ocsdk_1.SDKProvider.getSDK(this.omnichannelConfig, (0, createOcSDKConfiguration_1.default)(false), this.ocSdkLogger)];
3431
- case 4:
3432
- _a.OCClient = _d.sent();
3483
+ case 9:
3484
+ _b.OCClient = _e.sent();
3433
3485
  return [4 /*yield*/, this.OCClient.getChatConfig(this.requestId, bypassCache)];
3434
- case 5:
3435
- liveChatConfig = _d.sent(); // Bubble up error by default to throw ChatConfigRetrievalFailure
3436
- return [3 /*break*/, 7];
3437
- case 6:
3486
+ case 10:
3487
+ liveChatConfig = _e.sent(); // Bubble up error by default to throw ChatConfigRetrievalFailure
3488
+ return [3 /*break*/, 12];
3489
+ case 11:
3438
3490
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
3439
- if (((_c = (_b = error_30.response) === null || _b === void 0 ? void 0 : _b.headers) === null || _c === void 0 ? void 0 : _c.errorcode) && parseInt(error_30.response.headers.errorcode) === OmnichannelErrorCodes_1.default.WidgetNotFound) {
3491
+ if (((_d = (_c = error_30.response) === null || _c === void 0 ? void 0 : _c.headers) === null || _d === void 0 ? void 0 : _d.errorcode) && parseInt(error_30.response.headers.errorcode) === OmnichannelErrorCodes_1.default.WidgetNotFound) {
3440
3492
  console.warn("No widget with the given app id is present in the system.");
3441
3493
  }
3442
3494
  throw error_30; // Bubble up error by default to throw ChatConfigRetrievalFailure
3443
- case 7: return [3 /*break*/, 8];
3444
- case 8: return [2 /*return*/, this.liveChatConfig];
3495
+ case 12: return [3 /*break*/, 13];
3496
+ case 13: return [2 /*return*/, this.liveChatConfig];
3445
3497
  }
3446
3498
  });
3447
3499
  });
@@ -3451,18 +3503,23 @@ var OmnichannelChatSDK = /** @class */ (function () {
3451
3503
  return __awaiter(this, void 0, void 0, function () {
3452
3504
  var dataMaskingConfig, authSettings, liveWSAndLiveChatEngJoin, liveChatVersion, chatWidgetLanguage;
3453
3505
  return __generator(this, function (_a) {
3454
- dataMaskingConfig = liveChatConfig.DataMaskingInfo, authSettings = liveChatConfig.LiveChatConfigAuthSettings, liveWSAndLiveChatEngJoin = liveChatConfig.LiveWSAndLiveChatEngJoin, liveChatVersion = liveChatConfig.LiveChatVersion, chatWidgetLanguage = liveChatConfig.ChatWidgetLanguage;
3455
- Promise.all([
3456
- this.setDataMaskingConfiguration(dataMaskingConfig),
3457
- this.setPrechatConfigurations(liveWSAndLiveChatEngJoin),
3458
- this.setAuthSettingConfig(authSettings),
3459
- this.setPersistentChatConfiguration(liveWSAndLiveChatEngJoin),
3460
- this.setCallingOptionConfiguration(liveWSAndLiveChatEngJoin),
3461
- this.setLocaleIdConfiguration(chatWidgetLanguage),
3462
- this.setLiveChatVersionConfiguration(liveChatVersion),
3463
- this.setWidgetSnippetBaseUrl(liveWSAndLiveChatEngJoin)
3464
- ]);
3465
- return [2 /*return*/];
3506
+ switch (_a.label) {
3507
+ case 0:
3508
+ dataMaskingConfig = liveChatConfig.DataMaskingInfo, authSettings = liveChatConfig.LiveChatConfigAuthSettings, liveWSAndLiveChatEngJoin = liveChatConfig.LiveWSAndLiveChatEngJoin, liveChatVersion = liveChatConfig.LiveChatVersion, chatWidgetLanguage = liveChatConfig.ChatWidgetLanguage;
3509
+ return [4 /*yield*/, Promise.all([
3510
+ this.setDataMaskingConfiguration(dataMaskingConfig),
3511
+ this.setPrechatConfigurations(liveWSAndLiveChatEngJoin),
3512
+ this.setAuthSettingConfig(authSettings),
3513
+ this.setPersistentChatConfiguration(liveWSAndLiveChatEngJoin),
3514
+ this.setCallingOptionConfiguration(liveWSAndLiveChatEngJoin),
3515
+ this.setLocaleIdConfiguration(chatWidgetLanguage),
3516
+ this.setLiveChatVersionConfiguration(liveChatVersion),
3517
+ this.setWidgetSnippetBaseUrl(liveWSAndLiveChatEngJoin)
3518
+ ])];
3519
+ case 1:
3520
+ _a.sent();
3521
+ return [2 /*return*/];
3522
+ }
3466
3523
  });
3467
3524
  });
3468
3525
  };