UNPKG

@microsoft/omnichannel-chat-sdk

Version:
805 lines 56.1 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __values = (this && this.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ACSConversation = void 0; var communication_common_1 = require("@azure/communication-common"); var communication_chat_1 = require("@azure/communication-chat"); var MessagePrinterFactory_1 = require("../../utils/printers/MessagePrinterFactory"); var ACSChatMessageType_1 = require("./ACSChatMessageType"); var ACSParticipantDisplayName_1 = require("./ACSParticipantDisplayName"); var DeliveryMode_1 = require("@microsoft/omnichannel-ic3core/lib/model/DeliveryMode"); var LiveChatVersion_1 = require("../LiveChatVersion"); var MessageSource_1 = require("../../telemetry/MessageSource"); var TelemetryEvent_1 = require("../../telemetry/TelemetryEvent"); var createOmnichannelMessage_1 = require("../../utils/createOmnichannelMessage"); var createOmnichannelStreamingMessage_1 = require("../../utils/createOmnichannelStreamingMessage"); var MessageTags_1 = require("./MessageTags"); var ACSClientEvent; (function (ACSClientEvent) { ACSClientEvent["InitializeACSClient"] = "InitializeACSClient"; ACSClientEvent["InitializeACSConversation"] = "InitializeACSConversation"; ACSClientEvent["GetParticipants"] = "GetParticipants"; ACSClientEvent["RegisterOnNewMessage"] = "RegisterOnNewMessage"; ACSClientEvent["RegisterOnStreamingMessage"] = "RegisterOnStreamingMessage"; ACSClientEvent["RegisterOnThreadUpdate"] = "RegisterOnThreadUpdate"; ACSClientEvent["OnTypingEvent"] = "OnTypingEvent"; ACSClientEvent["GetMessages"] = "GetMessages"; ACSClientEvent["SendMessage"] = "SendMessage"; ACSClientEvent["SendTyping"] = "SendTyping"; ACSClientEvent["SendReadReceipt"] = "SendReadReceipt"; ACSClientEvent["StartPolling"] = "StartPolling"; ACSClientEvent["StopPolling"] = "StopPolling"; ACSClientEvent["MessageProcessingError"] = "MessageProcessingError"; ACSClientEvent["Disconnect"] = "Disconnect"; })(ACSClientEvent || (ACSClientEvent = {})); function nextDelay() { return __generator(this, function (_a) { switch (_a.label) { case 0: return [5 /*yield**/, __values([1000, 1000, 2000, 3000, 5000, 8000, 10000])]; case 1: _a.sent(); return [2 /*return*/]; } }); } var ACSConversation = /** @class */ (function () { function ACSConversation(tokenCredential, chatClient, logger) { if (logger === void 0) { logger = null; } this.logger = null; this.keepPolling = false; this.pollingTimer = null; this.streamSequenceCounters = new Map(); this.finalizedMessageIds = new Set(); this.streamingMessageCallback = null; this.logger = logger; this.tokenCredential = tokenCredential; this.chatClient = chatClient; this.eventListeners = {}; } ACSConversation.prototype.startPolling = function () { return __awaiter(this, void 0, void 0, function () { var _a, _b; return __generator(this, function (_c) { (_a = this.logger) === null || _a === void 0 ? void 0 : _a.startScenario(ACSClientEvent.StartPolling); this.keepPolling = true; (_b = this.logger) === null || _b === void 0 ? void 0 : _b.completeScenario(ACSClientEvent.StartPolling); return [2 /*return*/]; }); }); }; ACSConversation.prototype.stopPolling = function () { return __awaiter(this, void 0, void 0, function () { var _a, _b; return __generator(this, function (_c) { (_a = this.logger) === null || _a === void 0 ? void 0 : _a.startScenario(ACSClientEvent.StopPolling); this.keepPolling = false; (_b = this.logger) === null || _b === void 0 ? void 0 : _b.completeScenario(ACSClientEvent.StopPolling); return [2 /*return*/]; }); }); }; ACSConversation.prototype.initialize = function (sessionInfo) { return __awaiter(this, void 0, void 0, function () { var _a, error_1, exceptionDetails, error_2, exceptionDetails; var _b, _c, _d, _e, _f; return __generator(this, function (_g) { switch (_g.label) { case 0: (_b = this.logger) === null || _b === void 0 ? void 0 : _b.startScenario(ACSClientEvent.InitializeACSConversation); this.sessionInfo = sessionInfo; _g.label = 1; case 1: _g.trys.push([1, 3, , 4]); _a = this; return [4 /*yield*/, ((_c = this.chatClient) === null || _c === void 0 ? void 0 : _c.getChatThreadClient(sessionInfo.threadId))]; case 2: _a.chatThreadClient = _g.sent(); return [3 /*break*/, 4]; case 3: error_1 = _g.sent(); exceptionDetails = { response: 'ChatClientGetChatThreadClientFailure', errorObject: "".concat(error_1) }; (_d = this.logger) === null || _d === void 0 ? void 0 : _d.failScenario(ACSClientEvent.InitializeACSConversation, { ExceptionDetails: JSON.stringify(exceptionDetails) }); throw new Error(JSON.stringify(exceptionDetails)); case 4: _g.trys.push([4, 6, , 7]); return [4 /*yield*/, this.chatClient.startRealtimeNotifications()]; case 5: _g.sent(); return [3 /*break*/, 7]; case 6: error_2 = _g.sent(); exceptionDetails = { response: 'StartRealtimeNotificationsFailed', errorObject: "".concat(error_2) }; (_e = this.logger) === null || _e === void 0 ? void 0 : _e.failScenario(ACSClientEvent.InitializeACSConversation, { ExceptionDetails: JSON.stringify(exceptionDetails) }); throw new Error(JSON.stringify(exceptionDetails)); case 7: (_f = this.logger) === null || _f === void 0 ? void 0 : _f.completeScenario(ACSClientEvent.InitializeACSConversation); return [2 /*return*/]; } }); }); }; ACSConversation.prototype.getMessages = function () { return __awaiter(this, arguments, void 0, function (optionsParams) { var messages, pagedAsyncIterableIterator, nextMessage, chatMessage, error_3, exceptionDetails; var _a, _b, _c; if (optionsParams === void 0) { optionsParams = {}; } return __generator(this, function (_d) { switch (_d.label) { case 0: (_a = this.logger) === null || _a === void 0 ? void 0 : _a.startScenario(ACSClientEvent.GetMessages); messages = []; _d.label = 1; case 1: _d.trys.push([1, 9, , 10]); return [4 /*yield*/, this.chatThreadClient.listMessages()]; case 2: pagedAsyncIterableIterator = _d.sent(); return [4 /*yield*/, pagedAsyncIterableIterator.next()]; case 3: nextMessage = _d.sent(); _d.label = 4; case 4: if (!!nextMessage.done) return [3 /*break*/, 8]; chatMessage = nextMessage.value; if (!(chatMessage.type !== ACSChatMessageType_1.default.Text)) return [3 /*break*/, 6]; return [4 /*yield*/, pagedAsyncIterableIterator.next()]; case 5: nextMessage = _d.sent(); return [3 /*break*/, 4]; case 6: if ((optionsParams === null || optionsParams === void 0 ? void 0 : optionsParams.skipConversion) === true) { messages.push(chatMessage); } else { messages.push((0, createOmnichannelMessage_1.default)(chatMessage, { liveChatVersion: LiveChatVersion_1.default.V2 })); } return [4 /*yield*/, pagedAsyncIterableIterator.next()]; case 7: nextMessage = _d.sent(); return [3 /*break*/, 4]; case 8: (_b = this.logger) === null || _b === void 0 ? void 0 : _b.completeScenario(ACSClientEvent.GetMessages); return [3 /*break*/, 10]; case 9: error_3 = _d.sent(); exceptionDetails = { errorObject: "".concat(error_3) }; (_c = this.logger) === null || _c === void 0 ? void 0 : _c.failScenario(ACSClientEvent.GetMessages, { ExceptionDetails: JSON.stringify(exceptionDetails) }); throw new Error(ACSClientEvent.GetMessages); case 10: return [2 /*return*/, ((optionsParams === null || optionsParams === void 0 ? void 0 : optionsParams.skipConversion) === true) ? messages : messages]; } }); }); }; ACSConversation.prototype.getParticipants = function () { return __awaiter(this, void 0, void 0, function () { var participants, pagedAsyncIterableIterator, next, user, error_4, exceptionDetails; var _a, _b, _c; return __generator(this, function (_d) { switch (_d.label) { case 0: (_a = this.logger) === null || _a === void 0 ? void 0 : _a.startScenario(ACSClientEvent.GetParticipants); participants = []; _d.label = 1; case 1: _d.trys.push([1, 7, , 8]); return [4 /*yield*/, this.chatThreadClient.listParticipants()]; case 2: pagedAsyncIterableIterator = _d.sent(); return [4 /*yield*/, pagedAsyncIterableIterator.next()]; case 3: next = _d.sent(); _d.label = 4; case 4: if (!!next.done) return [3 /*break*/, 6]; user = next.value; participants.push(user); return [4 /*yield*/, pagedAsyncIterableIterator.next()]; case 5: next = _d.sent(); return [3 /*break*/, 4]; case 6: (_b = this.logger) === null || _b === void 0 ? void 0 : _b.completeScenario(ACSClientEvent.GetParticipants); return [3 /*break*/, 8]; case 7: error_4 = _d.sent(); exceptionDetails = { errorObject: "".concat(error_4) }; (_c = this.logger) === null || _c === void 0 ? void 0 : _c.failScenario(ACSClientEvent.GetParticipants, { ExceptionDetails: JSON.stringify(exceptionDetails) }); throw new Error(ACSClientEvent.GetParticipants); case 8: return [2 /*return*/, participants]; } }); }); }; ACSConversation.prototype.registerOnNewMessage = function (onNewMessageCallback_1) { return __awaiter(this, arguments, void 0, function (onNewMessageCallback, optionalParams) { var postedMessageIds, pollForMessages_1, delayGenerator, listener, error_5, exceptionDetails; var _this = this; var _a, _b, _c, _d, _e; if (optionalParams === void 0) { optionalParams = { disablePolling: false }; } return __generator(this, function (_f) { switch (_f.label) { case 0: (_a = this.logger) === null || _a === void 0 ? void 0 : _a.startScenario(ACSClientEvent.RegisterOnNewMessage); postedMessageIds = new Set(); _f.label = 1; case 1: _f.trys.push([1, 5, , 6]); pollForMessages_1 = function (delayGenerator) { return __awaiter(_this, void 0, void 0, function () { var messages, _i, _a, message, _b, id, senderDisplayName, customerMessageCondition, errorName, errorMessage, _c, defaultInterval, delay; var _d, _e, _f; return __generator(this, function (_g) { switch (_g.label) { case 0: if (!this.keepPolling) return [3 /*break*/, 4]; _g.label = 1; case 1: _g.trys.push([1, 3, , 4]); return [4 /*yield*/, this.getMessages({ skipConversion: true })]; case 2: messages = _g.sent(); for (_i = 0, _a = messages.reverse(); _i < _a.length; _i++) { message = _a[_i]; try { _b = message, id = _b.id, senderDisplayName = _b.senderDisplayName; customerMessageCondition = senderDisplayName === ACSParticipantDisplayName_1.default.Customer; // Filter out customer messages if (customerMessageCondition) { continue; } // Filter out duplicate messages if (!postedMessageIds.has(id)) { (_d = this.logger) === null || _d === void 0 ? void 0 : _d.recordIndividualEvent(TelemetryEvent_1.default.MessageReceived, MessageSource_1.MessageSource.Polling, MessagePrinterFactory_1.MessagePrinterFactory.printifyMessage(message, MessagePrinterFactory_1.PrinterType.Polling)); onNewMessageCallback(message); postedMessageIds.add(id); } } catch (error) { errorName = (_e = error === null || error === void 0 ? void 0 : error.name) !== null && _e !== void 0 ? _e : 'Error'; errorMessage = "[ACSClient][registerOnNewMessage] Error occurred while processing messages: ".concat(errorName); (_f = this.logger) === null || _f === void 0 ? void 0 : _f.failScenario(ACSClientEvent.MessageProcessingError, { ExceptionDetails: errorMessage }); // Always emit a console warning so consumers without // access to telemetry still know a message failed to // process. The message is static apart from the safe // error type, so no error content can leak. console.warn(errorMessage); } } return [3 /*break*/, 4]; case 3: _c = _g.sent(); return [3 /*break*/, 4]; case 4: defaultInterval = optionalParams.pollingInterval || 10000; delay = delayGenerator.next(); this.pollingTimer = setTimeout(function () { pollForMessages_1(delayGenerator); }, delay.done === true ? defaultInterval : delay.value); return [2 /*return*/]; } }); }); }; return [4 /*yield*/, this.startPolling()]; case 2: _f.sent(); if (!(optionalParams.disablePolling === false)) return [3 /*break*/, 4]; delayGenerator = nextDelay(); return [4 /*yield*/, pollForMessages_1(delayGenerator)]; case 3: _f.sent(); _f.label = 4; case 4: listener = function (event) { var _a, _b, _c, _d, _e, _f; var id = event.id, sender = event.sender; var customerMessageCondition = (sender.communicationUserId === ((_a = _this.sessionInfo) === null || _a === void 0 ? void 0 : _a.id)); var isChatMessageEditedEvent = Object.keys(event).includes("editedOn"); // Filter out customer messages if (customerMessageCondition) { return; } // Route streaming finals that arrive on chatMessageReceived to the streaming callback. // ACS may deliver the final streaming message as event 200 (chatMessageReceived) instead // of event 251 (streamingChatMessageChunkReceived). Detect this by checking streamingMetadata. var streamingType = (_b = event.streamingMetadata) === null || _b === void 0 ? void 0 : _b.streamingMessageType; if (streamingType === 'final' && _this.streamingMessageCallback) { try { var streamingMessage = (0, createOmnichannelStreamingMessage_1.default)(event, { liveChatVersion: LiveChatVersion_1.default.V2, eventName: 'streamingChatMessageChunkReceived', sequenceCounters: _this.streamSequenceCounters, finalizedMessageIds: _this.finalizedMessageIds, logger: _this.logger, }); if (streamingMessage) { _this.streamingMessageCallback(streamingMessage); (_c = _this.logger) === null || _c === void 0 ? void 0 : _c.recordIndividualEvent(TelemetryEvent_1.default.StreamingMessageReceived, MessageSource_1.MessageSource.WebSocketStreaming, MessagePrinterFactory_1.MessagePrinterFactory.printifyMessage(event, MessagePrinterFactory_1.PrinterType.Streaming)); } } catch (err) { (_d = _this.logger) === null || _d === void 0 ? void 0 : _d.recordIndividualEvent(TelemetryEvent_1.default.StreamingHandlerThrew, MessageSource_1.MessageSource.WebSocketStreaming, // eslint-disable-next-line @typescript-eslint/no-explicit-any { messageId: event.id, error: "".concat(err), source: 'chatMessageReceivedFinalRouting' }); } } else if (streamingType && streamingType !== 'final') { // Unexpected: chatMessageReceived should only carry 'final' streaming metadata. // Log for observability but still deliver to onNewMessage below. (_e = _this.logger) === null || _e === void 0 ? void 0 : _e.recordIndividualEvent(TelemetryEvent_1.default.StreamingUnexpectedTypeOnNewMessage, MessageSource_1.MessageSource.WebSocketStreaming, // eslint-disable-next-line @typescript-eslint/no-explicit-any { messageId: event.id, streamingType: streamingType }); } // Filter out duplicate messages if (postedMessageIds.has(id) && !isChatMessageEditedEvent) { return; } // Always deliver to onNewMessage for backward compatibility onNewMessageCallback(event); postedMessageIds.add(id); (_f = _this.logger) === null || _f === void 0 ? void 0 : _f.recordIndividualEvent(TelemetryEvent_1.default.MessageReceived, MessageSource_1.MessageSource.WebSocket, MessagePrinterFactory_1.MessagePrinterFactory.printifyMessage(event, MessagePrinterFactory_1.PrinterType.WebSocket)); }; (_b = this.chatClient) === null || _b === void 0 ? void 0 : _b.on("chatMessageReceived", listener); (_c = this.chatClient) === null || _c === void 0 ? void 0 : _c.on("chatMessageEdited", listener); this.trackListener("chatMessageReceived", listener); this.trackListener("chatMessageEdited", listener); (_d = this.logger) === null || _d === void 0 ? void 0 : _d.completeScenario(ACSClientEvent.RegisterOnNewMessage); return [3 /*break*/, 6]; case 5: error_5 = _f.sent(); exceptionDetails = { errorObject: "".concat(error_5) }; (_e = this.logger) === null || _e === void 0 ? void 0 : _e.failScenario(ACSClientEvent.RegisterOnNewMessage, { ExceptionDetails: JSON.stringify(exceptionDetails) }); throw new Error(ACSClientEvent.RegisterOnNewMessage); case 6: return [2 /*return*/]; } }); }); }; ACSConversation.prototype.registerOnStreamingMessage = function (onStreamingMessageCallback_1) { return __awaiter(this, arguments, void 0, function (onStreamingMessageCallback, // eslint-disable-next-line @typescript-eslint/no-unused-vars optionalParams) { var existingStartListeners, existingChunkListeners, _i, existingStartListeners_1, listener, _a, existingChunkListeners_1, listener, invokeWithIsolation_1, onStart, onChunk, exceptionDetails; var _this = this; var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l; if (optionalParams === void 0) { optionalParams = {}; } return __generator(this, function (_m) { (_b = this.logger) === null || _b === void 0 ? void 0 : _b.startScenario(ACSClientEvent.RegisterOnStreamingMessage); // Guard against duplicate registration — remove previous listeners before adding new ones. // This prevents listener leaks if the consumer calls onStreamingMessage() multiple times. if (this.streamingMessageCallback) { (_c = this.logger) === null || _c === void 0 ? void 0 : _c.recordIndividualEvent(TelemetryEvent_1.default.StreamingRegistrationReplaced, MessageSource_1.MessageSource.WebSocketStreaming, // eslint-disable-next-line @typescript-eslint/no-explicit-any { reason: 'registerOnStreamingMessage called while already registered' }); existingStartListeners = (_d = this.eventListeners['streamingChatMessageStarted']) !== null && _d !== void 0 ? _d : []; existingChunkListeners = (_e = this.eventListeners['streamingChatMessageChunkReceived']) !== null && _e !== void 0 ? _e : []; for (_i = 0, existingStartListeners_1 = existingStartListeners; _i < existingStartListeners_1.length; _i++) { listener = existingStartListeners_1[_i]; (_f = this.chatClient) === null || _f === void 0 ? void 0 : _f.off('streamingChatMessageStarted', listener); // eslint-disable-line @typescript-eslint/no-explicit-any } for (_a = 0, existingChunkListeners_1 = existingChunkListeners; _a < existingChunkListeners_1.length; _a++) { listener = existingChunkListeners_1[_a]; (_g = this.chatClient) === null || _g === void 0 ? void 0 : _g.off('streamingChatMessageChunkReceived', listener); // eslint-disable-line @typescript-eslint/no-explicit-any } this.eventListeners['streamingChatMessageStarted'] = []; this.eventListeners['streamingChatMessageChunkReceived'] = []; } // Store reference so chatMessageReceived listener can route streaming finals this.streamingMessageCallback = onStreamingMessageCallback; try { invokeWithIsolation_1 = function (event, message) { var result = onStreamingMessageCallback(message); if (result && typeof result.catch === 'function') { result.catch(function (rejected) { var _a; (_a = _this.logger) === null || _a === void 0 ? void 0 : _a.recordIndividualEvent(TelemetryEvent_1.default.StreamingHandlerAsyncRejected, MessageSource_1.MessageSource.WebSocketStreaming, // eslint-disable-next-line @typescript-eslint/no-explicit-any { messageId: event.id, error: "".concat(rejected) }); }); } }; onStart = function (event) { var _a, _b; try { var message = (0, createOmnichannelStreamingMessage_1.default)(event, { liveChatVersion: LiveChatVersion_1.default.V2, eventName: 'streamingChatMessageStarted', sequenceCounters: _this.streamSequenceCounters, finalizedMessageIds: _this.finalizedMessageIds, logger: _this.logger, }); if (message === undefined) { return; } (_a = _this.logger) === null || _a === void 0 ? void 0 : _a.recordIndividualEvent(TelemetryEvent_1.default.StreamingMessageReceived, MessageSource_1.MessageSource.WebSocketStreaming, MessagePrinterFactory_1.MessagePrinterFactory.printifyMessage(event, MessagePrinterFactory_1.PrinterType.Streaming)); invokeWithIsolation_1(event, message); } catch (err) { (_b = _this.logger) === null || _b === void 0 ? void 0 : _b.recordIndividualEvent(TelemetryEvent_1.default.StreamingHandlerThrew, MessageSource_1.MessageSource.WebSocketStreaming, // eslint-disable-next-line @typescript-eslint/no-explicit-any { messageId: event.id, error: "".concat(err) }); } }; onChunk = function (event) { var _a, _b, _c, _d; try { var message = (0, createOmnichannelStreamingMessage_1.default)(event, { liveChatVersion: LiveChatVersion_1.default.V2, eventName: 'streamingChatMessageChunkReceived', sequenceCounters: _this.streamSequenceCounters, finalizedMessageIds: _this.finalizedMessageIds, logger: _this.logger, }); if (message === undefined) { return; } (_a = _this.logger) === null || _a === void 0 ? void 0 : _a.recordIndividualEvent(TelemetryEvent_1.default.StreamingMessageReceived, MessageSource_1.MessageSource.WebSocketStreaming, MessagePrinterFactory_1.MessagePrinterFactory.printifyMessage(event, MessagePrinterFactory_1.PrinterType.Streaming)); invokeWithIsolation_1(event, message); // Backwards-compat fire-through: when a streaming message reaches // "final", also deliver it to chatMessageReceived listeners so // consumers using only onNewMessage still see the complete message. if (message.streamingMetadata.streamingMessageType === 'final') { var newMessageListeners = (_b = _this.eventListeners['chatMessageReceived']) !== null && _b !== void 0 ? _b : []; for (var _i = 0, newMessageListeners_1 = newMessageListeners; _i < newMessageListeners_1.length; _i++) { var listener = newMessageListeners_1[_i]; try { listener(event); } catch (err) { (_c = _this.logger) === null || _c === void 0 ? void 0 : _c.recordIndividualEvent(TelemetryEvent_1.default.StreamingHandlerThrew, MessageSource_1.MessageSource.WebSocketStreaming, // eslint-disable-next-line @typescript-eslint/no-explicit-any { messageId: event.id, error: "".concat(err), source: 'newMessageFireThrough' }); } } } } catch (err) { (_d = _this.logger) === null || _d === void 0 ? void 0 : _d.recordIndividualEvent(TelemetryEvent_1.default.StreamingHandlerThrew, MessageSource_1.MessageSource.WebSocketStreaming, // eslint-disable-next-line @typescript-eslint/no-explicit-any { messageId: event.id, error: "".concat(err) }); } }; (_h = this.chatClient) === null || _h === void 0 ? void 0 : _h.on('streamingChatMessageStarted', onStart); (_j = this.chatClient) === null || _j === void 0 ? void 0 : _j.on('streamingChatMessageChunkReceived', onChunk); this.trackListener('streamingChatMessageStarted', onStart); this.trackListener('streamingChatMessageChunkReceived', onChunk); (_k = this.logger) === null || _k === void 0 ? void 0 : _k.completeScenario(ACSClientEvent.RegisterOnStreamingMessage); } catch (error) { exceptionDetails = { errorObject: "".concat(error) }; (_l = this.logger) === null || _l === void 0 ? void 0 : _l.failScenario(ACSClientEvent.RegisterOnStreamingMessage, { ExceptionDetails: JSON.stringify(exceptionDetails), }); throw new Error("".concat(ACSClientEvent.RegisterOnStreamingMessage, ": ").concat(error)); } return [2 /*return*/]; }); }); }; ACSConversation.prototype.registerOnThreadUpdate = function (onThreadUpdateCallback) { return __awaiter(this, void 0, void 0, function () { var listener; var _a, _b, _c, _d; return __generator(this, function (_e) { (_a = this.logger) === null || _a === void 0 ? void 0 : _a.startScenario(ACSClientEvent.RegisterOnThreadUpdate); try { listener = function (event) { onThreadUpdateCallback(event); }; (_b = this.chatClient) === null || _b === void 0 ? void 0 : _b.on("participantsRemoved", listener); this.trackListener("participantsRemoved", listener); (_c = this.logger) === null || _c === void 0 ? void 0 : _c.completeScenario(ACSClientEvent.RegisterOnThreadUpdate); } catch (error) { (_d = this.logger) === null || _d === void 0 ? void 0 : _d.failScenario(ACSClientEvent.RegisterOnThreadUpdate); } return [2 /*return*/]; }); }); }; ACSConversation.prototype.onTypingEvent = function (onTypingEventCallback) { return __awaiter(this, void 0, void 0, function () { var listener; var _a, _b, _c, _d; return __generator(this, function (_e) { (_a = this.logger) === null || _a === void 0 ? void 0 : _a.startScenario(ACSClientEvent.OnTypingEvent); try { listener = function (event) { var sender = event.sender, recipient = event.recipient; // Ignore participant's own typing events if (sender.communicationUserId === recipient.communicationUserId) { // eslint-disable-line @typescript-eslint/no-explicit-any return; } onTypingEventCallback(event); }; (_b = this.chatClient) === null || _b === void 0 ? void 0 : _b.on("typingIndicatorReceived", listener); this.trackListener("typingIndicatorReceived", listener); (_c = this.logger) === null || _c === void 0 ? void 0 : _c.completeScenario(ACSClientEvent.OnTypingEvent); } catch (error) { (_d = this.logger) === null || _d === void 0 ? void 0 : _d.failScenario(ACSClientEvent.OnTypingEvent); } return [2 /*return*/]; }); }); }; ACSConversation.prototype.sendMessage = function (message) { return __awaiter(this, void 0, void 0, function () { var sendMessageRequest, sendMessageOptions, response, chatMessage, error_6, exceptionDetails; var _a, _b, _c, _d, _e; return __generator(this, function (_f) { switch (_f.label) { case 0: (_a = this.logger) === null || _a === void 0 ? void 0 : _a.startScenario(ACSClientEvent.SendMessage); if (!message.metadata) { message.metadata = {}; } sendMessageRequest = { content: message.content, }; sendMessageOptions = { senderDisplayName: ACSParticipantDisplayName_1.default.Customer, metadata: __assign({ deliveryMode: DeliveryMode_1.default.Bridged, tags: MessageTags_1.defaultMessageTags.join(',') }, message.metadata) }; _f.label = 1; case 1: _f.trys.push([1, 3, , 4]); return [4 /*yield*/, ((_b = this.chatThreadClient) === null || _b === void 0 ? void 0 : _b.sendMessage(sendMessageRequest, sendMessageOptions))]; case 2: response = _f.sent(); (_c = this.logger) === null || _c === void 0 ? void 0 : _c.completeScenario(ACSClientEvent.SendMessage); if (response === null || response === void 0 ? void 0 : response.id) { chatMessage = { id: response === null || response === void 0 ? void 0 : response.id, content: message.content, sender: { communicationUserId: (_d = this.sessionInfo) === null || _d === void 0 ? void 0 : _d.id }, displayName: sendMessageOptions.senderDisplayName, metadata: { tags: MessageTags_1.defaultMessageTags.join(',') }, createdOn: new Date(parseInt(response === null || response === void 0 ? void 0 : response.id)) || (response === null || response === void 0 ? void 0 : response.id) }; return [2 /*return*/, (0, createOmnichannelMessage_1.default)(chatMessage, { liveChatVersion: LiveChatVersion_1.default.V2 })]; } return [3 /*break*/, 4]; case 3: error_6 = _f.sent(); exceptionDetails = { response: 'SendMessageFailed', errorObject: "".concat(error_6) }; (_e = this.logger) === null || _e === void 0 ? void 0 : _e.failScenario(ACSClientEvent.SendMessage, { ExceptionDetails: JSON.stringify(exceptionDetails) }); throw error_6; case 4: return [2 /*return*/, {}]; } }); }); }; ACSConversation.prototype.sendTyping = function () { return __awaiter(this, void 0, void 0, function () { var error_7, exceptionDetails; var _a, _b, _c, _d; return __generator(this, function (_e) { switch (_e.label) { case 0: (_a = this.logger) === null || _a === void 0 ? void 0 : _a.startScenario(ACSClientEvent.SendTyping); _e.label = 1; case 1: _e.trys.push([1, 3, , 4]); return [4 /*yield*/, ((_b = this.chatThreadClient) === null || _b === void 0 ? void 0 : _b.sendTypingNotification())]; case 2: _e.sent(); (_c = this.logger) === null || _c === void 0 ? void 0 : _c.completeScenario(ACSClientEvent.SendTyping); return [3 /*break*/, 4]; case 3: error_7 = _e.sent(); exceptionDetails = { response: 'SendTypingFailed', errorObject: "".concat(error_7) }; (_d = this.logger) === null || _d === void 0 ? void 0 : _d.failScenario(ACSClientEvent.SendTyping, { ExceptionDetails: JSON.stringify(exceptionDetails) }); throw new Error('SendTypingFailed'); case 4: return [2 /*return*/]; } }); }); }; ACSConversation.prototype.sendReadReceipt = function (messageId) { return __awaiter(this, void 0, void 0, function () { var error_8, exceptionDetails; var _a, _b, _c, _d; return __generator(this, function (_e) { switch (_e.label) { case 0: (_a = this.logger) === null || _a === void 0 ? void 0 : _a.startScenario(ACSClientEvent.SendReadReceipt); _e.label = 1; case 1: _e.trys.push([1, 3, , 4]); return [4 /*yield*/, ((_b = this.chatThreadClient) === null || _b === void 0 ? void 0 : _b.sendReadReceipt({ chatMessageId: messageId }))]; case 2: _e.sent(); (_c = this.logger) === null || _c === void 0 ? void 0 : _c.completeScenario(ACSClientEvent.SendReadReceipt); return [3 /*break*/, 4]; case 3: error_8 = _e.sent(); exceptionDetails = { response: 'SendReadReceiptFailed', errorObject: "".concat(error_8) }; (_d = this.logger) === null || _d === void 0 ? void 0 : _d.failScenario(ACSClientEvent.SendReadReceipt, { ExceptionDetails: JSON.stringify(exceptionDetails) }); throw new Error('SendReadReceiptFailed'); case 4: return [2 /*return*/]; } }); }); }; ACSConversation.prototype.sendFileMessage = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, undefined]; }); }); }; ACSConversation.prototype.sendFileData = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, undefined]; }); }); }; ACSConversation.prototype.uploadFile = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, undefined]; }); }); }; ACSConversation.prototype.downloadFile = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, undefined]; }); }); }; ACSConversation.prototype.disconnect = function () { return __awaiter(this, void 0, void 0, function () { var _loop_1, _i, _a, _b, event_1, listeners, _c; var _this = this; var _d, _e, _f; return __generator(this, function (_g) { switch (_g.label) { case 0: (_d = this.logger) === null || _d === void 0 ? void 0 : _d.startScenario(ACSClientEvent.Disconnect); _g.label = 1; case 1: _g.trys.push([1, 3, , 4]); _loop_1 = function (event_1, listeners) { listeners.forEach(function (listener) { _this.chatClient.off(event_1, listener); // eslint-disable-line @typescript-eslint/no-explicit-any }); }; for (_i = 0, _a = Object.entries(this.eventListeners); _i < _a.length; _i++) { _b = _a[_i], event_1 = _b[0], listeners = _b[1]; _loop_1(event_1, listeners); } return [4 /*yield*/, this.stopPolling()]; case 2: _g.sent(); if (this.pollingTimer) { clearTimeout(this.pollingTimer); } // Clear streaming state to prevent memory leaks across sessions this.streamSequenceCounters.clear(); this.finalizedMessageIds.clear(); this.streamingMessageCallback = null; (_e = this.logger) === null || _e === void 0 ? void 0 : _e.completeScenario(ACSClientEvent.Disconnect); return [3 /*break*/, 4]; case 3: _c = _g.sent(); (_f = this.logger) === null || _f === void 0 ? void 0 : _f.failScenario(ACSClientEvent.Disconnect); return [3 /*break*/, 4]; case 4: return [2 /*return*/]; } }); }); }; ACSConversation.prototype.createParticipantsMapping = function () { return __awaiter(this, void 0, void 0, function () { var participants, participantsMapping, _i, participants_1, participant, id; var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, this.getParticipants()]; case 1: participants = _b.sent(); participantsMapping = {}; for (_