@carbon/ai-chat 0.1.1-alpha5 → 0.1.1-react17

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.
Files changed (75) hide show
  1. package/dist/App.js +933 -55468
  2. package/dist/Carousel.js +1 -5705
  3. package/dist/Chat.js +1 -8339
  4. package/dist/GenesysMessengerServiceDesk.js +1 -579
  5. package/dist/HumanAgentServiceImpl.js +1 -1122
  6. package/dist/NiceDFOServiceDesk.js +2 -2097
  7. package/dist/PDFViewerContainer.js +2 -27439
  8. package/dist/SFServiceDesk.js +1 -1012
  9. package/dist/ServiceDeskImpl.js +1 -72
  10. package/dist/ZendeskServiceDesk.js +1 -649
  11. package/dist/_commonjsHelpers.js +1 -33
  12. package/dist/_node-resolve_empty.js +1 -25
  13. package/dist/agentActions.js +1 -187
  14. package/dist/aiChatEntry.js +1 -28
  15. package/dist/aiChatEntry2.js +4 -7022
  16. package/dist/anonymousUserIDStorage.js +2 -250
  17. package/dist/ar-dz.js +1 -55
  18. package/dist/ar-kw.js +1 -55
  19. package/dist/ar-ly.js +1 -55
  20. package/dist/ar-ma.js +1 -55
  21. package/dist/ar-sa.js +1 -55
  22. package/dist/ar-tn.js +1 -55
  23. package/dist/ar.js +1 -55
  24. package/dist/ar2.js +1 -470
  25. package/dist/cs.js +1 -55
  26. package/dist/cs2.js +1 -470
  27. package/dist/de-at.js +1 -55
  28. package/dist/de-ch.js +1 -55
  29. package/dist/de.js +1 -55
  30. package/dist/de2.js +1 -470
  31. package/dist/domUtils.js +2 -820
  32. package/dist/en-au.js +1 -55
  33. package/dist/en-ca.js +1 -55
  34. package/dist/en-gb.js +1 -55
  35. package/dist/en-ie.js +1 -55
  36. package/dist/en-il.js +1 -55
  37. package/dist/en-nz.js +1 -55
  38. package/dist/es-do.js +1 -55
  39. package/dist/es-us.js +1 -55
  40. package/dist/es.js +1 -55
  41. package/dist/es2.js +1 -470
  42. package/dist/export.js +1 -25
  43. package/dist/export.legacy.js +1 -25
  44. package/dist/fontUtils.js +1 -1036
  45. package/dist/fr-ca.js +1 -55
  46. package/dist/fr-ch.js +1 -55
  47. package/dist/fr.js +1 -55
  48. package/dist/fr2.js +1 -470
  49. package/dist/humanAgentUtils.js +1 -1393
  50. package/dist/it-ch.js +1 -55
  51. package/dist/it.js +1 -55
  52. package/dist/it2.js +1 -470
  53. package/dist/ja.js +1 -55
  54. package/dist/ja2.js +1 -470
  55. package/dist/jstz.min.js +1 -41
  56. package/dist/ko.js +1 -55
  57. package/dist/ko2.js +1 -470
  58. package/dist/messageUtils.js +1 -1338
  59. package/dist/mockServiceDesk.js +1 -851
  60. package/dist/moduleFederationPluginUtils.js +2 -5852
  61. package/dist/nl.js +1 -55
  62. package/dist/nl2.js +1 -470
  63. package/dist/pt-br.js +1 -55
  64. package/dist/pt-br2.js +1 -470
  65. package/dist/pt.js +1 -55
  66. package/dist/render.js +1 -88
  67. package/dist/web-components/cds-aichat-container/index.js +3 -3
  68. package/dist/web-components/cds-aichat-container/index.js.map +1 -1
  69. package/dist/web-components/cds-aichat-custom-element/index.js +2 -2
  70. package/dist/web-components/cds-aichat-custom-element/index.js.map +1 -1
  71. package/dist/zh-cn.js +1 -55
  72. package/dist/zh-tw.js +1 -55
  73. package/dist/zh-tw2.js +1 -470
  74. package/dist/zh.js +1 -470
  75. package/package.json +1 -1
@@ -1,649 +1 @@
1
- /*
2
-
3
-
4
- (C) Copyright IBM Corp. 2017, 2024. All Rights Reserved.
5
-
6
- Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
7
- in compliance with the License. You may obtain a copy of the License at
8
-
9
- http://www.apache.org/licenses/LICENSE-2.0
10
-
11
- Unless required by applicable law or agreed to in writing, software distributed under the License
12
- is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
13
- or implied. See the License for the specific language governing permissions and limitations under
14
- the License.
15
-
16
- @carbon/ai-chat 0.1.1-alpha5
17
-
18
- Built: Oct 24 2024 10:59 am -04:00
19
-
20
-
21
-
22
- */
23
- import { ak as ErrorType, t as isConnectToAgent, j as createMessageResponseForText } from './messageUtils.js';
24
- import { W as WA_CONSOLE_PREFIX, i as isEmptyObject, p as MessageResponseTypes, c as consoleError, n as sleep } from './aiChatEntry2.js';
25
- import { S as ServiceDeskImpl } from './ServiceDeskImpl.js';
26
- import '@lit/react';
27
- import 'react';
28
- import 'lit';
29
- import 'lit/decorators.js';
30
- import 'react-dom';
31
-
32
- /**
33
- *
34
- * IBM Confidential
35
- *
36
- * (C) Copyright IBM Corp. 2019, 2023
37
- *
38
- * The source code for this program is not published or otherwise
39
- * divested of its trade secrets, irrespective of what has been
40
- * deposited with the U. S. Copyright Office
41
- *
42
- * US Government Users Restricted Rights - Use, duplication or
43
- * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
44
- *
45
- */
46
- /**
47
- * Event types that Zendesk Web SDK send to us.
48
- */
49
- var CHAT_EVENT_TYPES;
50
- (function (CHAT_EVENT_TYPES) {
51
- // Chat message incoming from an agent.
52
- CHAT_EVENT_TYPES["MESSAGE"] = "chat.msg";
53
- // Agent is typing.
54
- CHAT_EVENT_TYPES["TYPING"] = "typing";
55
- // A visitor is in the wait queue.
56
- CHAT_EVENT_TYPES["WAIT_QUEUE"] = "chat.wait_queue";
57
- // A visitor is in a specific position in the wait queue.
58
- CHAT_EVENT_TYPES["QUEUE_POSITION"] = "chat.queue_position";
59
- // An agent or visitor has joined the chat.
60
- CHAT_EVENT_TYPES["MEMBER_JOIN"] = "chat.memberjoin";
61
- // An agent or visitor has left the chat.
62
- CHAT_EVENT_TYPES["MEMBER_LEAVE"] = "chat.memberleave";
63
- // Agent has read a message.
64
- CHAT_EVENT_TYPES["LAST_READ"] = "last_read";
65
- // An agent or visitor sends a chat comment.
66
- CHAT_EVENT_TYPES["COMMENT"] = "chat.comment";
67
- })(CHAT_EVENT_TYPES || (CHAT_EVENT_TYPES = {}));
68
- /**
69
- * Account status that denotes whether Zendesk account is valid and has available agents.
70
- */
71
- var ACCOUNT_STATUS;
72
- (function (ACCOUNT_STATUS) {
73
- ACCOUNT_STATUS["ONLINE"] = "online";
74
- ACCOUNT_STATUS["AWAY"] = "away";
75
- ACCOUNT_STATUS["OFFLINE"] = "offline";
76
- })(ACCOUNT_STATUS || (ACCOUNT_STATUS = {}));
77
- /**
78
- * Connection status event types that Zendesk sends after we call init().
79
- */
80
- var CONNECTION_STATUS;
81
- (function (CONNECTION_STATUS) {
82
- CONNECTION_STATUS["CLOSED"] = "closed";
83
- CONNECTION_STATUS["CONNECTED"] = "connected";
84
- CONNECTION_STATUS["CONNECTING"] = "connecting";
85
- })(CONNECTION_STATUS || (CONNECTION_STATUS = {}));
86
- // Number of retries we attempt when Zendesk Web SDK calls fail.
87
- const NUM_RETRIES = 5;
88
- // Sleep interval in milliseconds before the next retry.
89
- const RETRY_INTERVAL = 1000;
90
- // Zendesk Web SDK source script URL.
91
- const ZENDESK_WEB_SDK_URL = 'https://dev.zopim.com/web-sdk/latest/web-sdk.js';
92
- // Nickname prefix for agents.
93
- const NICKNAME_PREFIX_AGENT = 'agent:';
94
- // Nickname prefix for visitors, AKA the chat widget user. (visitor prefix does NOT have an appended colon)
95
- const NICKNAME_PREFIX_VISITOR = 'visitor';
96
- // Prefix we use for denoting a tag used to store a session variable in for agent app.
97
- const TAG_WA_SESSION_PREFIX = 'x-watson-assistant-session_';
98
- // Prefix we use for denoting a tag used to store a session variable in our agent app. This is a newer version that is
99
- // compatible with ZenDesk Support, which removes special characters more aggressively than ZenDesk Chat.
100
- const TAG_WA_SESSION_PREFIX_SUPPORT = 'x-watson-assistant-session-support_';
101
- // Error denoting Zendesk account is not online or has no online agents.
102
- const ERROR_ACCOUNT_NOT_ONLINE = `${WA_CONSOLE_PREFIX} Zendesk account is not online`;
103
- // Error denoting a connection attempt was made but with no initial message.
104
- const ERROR_NO_AGENT_MESSAGE = `${WA_CONSOLE_PREFIX} A message to the agent is required to initiate a connection to the service desk.`;
105
- // Error denoting the Zendesk account connection is not initialized and is not ready to be called.
106
- const ERROR_NOT_INITIALIZED = `${WA_CONSOLE_PREFIX} Zendesk Web SDK is not initialized.`;
107
- // Error denoting that we do not support a structured message without an initialed message string.
108
- const ERROR_STRUCTURED_MSG_NOT_SUPPORTED = `${WA_CONSOLE_PREFIX} Received a structured message without a string message from agent and this is not supported.`;
109
- // Warning denoting we received a structured_msg event type that we don't currently support.
110
- const WARNING_EVENT_TYPE_NOT_SUPPORTED = (type) => `${WA_CONSOLE_PREFIX} Event type ${type} not currently supported.`;
111
- // Warning denoting we received an options array event type that we don't currently support.
112
- const WARNING_MESSAGE_OPTIONS_NOT_SENT = `${WA_CONSOLE_PREFIX} Received options attached to the message and the options will not be displayed to the user.`;
113
- // Warning denoting that we received a structured message with a string, and that we will strip out the structured msg.
114
- const WARNING_STRUCTURED_MSG_NOT_SUPPORTED = `${WA_CONSOLE_PREFIX} Received a structured message from agent and this is not supported. Only the string message will be sent.`;
115
-
116
- /**
117
- *
118
- * IBM Confidential
119
- *
120
- * (C) Copyright IBM Corp. 2019, 2023
121
- *
122
- * The source code for this program is not published or otherwise
123
- * divested of its trade secrets, irrespective of what has been
124
- * deposited with the U. S. Copyright Office
125
- *
126
- * US Government Users Restricted Rights - Use, duplication or
127
- * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
128
- *
129
- */
130
- /**
131
- * Zendesk Integration type name - used externally for routing purposes
132
- */
133
- const ZENDESK_INTEGRATION_NAME = 'zendesk';
134
- /**
135
- * Boolean indicating if Zendesk's SDK is already loaded on the DOM as a script. If it is, then ZendeskServiceDesk will
136
- * skip loading another identical script onto the DOM.
137
- */
138
- global.zendeskScriptLoaded = false;
139
- class ZendeskServiceDesk extends ServiceDeskImpl {
140
- constructor(callback, config, serviceManager) {
141
- super(callback, config, serviceManager);
142
- /**
143
- * Indicates if we are currently connected to the service desk. This may flip to false at any point as the result
144
- * of the connection getting dropped in the middle of a conversation.
145
- */
146
- this.isConnected = false;
147
- this.account_key = config && config.subscription && config.subscription.account && config.subscription.account.id;
148
- if (!this.account_key) {
149
- throw new Error('Zendesk account key is not found in definition config.');
150
- }
151
- this.isChatStarted = false;
152
- }
153
- /**
154
- * If not already initialized, this will load the zendesk module from the ZENDESK_WEB_SDK_URL source and then inject
155
- * the module into the webpage's DOM. When the module load is complete, the returned Promise will resolve.
156
- */
157
- async ensureZendeskModuleLoadedAndConnected() {
158
- // If Zendesk SDK is already loaded, simply set the SDK and SDK-promise objects.
159
- // Otherwise, load the Zendesk SDK onto the DOM.
160
- if (global.zendeskScriptLoaded) {
161
- this.sdk = window.zChat;
162
- this.loadingSDKPromise = Promise.resolve();
163
- }
164
- else if (!this.loadingSDKPromise && !this.sdk) {
165
- this.loadingSDKPromise = new Promise((resolve, reject) => {
166
- const script = document.createElement('script');
167
- script.type = 'text/javascript';
168
- script.async = true;
169
- script.src = ZENDESK_WEB_SDK_URL;
170
- script.onerror = (error) => {
171
- reject(error);
172
- };
173
- script.onload = () => {
174
- this.loadingSDKPromise = null;
175
- this.sdk = window.zChat;
176
- const params = {
177
- account_key: this.account_key,
178
- suppress_console_error: true,
179
- };
180
- // If JWT is available, then call the Zendesk jwt_fn
181
- // to make sure calls are routed to Zendesk through the auth route
182
- if (this.authJWT) {
183
- params.authentication = {
184
- jwt_fn: (callback) => {
185
- // The JWT is immediately available so call the callback right away
186
- callback(this.authJWT);
187
- },
188
- };
189
- }
190
- this.sdk.init(params);
191
- this.sdk.on('chat', (event_data) => {
192
- if (this.isAccountOnline()) {
193
- this.handleChatEvent(event_data);
194
- }
195
- });
196
- // This event fires only when an agent joins or an existing agent's information has changed.
197
- this.sdk.on('agent_update', (event_data) => {
198
- if (this.isAccountOnline()) {
199
- this.handleChatAgentUpdateEvent(event_data);
200
- }
201
- });
202
- this.sdk.on('error', (error) => {
203
- const { context } = error;
204
- if (context === 'init') {
205
- this.callback.setErrorStatus({ type: ErrorType.CONNECTING, logInfo: error.message });
206
- }
207
- });
208
- // Documentation on connection_update events: https://api.zopim.com/web-sdk/#zchat-getaccountstatus.
209
- this.sdk.on('connection_update', (status) => {
210
- switch (status) {
211
- case CONNECTION_STATUS.CONNECTED: {
212
- this.isConnected = true;
213
- this.callback.setErrorStatus({ type: ErrorType.DISCONNECTED, isDisconnected: false });
214
- // Resolve the initial promise that may be waiting on the connection to happen. This may occur
215
- // multiple times during the chat but it's okay to do this more than once.
216
- resolve(undefined);
217
- break;
218
- }
219
- case CONNECTION_STATUS.CONNECTING:
220
- case CONNECTION_STATUS.CLOSED: {
221
- // CONNECTION_STATUS.CONNECTING can occur if the connection with the service desk is temporarily lost in the middle of a
222
- // conversation. CONNECTION_STATUS.CLOSED can occur if the connection has been closed due to various reasons.
223
- const wasConnected = this.isConnected;
224
- this.isConnected = false;
225
- if (wasConnected) {
226
- this.callback.setErrorStatus({ type: ErrorType.DISCONNECTED, isDisconnected: true });
227
- }
228
- break;
229
- }
230
- }
231
- });
232
- };
233
- document.getElementsByTagName('head')[0].appendChild(script);
234
- global.zendeskScriptLoaded = true;
235
- });
236
- }
237
- return this.loadingSDKPromise;
238
- }
239
- async startChat(connectMessage, startChatOptions) {
240
- // The connect info is contained on the first "connect_to_agent" response we got from dialog.
241
- const connectInfo = connectMessage.output.generic.find(isConnectToAgent);
242
- this.authJWT = connectInfo.transfer_info?.additional_data?.jwt;
243
- await this.ensureZendeskModuleLoadedAndConnected();
244
- if (this.isChatStarted) {
245
- return;
246
- }
247
- if (this.isAccountOnline()) {
248
- // If the visitor does not have a JWT associated with it (aka not authenticated), then
249
- // set her display name to the display name generated by the webchat.
250
- // If the visitor is authenticated, then Zendesk will automatically compile her details
251
- // from her JWT payload.
252
- if (!this.authJWT) {
253
- this.sdk.setVisitorInfo({
254
- display_name: this.state.userID || 'Unknown Visitor',
255
- email: '',
256
- phone: '',
257
- });
258
- }
259
- // Clearing the department before the chat is required, otherwise the conversation retains the existing
260
- // department information (despite having already requested to clear the department in endChat).
261
- await this.clearChatDepartment();
262
- // Gather info about all online departments and the target routing department name.
263
- // Then figure if the target route department is online, and if so then perform the routing.
264
- const routeDepartmentName = connectInfo.transfer_info?.target?.[ZENDESK_INTEGRATION_NAME]?.department;
265
- const routeDepartment = routeDepartmentName &&
266
- this.sdk
267
- .getAllDepartments()
268
- .find((department) => department.name === routeDepartmentName && department.status === ACCOUNT_STATUS.ONLINE);
269
- if (routeDepartment) {
270
- await this.setChatDepartment(routeDepartment.id);
271
- }
272
- // In order to load the agent app inside the Zendesk application, we need to pass the session history key to
273
- // Zendesk. We do that by passing the key as a tag. There are two different versions of Zendesk: Zendesk Chat
274
- // and Zendesk Support. Each uses its own format for tags so we need to pass two tags to support either system.
275
- const addSessionTagExecutor = () => new Promise(resolve => {
276
- const tags = [];
277
- // A string that is separated by AGENT_APP_KEY_SEPARATOR that can be used to create a PublicConfig. It
278
- // includes base connect info like integrationID, etc., and by pass JWT security
279
- // with a one time auth code. It is formatted as JSON as
280
- // {
281
- // "sessionHistoryKey":"dev::6.9.0::425169::f4d26c16-8607-49ce-8d71-70f1c2de5feb::6a755ee2-b094-4b9b-ada3-482295647f17::6435434b-b3e1-4f70-8eff-7149d43d938b::0fcc042c5b45414b99850fbd38840ad9"
282
- // }
283
- // We must stringify it for ZenDesk Chat.
284
- const metadata_for_chat = JSON.stringify(startChatOptions.agentAppInfo);
285
- // There might already be tags on the account, so we include Date.now here to make sure we grab most recent.
286
- tags.push(`${TAG_WA_SESSION_PREFIX}${this.state.sessionID}_${Date.now()}_${metadata_for_chat}`);
287
- // Zendesk Support only allows alphanumeric, dash and underscore characters in their tags.
288
- // They say they support / but it is a lie and it is stripped.
289
- // They also say they support all UTF-8 characters... (see https://www.w3schools.com/charsets/ref_utf_basic_latin.asp)
290
- // But they don't really. But they do support the Latin ones below.
291
- // They also change everything to lowercase. I blame a designer I hate for that one.
292
- // See https://support.zendesk.com/hc/en-us/articles/4408835059482-Working-with-ticket-tags
293
- // This means we need to send the data in an alternate format.
294
- // We have to send both versions to account for folks with a version of the agent app prior to web chat version 7.1.
295
- // We could, in the future, force folks to upgrade their agent app when moving to a future major version of web chat
296
- // and remove the TAG_WA_SESSION_PREFIX tag and only use this tag.
297
- const metadata_for_support = startChatOptions.agentAppInfo.sessionHistoryKey
298
- .replace(/\./g, 'ä') // replace all periods with ä
299
- .replace(/_/g, 'â') // replace all underscores with â, we don't want things to get confused when we split on _ later.
300
- .replace(/::/g, 'à'); // replace all '::' with 'à'
301
- // The ZenDesk agent app will reverse all these replacements when they are able to grab the tags; this
302
- // happens in iframe.html.
303
- // There might already be tags on the account, so we include Date.now here to make sure we grab most recent.
304
- tags.push(`${TAG_WA_SESSION_PREFIX_SUPPORT}${this.state.sessionID}_${Date.now()}_${metadata_for_support}`);
305
- this.sdk.addTags(tags, (error) => resolve(this.handleError(error)));
306
- });
307
- await this.doWithRetry(0, addSessionTagExecutor);
308
- // Add any tags that are specified in the dialog pre-chat context variables.
309
- const preChat = connectMessage.context?.integrations?.zendesk?.pre_chat;
310
- if (typeof preChat === 'object' && !isEmptyObject(preChat)) {
311
- const preChatTags = Object.entries(preChat).map(([key, value]) => `${key}_${value}`);
312
- const addContextTagsExecutor = () => new Promise(resolve => {
313
- this.sdk.addTags(preChatTags, (error) => resolve(this.handleError(error)));
314
- });
315
- await this.doWithRetry(0, addContextTagsExecutor);
316
- }
317
- // Send the messages provided by the connect_to_agent object intended to be sent to the agent. If the array doesn't
318
- // exist, the connection should fail because an initial message is required to establish the websocket connection.
319
- if (connectInfo.transfer_info && Array.isArray(connectInfo.transfer_info.summary_message_to_agent)) {
320
- connectInfo.transfer_info.summary_message_to_agent.forEach(agentMessage => {
321
- if (agentMessage.response_type === MessageResponseTypes.TEXT) {
322
- this.sdk.sendChatMsg(agentMessage.text, (error) => {
323
- if (error) {
324
- throw Error(error);
325
- }
326
- });
327
- }
328
- });
329
- }
330
- else {
331
- throw Error(ERROR_NO_AGENT_MESSAGE);
332
- }
333
- // Check if the agent is already in the chat room. This happens when the Zendesk agent clicks on Continue Chat
334
- // after the web chat user has ended the chat.
335
- const existingAgents = this.sdk.getServingAgentsInfo();
336
- if (Array.isArray(existingAgents) && existingAgents.length > 0) {
337
- const { nick, display_name } = existingAgents[0];
338
- const agent = {
339
- id: nick,
340
- nickname: display_name, // nickname is a misnomer in Zendesk, using display_name instead
341
- };
342
- this.currentAgent = agent;
343
- this.callback.agentJoined(agent);
344
- }
345
- this.isChatStarted = true;
346
- }
347
- else {
348
- throw Error(ERROR_ACCOUNT_NOT_ONLINE);
349
- }
350
- }
351
- async endChat() {
352
- await this.ensureZendeskModuleLoadedAndConnected();
353
- this.assertChatStarted();
354
- const executor = () => new Promise(resolve => {
355
- // End chat while clearing the conversation's default department.
356
- // Otherwise, changing the conversation's department will not work.
357
- this.sdk.endChat({
358
- clear_dept_id_on_chat_ended: true,
359
- }, (error) => {
360
- if (error) {
361
- consoleError('[ZendeskServiceDesk]', error);
362
- resolve(false);
363
- }
364
- else {
365
- this.isChatStarted = false;
366
- this.currentAgent = undefined;
367
- resolve(true);
368
- }
369
- });
370
- });
371
- await this.doWithRetry(0, executor);
372
- }
373
- async sendMessageToAgent(message, messageID) {
374
- await this.ensureZendeskModuleLoadedAndConnected();
375
- this.assertChatStarted();
376
- const { text } = message.input;
377
- if (this.isAccountOnline()) {
378
- const executor = () => new Promise(resolve => {
379
- this.sdk.sendChatMsg(text, (error) => {
380
- if (error) {
381
- consoleError('[ZendeskServiceDesk] Error sending message', error);
382
- resolve(false);
383
- }
384
- else {
385
- this.sdk.sendTyping(false);
386
- resolve(true);
387
- }
388
- });
389
- });
390
- await this.doWithRetry(0, executor);
391
- }
392
- else {
393
- throw Error(ERROR_ACCOUNT_NOT_ONLINE);
394
- }
395
- }
396
- async userReadMessages() {
397
- await this.ensureZendeskModuleLoadedAndConnected();
398
- this.assertChatStarted();
399
- this.sdk.markAsRead();
400
- }
401
- async userTyping(isTyping) {
402
- await this.ensureZendeskModuleLoadedAndConnected();
403
- this.assertChatStarted();
404
- this.sdk.sendTyping(isTyping);
405
- }
406
- async areAnyAgentsOnline(connectMessage) {
407
- const connectInfo = connectMessage.output.generic.find(isConnectToAgent);
408
- this.authJWT = connectInfo?.transfer_info?.additional_data?.jwt;
409
- await this.ensureZendeskModuleLoadedAndConnected();
410
- return this.isAccountOnline();
411
- }
412
- /**
413
- * Routes the event to the correct handler method based on the event type.
414
- */
415
- handleChatEvent(event) {
416
- switch (event.type) {
417
- case CHAT_EVENT_TYPES.MESSAGE: {
418
- this.handleChatMessageEvent(event);
419
- break;
420
- }
421
- case CHAT_EVENT_TYPES.TYPING: {
422
- this.handleChatTypingEvent(event);
423
- break;
424
- }
425
- case CHAT_EVENT_TYPES.WAIT_QUEUE: {
426
- const queuePositionEvent = {
427
- type: CHAT_EVENT_TYPES.QUEUE_POSITION,
428
- nick: event.nick,
429
- queue_position: event.wait_queue,
430
- };
431
- this.handleChatQueuePositionEvent(queuePositionEvent);
432
- break;
433
- }
434
- case CHAT_EVENT_TYPES.QUEUE_POSITION: {
435
- this.handleChatQueuePositionEvent(event);
436
- break;
437
- }
438
- case CHAT_EVENT_TYPES.MEMBER_JOIN: {
439
- // nothing goes here because the member join feature is being handled by the 'agent_update' event
440
- break;
441
- }
442
- case CHAT_EVENT_TYPES.MEMBER_LEAVE: {
443
- this.handleChatAgentLeaveEvent(event);
444
- break;
445
- }
446
- case CHAT_EVENT_TYPES.LAST_READ: {
447
- this.handleChatAgentLastReadEvent(event);
448
- break;
449
- }
450
- case CHAT_EVENT_TYPES.COMMENT: {
451
- this.handleChatComment(event);
452
- break;
453
- }
454
- default: {
455
- console.warn(WARNING_EVENT_TYPE_NOT_SUPPORTED(event.type));
456
- this.handleEventNotSupported(event);
457
- break;
458
- }
459
- }
460
- }
461
- /**
462
- * Handles event when the agent sends a message.
463
- */
464
- async handleChatMessageEvent(event) {
465
- const { msg, structured_msg, options } = event;
466
- if (this.isAgentMessage(event)) {
467
- // We currently cannot support structured messages, so we treat them like regular string messages.
468
- // Options array might exist and contain no elements even in a pure text message event.
469
- if (structured_msg || (Array.isArray(options) && options.length > 0)) {
470
- // If the structured message has no initial string, then we cannot treat this like a single string message and
471
- // must throw an error.
472
- if (!msg) {
473
- throw Error(ERROR_STRUCTURED_MSG_NOT_SUPPORTED);
474
- }
475
- // Warning message depends on whether the structured message or options was filled.
476
- const warningMsg = structured_msg ? WARNING_STRUCTURED_MSG_NOT_SUPPORTED : WARNING_MESSAGE_OPTIONS_NOT_SENT;
477
- console.warn(warningMsg);
478
- const executor = () => new Promise(resolve => this.sdk.sendChatComment(warningMsg, (error) => resolve(this.handleError(error))));
479
- await this.doWithRetry(0, executor);
480
- }
481
- const agentId = this.currentAgent ? this.currentAgent.id : null;
482
- const messageResponse = createMessageResponseForText(msg);
483
- // As soon as the agent sends a message, make sure to clear the "isTyping" event for the agent.
484
- this.callback.agentTyping(false);
485
- this.callback.sendMessageToUser(messageResponse, agentId);
486
- }
487
- }
488
- /**
489
- * Handles event when the agent is typing.
490
- */
491
- handleChatTypingEvent(event) {
492
- const { typing } = event;
493
- if (this.isAgentMessage(event)) {
494
- this.callback.agentTyping(typing);
495
- }
496
- }
497
- /**
498
- * Handles event when the visitor/chat user enters the agent wait queue.
499
- */
500
- handleChatQueuePositionEvent(event) {
501
- const { queue_position } = event;
502
- const availability = {
503
- position_in_queue: queue_position,
504
- };
505
- this.callback.updateAgentAvailability(availability);
506
- }
507
- /**
508
- * Handles event when an agent joins, is transferred, or has updated his/her information.
509
- */
510
- handleChatAgentUpdateEvent(event) {
511
- // Check if the chat has not started (or more actually, has already ended) and ignore if so.
512
- if (!this.isChatStarted) {
513
- return;
514
- }
515
- const { nick, display_name } = event;
516
- const agent = {
517
- id: nick,
518
- nickname: display_name,
519
- profile_picture_url: event.avatar_path ? event.avatar_path : undefined,
520
- };
521
- // If an agent already exists and the agent IDs do not match, then an agent transfer is occurring.
522
- if (this.currentAgent && this.currentAgent.id !== agent.id) {
523
- this.callback.beginTransferToAnotherAgent(agent);
524
- this.callback.agentJoined(agent);
525
- }
526
- else if (!this.currentAgent) {
527
- // New agent has joined, and no agent had previously joined.
528
- this.callback.agentJoined(agent);
529
- }
530
- this.currentAgent = agent;
531
- }
532
- /**
533
- * Handles event when an agent leaves the chat.
534
- */
535
- handleChatAgentLeaveEvent(event) {
536
- const { nick } = event;
537
- if (this.isAgentMessage(event)) {
538
- // If the current agent leaves, then end the chat.
539
- // TO DO: When we support multiple agents, we need to track which agents have come and gone.
540
- if (nick === this.currentAgent.id) {
541
- this.callback.agentLeftChat();
542
- this.currentAgent = null;
543
- }
544
- }
545
- }
546
- /**
547
- * Handles event when an agent has read a message.
548
- */
549
- handleChatAgentLastReadEvent(event) {
550
- if (this.isAgentMessage(event)) {
551
- this.callback.agentReadMessages();
552
- }
553
- }
554
- /**
555
- * Handles event when an agent or visitor sends a chat comment. Sending a chat comment is akin to sending a chat
556
- * status to the agent.
557
- */
558
- async handleChatComment(event) {
559
- if (this.isVisitorMessage(event)) {
560
- // This is the expected case, and we ignore chat comment events that we send on the visitor's behalf.
561
- return;
562
- }
563
- // If the agent sends a comment, let the agent know we don't know how to send that to the visitor.
564
- this.handleEventNotSupported(event);
565
- }
566
- /**
567
- * Handles events that we do not currently support by sending a chat comment to the agent the message was not sent.
568
- */
569
- async handleEventNotSupported(event) {
570
- const executor = () => new Promise(resolve => this.sdk.sendChatComment(WARNING_EVENT_TYPE_NOT_SUPPORTED(event.type), (error) => resolve(this.handleError(error))));
571
- await this.doWithRetry(0, executor);
572
- }
573
- /**
574
- * Returns true if the event is a message with agent as the source.
575
- */
576
- isAgentMessage(event) {
577
- return typeof event.nick === 'string' && event.nick.startsWith(NICKNAME_PREFIX_AGENT);
578
- }
579
- /**
580
- * Returns true if the event is a message with visitor as the source.
581
- */
582
- isVisitorMessage(event) {
583
- return typeof event.nick === 'string' && event.nick.startsWith(NICKNAME_PREFIX_VISITOR);
584
- }
585
- /**
586
- * Returns true if the account is online and there are online agents.
587
- */
588
- isAccountOnline() {
589
- return this.sdk?.getAccountStatus() === ACCOUNT_STATUS.ONLINE;
590
- }
591
- /**
592
- * Asserts that the chat has initialized and has started.
593
- */
594
- assertChatStarted() {
595
- if (!this.isChatStarted) {
596
- throw Error(ERROR_NOT_INITIALIZED);
597
- }
598
- }
599
- /**
600
- * Sets the routing department of the chat conversation.
601
- *
602
- * @param departmentId The ID of the department to route to.
603
- */
604
- async setChatDepartment(departmentId) {
605
- const executor = () => new Promise(resolve => this.sdk.setVisitorDefaultDepartment(departmentId, (error) => resolve(this.handleError(error))));
606
- await this.doWithRetry(0, executor);
607
- }
608
- /**
609
- * Clear the routing department of the chat conversation.
610
- */
611
- async clearChatDepartment() {
612
- const executor = () => new Promise(resolve => this.sdk.clearVisitorDefaultDepartment((error) => resolve(this.handleError(error))));
613
- await this.doWithRetry(0, executor);
614
- }
615
- /**
616
- * Calls the executor method and retries the call a number of times if the executor fails.
617
- */
618
- async doWithRetry(numRetriesAttempted, executor) {
619
- if (numRetriesAttempted > NUM_RETRIES) {
620
- return false;
621
- }
622
- try {
623
- const result = await executor();
624
- if (result) {
625
- return true;
626
- }
627
- }
628
- catch (error) {
629
- consoleError('Error in ZendeskServiceDesk.doWithRetry', error);
630
- }
631
- await sleep(RETRY_INTERVAL);
632
- return this.doWithRetry(numRetriesAttempted + 1, executor);
633
- }
634
- /**
635
- * Takes an optional error and, if not null, prints the error onto the browser console.
636
- * Then returns whether an error was found.
637
- *
638
- * @param error The error to investigate (can be undefined).
639
- */
640
- handleError(error) {
641
- if (error) {
642
- consoleError('[ZendeskServiceDesk]', error);
643
- return false;
644
- }
645
- return true;
646
- }
647
- }
648
-
649
- export { ZendeskServiceDesk };
1
+ import{ak as t,t as e,j as s}from"./messageUtils.js";import{W as n,i,p as a,c as r,n as o}from"./aiChatEntry2.js";import{S as h}from"./ServiceDeskImpl.js";import"@lit/react";import"react";import"lit";import"lit/decorators.js";import"react-dom";var d,c,l;!function(t){t.MESSAGE="chat.msg",t.TYPING="typing",t.WAIT_QUEUE="chat.wait_queue",t.QUEUE_POSITION="chat.queue_position",t.MEMBER_JOIN="chat.memberjoin",t.MEMBER_LEAVE="chat.memberleave",t.LAST_READ="last_read",t.COMMENT="chat.comment"}(d||(d={})),function(t){t.ONLINE="online",t.AWAY="away",t.OFFLINE="offline"}(c||(c={})),function(t){t.CLOSED="closed",t.CONNECTED="connected",t.CONNECTING="connecting"}(l||(l={}));const u=`${n} Zendesk account is not online`,g=`${n} A message to the agent is required to initiate a connection to the service desk.`,p=`${n} Zendesk Web SDK is not initialized.`,k=`${n} Received a structured message without a string message from agent and this is not supported.`,E=t=>`${n} Event type ${t} not currently supported.`,m=`${n} Received options attached to the message and the options will not be displayed to the user.`,C=`${n} Received a structured message from agent and this is not supported. Only the string message will be sent.`;global.zendeskScriptLoaded=!1;class y extends h{constructor(t,e,s){if(super(t,e,s),this.isConnected=!1,this.account_key=e&&e.subscription&&e.subscription.account&&e.subscription.account.id,!this.account_key)throw new Error("Zendesk account key is not found in definition config.");this.isChatStarted=!1}async ensureZendeskModuleLoadedAndConnected(){return global.zendeskScriptLoaded?(this.sdk=window.zChat,this.loadingSDKPromise=Promise.resolve()):this.loadingSDKPromise||this.sdk||(this.loadingSDKPromise=new Promise(((e,s)=>{const n=document.createElement("script");n.type="text/javascript",n.async=!0,n.src="https://dev.zopim.com/web-sdk/latest/web-sdk.js",n.onerror=t=>{s(t)},n.onload=()=>{this.loadingSDKPromise=null,this.sdk=window.zChat;const s={account_key:this.account_key,suppress_console_error:!0};this.authJWT&&(s.authentication={jwt_fn:t=>{t(this.authJWT)}}),this.sdk.init(s),this.sdk.on("chat",(t=>{this.isAccountOnline()&&this.handleChatEvent(t)})),this.sdk.on("agent_update",(t=>{this.isAccountOnline()&&this.handleChatAgentUpdateEvent(t)})),this.sdk.on("error",(e=>{const{context:s}=e;"init"===s&&this.callback.setErrorStatus({type:t.CONNECTING,logInfo:e.message})})),this.sdk.on("connection_update",(s=>{switch(s){case l.CONNECTED:this.isConnected=!0,this.callback.setErrorStatus({type:t.DISCONNECTED,isDisconnected:!1}),e(void 0);break;case l.CONNECTING:case l.CLOSED:{const e=this.isConnected;this.isConnected=!1,e&&this.callback.setErrorStatus({type:t.DISCONNECTED,isDisconnected:!0});break}}}))},document.getElementsByTagName("head")[0].appendChild(n),global.zendeskScriptLoaded=!0}))),this.loadingSDKPromise}async startChat(t,s){const n=t.output.generic.find(e);if(this.authJWT=n.transfer_info?.additional_data?.jwt,await this.ensureZendeskModuleLoadedAndConnected(),!this.isChatStarted){if(!this.isAccountOnline())throw Error(u);{this.authJWT||this.sdk.setVisitorInfo({display_name:this.state.userID||"Unknown Visitor",email:"",phone:""}),await this.clearChatDepartment();const e=n.transfer_info?.target?.zendesk?.department,r=e&&this.sdk.getAllDepartments().find((t=>t.name===e&&t.status===c.ONLINE));r&&await this.setChatDepartment(r.id);const o=()=>new Promise((t=>{const e=[],n=JSON.stringify(s.agentAppInfo);e.push(`x-watson-assistant-session_${this.state.sessionID}_${Date.now()}_${n}`);const i=s.agentAppInfo.sessionHistoryKey.replace(/\./g,"ä").replace(/_/g,"â").replace(/::/g,"à");e.push(`x-watson-assistant-session-support_${this.state.sessionID}_${Date.now()}_${i}`),this.sdk.addTags(e,(e=>t(this.handleError(e))))}));await this.doWithRetry(0,o);const h=t.context?.integrations?.zendesk?.pre_chat;if("object"==typeof h&&!i(h)){const t=Object.entries(h).map((([t,e])=>`${t}_${e}`)),e=()=>new Promise((e=>{this.sdk.addTags(t,(t=>e(this.handleError(t))))}));await this.doWithRetry(0,e)}if(!n.transfer_info||!Array.isArray(n.transfer_info.summary_message_to_agent))throw Error(g);n.transfer_info.summary_message_to_agent.forEach((t=>{t.response_type===a.TEXT&&this.sdk.sendChatMsg(t.text,(t=>{if(t)throw Error(t)}))}));const d=this.sdk.getServingAgentsInfo();if(Array.isArray(d)&&d.length>0){const{nick:t,display_name:e}=d[0],s={id:t,nickname:e};this.currentAgent=s,this.callback.agentJoined(s)}this.isChatStarted=!0}}}async endChat(){await this.ensureZendeskModuleLoadedAndConnected(),this.assertChatStarted();await this.doWithRetry(0,(()=>new Promise((t=>{this.sdk.endChat({clear_dept_id_on_chat_ended:!0},(e=>{e?(r("[ZendeskServiceDesk]",e),t(!1)):(this.isChatStarted=!1,this.currentAgent=void 0,t(!0))}))}))))}async sendMessageToAgent(t,e){await this.ensureZendeskModuleLoadedAndConnected(),this.assertChatStarted();const{text:s}=t.input;if(!this.isAccountOnline())throw Error(u);{const t=()=>new Promise((t=>{this.sdk.sendChatMsg(s,(e=>{e?(r("[ZendeskServiceDesk] Error sending message",e),t(!1)):(this.sdk.sendTyping(!1),t(!0))}))}));await this.doWithRetry(0,t)}}async userReadMessages(){await this.ensureZendeskModuleLoadedAndConnected(),this.assertChatStarted(),this.sdk.markAsRead()}async userTyping(t){await this.ensureZendeskModuleLoadedAndConnected(),this.assertChatStarted(),this.sdk.sendTyping(t)}async areAnyAgentsOnline(t){const s=t.output.generic.find(e);return this.authJWT=s?.transfer_info?.additional_data?.jwt,await this.ensureZendeskModuleLoadedAndConnected(),this.isAccountOnline()}handleChatEvent(t){switch(t.type){case d.MESSAGE:this.handleChatMessageEvent(t);break;case d.TYPING:this.handleChatTypingEvent(t);break;case d.WAIT_QUEUE:{const e={type:d.QUEUE_POSITION,nick:t.nick,queue_position:t.wait_queue};this.handleChatQueuePositionEvent(e);break}case d.QUEUE_POSITION:this.handleChatQueuePositionEvent(t);break;case d.MEMBER_JOIN:break;case d.MEMBER_LEAVE:this.handleChatAgentLeaveEvent(t);break;case d.LAST_READ:this.handleChatAgentLastReadEvent(t);break;case d.COMMENT:this.handleChatComment(t);break;default:console.warn(E(t.type)),this.handleEventNotSupported(t)}}async handleChatMessageEvent(t){const{msg:e,structured_msg:n,options:i}=t;if(this.isAgentMessage(t)){if(n||Array.isArray(i)&&i.length>0){if(!e)throw Error(k);const t=n?C:m;console.warn(t);const s=()=>new Promise((e=>this.sdk.sendChatComment(t,(t=>e(this.handleError(t))))));await this.doWithRetry(0,s)}const t=this.currentAgent?this.currentAgent.id:null,a=s(e);this.callback.agentTyping(!1),this.callback.sendMessageToUser(a,t)}}handleChatTypingEvent(t){const{typing:e}=t;this.isAgentMessage(t)&&this.callback.agentTyping(e)}handleChatQueuePositionEvent(t){const{queue_position:e}=t,s={position_in_queue:e};this.callback.updateAgentAvailability(s)}handleChatAgentUpdateEvent(t){if(!this.isChatStarted)return;const{nick:e,display_name:s}=t,n={id:e,nickname:s,profile_picture_url:t.avatar_path?t.avatar_path:void 0};this.currentAgent&&this.currentAgent.id!==n.id?(this.callback.beginTransferToAnotherAgent(n),this.callback.agentJoined(n)):this.currentAgent||this.callback.agentJoined(n),this.currentAgent=n}handleChatAgentLeaveEvent(t){const{nick:e}=t;this.isAgentMessage(t)&&e===this.currentAgent.id&&(this.callback.agentLeftChat(),this.currentAgent=null)}handleChatAgentLastReadEvent(t){this.isAgentMessage(t)&&this.callback.agentReadMessages()}async handleChatComment(t){this.isVisitorMessage(t)||this.handleEventNotSupported(t)}async handleEventNotSupported(t){await this.doWithRetry(0,(()=>new Promise((e=>this.sdk.sendChatComment(E(t.type),(t=>e(this.handleError(t))))))))}isAgentMessage(t){return"string"==typeof t.nick&&t.nick.startsWith("agent:")}isVisitorMessage(t){return"string"==typeof t.nick&&t.nick.startsWith("visitor")}isAccountOnline(){return this.sdk?.getAccountStatus()===c.ONLINE}assertChatStarted(){if(!this.isChatStarted)throw Error(p)}async setChatDepartment(t){await this.doWithRetry(0,(()=>new Promise((e=>this.sdk.setVisitorDefaultDepartment(t,(t=>e(this.handleError(t))))))))}async clearChatDepartment(){await this.doWithRetry(0,(()=>new Promise((t=>this.sdk.clearVisitorDefaultDepartment((e=>t(this.handleError(e))))))))}async doWithRetry(t,e){if(t>5)return!1;try{if(await e())return!0}catch(t){r("Error in ZendeskServiceDesk.doWithRetry",t)}return await o(1e3),this.doWithRetry(t+1,e)}handleError(t){return!t||(r("[ZendeskServiceDesk]",t),!1)}}export{y as ZendeskServiceDesk};