@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,579 +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 { t as isConnectToAgent, o as asyncForEach, L as InternalMessageResponseType, a0 as ButtonItemKind, a2 as ButtonItemType, ak as ErrorType, ad as ScreenShareState } from './messageUtils.js';
24
- import { r as loadScript } from './domUtils.js';
25
- import { h as debugLog, a4 as assertType, i as isEmptyObject, c as consoleError, a7 as resolveOrTimeout } from './aiChatEntry2.js';
26
- import { aL as getSummaryMessages } from './humanAgentUtils.js';
27
- import { S as ServiceDeskImpl } from './ServiceDeskImpl.js';
28
- import '@lit/react';
29
- import 'react';
30
- import 'lit';
31
- import 'lit/decorators.js';
32
- import 'react-dom';
33
-
34
- /**
35
- *
36
- * IBM Confidential
37
- *
38
- * (C) Copyright IBM Corp. 2023
39
- *
40
- * The source code for this program is not published or otherwise
41
- * divested of its trade secrets, irrespective of what has been
42
- * deposited with the U. S. Copyright Office
43
- *
44
- * US Government Users Restricted Rights - Use, duplication or
45
- * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
46
- *
47
- */
48
- /**
49
- * This service desk integration is an integration to the Genesys contact center using their Web Messenger
50
- * functionality.
51
- *
52
- * @see https://developer.genesys.cloud/commdigital/digital/webmessaging/messengersdk for their SDK documentation.
53
- * @see https://developer.genesys.cloud/forum for their developer forum.
54
- * @see https://help.mypurecloud.com/articles/get-started-with-web-messaging for getting started with web messaging.
55
- */
56
- const PREFIX = '[GenesysMessengerServiceDesk]';
57
- // The amount of time to wait for steps in the initialization process to complete before timing out.
58
- const INIT_TIMEOUT_SECS = 10;
59
- // The Promise that is used to load the SDK. The resolve value indicates if we are reconnecting to an existing session.
60
- let scriptPromise;
61
- // This is the global Genesys object that is created by their SDK.
62
- let Genesys;
63
- class GenesysMessengerServiceDesk extends ServiceDeskImpl {
64
- constructor() {
65
- super(...arguments);
66
- /**
67
- * The maximum size of files that are allowed (if file uploads are allowed). A value of 0 indicates that file
68
- * uploads are not allowed.
69
- */
70
- this.maxFileSizeKB = 0;
71
- /**
72
- * Uploads the given file.
73
- */
74
- this.doFileUpload = async (upload) => {
75
- const transfer = new DataTransfer();
76
- transfer.items.add(upload.file);
77
- const failed = () => {
78
- this.callback.setFileUploadStatus(upload.id, true, this.getIntlText('fileSharing_uploadFailed'));
79
- };
80
- // Request an upload. This process will conclude when the fileUploaded event is fired. We'll resolve the upload
81
- // Promise when that happens.
82
- this.currentFileUploadID = upload.id;
83
- debugLog(`${PREFIX} MessagingService.requestUpload`, upload);
84
- Genesys('command', 'MessagingService.requestUpload', { file: transfer.files }, null, failed);
85
- };
86
- }
87
- /**
88
- * Instructs the service desk to start a new chat. This should be called immediately after the service desk
89
- * instance has been created. It will make the appropriate calls to the service desk and begin communicating back
90
- * to the calling code using the callback produce to the instance. This may only be called once per instance.
91
- */
92
- async startChat(connectMessage, startChatOptions) {
93
- this.updatePersistedState({ agentsJoined: {}, lastAgentMessageID: null }, false);
94
- await this.ensureGenesys(false);
95
- const connectItem = connectMessage.output.generic.find(isConnectToAgent);
96
- const { preStartChatPayload } = startChatOptions;
97
- // Create an attribute with the session history key so the agent app can be loaded. Also add in any custom
98
- // attributes that may be in the pre-chat payload.
99
- const { sessionHistoryKey } = startChatOptions.agentAppInfo;
100
- const customAttributes = {
101
- ...preStartChatPayload?.customAttributes,
102
- wacSessionHistoryKey: sessionHistoryKey,
103
- };
104
- Genesys('command', 'Database.set', { messaging: { customAttributes } });
105
- // Send each of the default summary message texts to the agent.
106
- const messagesToAgent = getSummaryMessages(connectItem, 'Begin conversation');
107
- messagesToAgent.forEach(message => {
108
- Genesys('command', 'MessagingService.sendMessage', { message });
109
- });
110
- }
111
- /**
112
- * Handles an incoming MessagingService.messagesReceived event.
113
- */
114
- async handleMessagesReceived(event) {
115
- debugLog(`${PREFIX} MessagingService.messagesReceived`, event);
116
- const outbound = event.data.messages.filter((message) => message?.direction === 'Outbound');
117
- if (outbound.length) {
118
- this.callback.agentTyping(false);
119
- await asyncForEach(outbound, async (message) => this.handleOutboundMessage(message, true));
120
- }
121
- }
122
- /**
123
- * Handles a message.
124
- */
125
- async handleOutboundMessage(message, includeEvents) {
126
- // The agent info is on different properties depending on if the message came from the restored event or a live
127
- // message event.
128
- const agentInfo = message.channel?.from || message.from;
129
- const nickname = agentInfo?.nickname || agentInfo?.name || null;
130
- const profile_picture_url = agentInfo?.avatar || agentInfo?.image || null;
131
- const agentID = nickname || 'default-agent';
132
- const { isConnected } = this.serviceManager.store.getState().persistedToBrowserStorage.chatState.agentState;
133
- const persistedState = this.persistedState();
134
- if (!persistedState.agentsJoined[nickname] || !isConnected) {
135
- this.updatePersistedState({ agentsJoined: { [nickname]: true } });
136
- await this.callback.agentJoined({ id: agentID, nickname, profile_picture_url });
137
- }
138
- this.updatePersistedState({ lastAgentMessageID: message.id });
139
- if (message.type?.toLowerCase() === 'event') {
140
- if (includeEvents) {
141
- this.handleMessagesReceivedEvent(message);
142
- }
143
- }
144
- else if (message.text) {
145
- this.handleMessagesReceivedText(message, agentID);
146
- }
147
- else if (message.content?.length || message.files?.length) {
148
- this.handleFileAttachments(message, agentID);
149
- }
150
- }
151
- /**
152
- * Handles an event message. These include the co-browse requests.
153
- */
154
- async handleMessagesReceivedEvent(message) {
155
- asyncForEach(message.events, async (event) => {
156
- if (event.eventType === 'CoBrowse' && event.coBrowse?.type === 'OfferingExpired') {
157
- debugLog(`${PREFIX} The agent cancelled the co-browse request.`);
158
- await this.callback.screenShareEnded();
159
- }
160
- else if (event.eventType === 'CoBrowse' && event.coBrowse?.type === 'Offering') {
161
- debugLog(`${PREFIX} Requesting co-browse sharing from the user...`);
162
- const result = await this.callback.screenShareRequest();
163
- debugLog(`${PREFIX} Got result for the co-browse request: ${result}`);
164
- const { sessionId, sessionJoinToken } = event.coBrowse;
165
- const params = { joinCode: sessionJoinToken, sessionId };
166
- if (result === ScreenShareState.ACCEPTED) {
167
- const onSuccess = () => debugLog(`${PREFIX} Co-browse session successfully started`);
168
- const onError = (error) => consoleError(`${PREFIX} Error starting a co-browse session`, error);
169
- Genesys('command', 'CobrowseService.acceptSession', params, onSuccess, onError);
170
- }
171
- else {
172
- Genesys('command', 'CobrowseService.declineSession', params);
173
- }
174
- }
175
- });
176
- }
177
- /**
178
- * Handles a message with text in it.
179
- */
180
- async handleMessagesReceivedText(message, agentID) {
181
- await this.callback.sendMessageToUser(message.text, agentID);
182
- }
183
- /**
184
- * Handles a message with content in it. These would include file links.
185
- */
186
- async handleFileAttachments(message, agentID) {
187
- const files = this.getFileAttachments(message);
188
- const items = files.map(({ filename, url }) => assertType({
189
- response_type: InternalMessageResponseType.BUTTON,
190
- kind: ButtonItemKind.LINK,
191
- button_type: ButtonItemType.URL,
192
- url,
193
- label: filename,
194
- }));
195
- if (items.length) {
196
- const messageToUser = { id: null, output: { generic: items } };
197
- await this.callback.sendMessageToUser(messageToUser, agentID);
198
- }
199
- }
200
- /**
201
- * Extracts file download links from the given message.
202
- */
203
- getFileAttachments(message) {
204
- const files = [];
205
- // Files that come in on live messages.
206
- message.content
207
- ?.filter((content) => content?.attachment)
208
- .forEach(({ attachment }) => files.push({ filename: attachment.filename, url: attachment.url }));
209
- // Files that come in from a restored event.
210
- message.files?.forEach((file) => files.push({ filename: file.name, url: file.downloadUrl }));
211
- return files;
212
- }
213
- /**
214
- * Handles an incoming MessagingService.typingReceived event. This indicates that an agent is typing.
215
- */
216
- handleTypingReceived(event) {
217
- debugLog(`${PREFIX} MessagingService.typingReceived`, event);
218
- if (!isEmptyObject(this.persistedState().agentsJoined)) {
219
- if (this.agentTypingTimeout) {
220
- clearTimeout(this.agentTypingTimeout);
221
- }
222
- const isTyping = event.data?.typing?.type === 'On';
223
- this.callback.agentTyping(isTyping);
224
- // We're supposed to get a "timeout" event to tell us when the agent has stopped typing but that event seems
225
- // to be inconsistent and we don't always get it. So we're just going to use our own timeout so we don't get
226
- // stuck with an agent permanently typing.
227
- if (isTyping) {
228
- this.agentTypingTimeout = setTimeout(() => {
229
- this.callback.agentTyping(false);
230
- this.agentTypingTimeout = null;
231
- }, event.data?.typing?.duration || 5000);
232
- }
233
- }
234
- }
235
- /**
236
- * Handles an incoming MessagingService.handleTypingTimeout event. This is the timout for an agent typing.
237
- */
238
- handleTypingTimeout(event) {
239
- debugLog(`${PREFIX} MessagingService.handleTypingTimeout`, event);
240
- this.callback.agentTyping(false);
241
- }
242
- /**
243
- * Handles an incoming MessagingService.fileUploaded event.
244
- */
245
- async handleFileUploaded(event) {
246
- debugLog(`${PREFIX} MessagingService.fileUploaded`, event);
247
- // We have to send an actual message to Genesys in order to deliver the files.
248
- Genesys('command', 'MessagingService.sendMessage', {
249
- message: this.getIntlText('fileSharing_agentMessageText'),
250
- });
251
- this.callback.setFileUploadStatus(this.currentFileUploadID);
252
- }
253
- /**
254
- * Handles an incoming MessagingService.fileUploadError event.
255
- */
256
- handleFileUploadError(event) {
257
- consoleError(`${PREFIX} MessagingService.fileUploadError`, event);
258
- if (this.currentFileUploadID) {
259
- this.callback.setFileUploadStatus(this.currentFileUploadID, true, this.getIntlText('fileSharing_uploadFailed'));
260
- }
261
- }
262
- /**
263
- * Handles an incoming MessagingService.error event.
264
- */
265
- handleError(event) {
266
- consoleError(`${PREFIX} MessagingService.error`, event);
267
- if (this.currentFileUploadID) {
268
- const errorCode = event.data?.error?.body?.errorCode;
269
- const errorMessage = event.data?.error?.body?.errorMessage || this.getIntlText('fileSharing_uploadFailed');
270
- // See https://developer.genesys.cloud/commdigital/digital/webmessaging/websocketapi#error-codes
271
- switch (errorCode) {
272
- case 4001: // File type is not supported.
273
- case 4002: // File size is greater than 102400.
274
- case 4003: // Invalid file content.
275
- case 4004: // File name invalid.
276
- case 4005: // File name is too long.
277
- case 4008: // Attachment has expired.
278
- case 4010: // Attachment not successfully uploaded.
279
- this.callback.setFileUploadStatus(this.currentFileUploadID, true, errorMessage);
280
- break;
281
- }
282
- }
283
- }
284
- /**
285
- * Handles an incoming MessagingService.restored event. This occurs when the user has reconnected to an existing
286
- * session after reloading the page.
287
- */
288
- async handleRestored(event) {
289
- debugLog(`${PREFIX} MessagingService.restored`, event);
290
- const { lastAgentMessageID } = this.persistedState();
291
- debugLog(`${PREFIX} Last agent message: ${lastAgentMessageID}`);
292
- // First we need to see if the agent's last message is in the list. If not, we're just going to give up and
293
- // assume something is not right about the history instead of just potentially repeating the whole thing.
294
- if (lastAgentMessageID && event.data?.messages?.length) {
295
- const { messages } = event.data;
296
- const lastIndex = messages.findIndex((message) => message.id === lastAgentMessageID);
297
- if (lastIndex > 0) {
298
- // Go backwards from the last index and handle each message.
299
- for (let index = lastIndex - 1; index >= 0; index--) {
300
- const message = messages[index];
301
- if (message.messageType === 'outbound') {
302
- // eslint-disable-next-line no-await-in-loop
303
- await this.handleOutboundMessage(message, false);
304
- }
305
- }
306
- }
307
- }
308
- }
309
- /**
310
- * Handles an incoming MessagingService.offline event.
311
- */
312
- handleOffline(event) {
313
- debugLog(`${PREFIX} MessagingService.offline`, event);
314
- this.callback.setErrorStatus({ type: ErrorType.DISCONNECTED, isDisconnected: true });
315
- }
316
- /**
317
- * Handles an incoming MessagingService.reconnected event.
318
- */
319
- handleReconnected(event) {
320
- debugLog(`${PREFIX} MessagingService.reconnected`, event);
321
- this.callback.setErrorStatus({ type: ErrorType.DISCONNECTED, isDisconnected: false });
322
- }
323
- /**
324
- * Handles an incoming CobrowseService.sessionEnded event.
325
- */
326
- async handleCoBrowseEnded(event) {
327
- debugLog(`${PREFIX} CobrowseService.sessionEnded`, event);
328
- await this.callback.screenShareEnded();
329
- }
330
- /**
331
- * Tells the service desk to terminate the chat.
332
- */
333
- async endChat() {
334
- this.stopUserTypingInterval();
335
- this.updatePersistedState({ agentsJoined: {}, lastAgentMessageID: null }, false);
336
- }
337
- /**
338
- * Sends a message to the agent in the service desk.
339
- */
340
- async sendMessageToAgent(message, messageID, additionalData) {
341
- if (message.input.text) {
342
- Genesys('command', 'MessagingService.sendMessage', {
343
- message: message.input.text,
344
- });
345
- }
346
- if (additionalData.filesToUpload.length) {
347
- // If a file was provided, then upload it. The web chat service should guarantee we never get more than one.
348
- this.doFileUpload(additionalData.filesToUpload[0]);
349
- }
350
- }
351
- /**
352
- * Informs the service desk that the user has read all the messages that have been sent by the service desk.
353
- *
354
- * @returns Returns a Promise that resolves when the service desk has successfully handled the call.
355
- */
356
- async userReadMessages() {
357
- // Not supported in this integration.
358
- }
359
- /**
360
- * Tells the service desk if a user has started or stopped typing.
361
- */
362
- async userTyping(isTyping) {
363
- this.stopUserTypingInterval();
364
- if (isTyping) {
365
- Genesys('command', 'MessagingService.sendTyping');
366
- // Genesys seems to expect us to keep sending a typing indicator while a user is typing or the indicator
367
- // automatically stops after 5 seconds.
368
- this.userTypingInterval = window.setInterval(() => {
369
- Genesys('command', 'MessagingService.sendTyping');
370
- }, 2500);
371
- }
372
- }
373
- /**
374
- * Stops and clear the interval that is used to tell Genesys that the user is typing.
375
- */
376
- stopUserTypingInterval() {
377
- if (this.userTypingInterval) {
378
- clearInterval(this.userTypingInterval);
379
- this.userTypingInterval = null;
380
- }
381
- }
382
- /**
383
- * Checks if any agents are online and ready to communicate with the user.
384
- */
385
- async areAnyAgentsOnline(connectMessage) {
386
- // Genesys doesn't provide this information.
387
- return true;
388
- }
389
- /**
390
- * Indicates that the user has selected some files to be uploaded but that the user has not yet chosen to send
391
- * them to the agent. This method can use this as an opportunity to perform any early validation of the files in
392
- * order to display an error to the user. It should not actually upload the files at this point. If the user
393
- * chooses to send the files to the agent, they will be included later when {@link #sendMessageToAgent} is called.
394
- */
395
- filesSelectedForUpload(uploads) {
396
- uploads.forEach(upload => {
397
- if (upload.file.size > this.maxFileSizeKB * 1024) {
398
- const maxSize = `${this.maxFileSizeKB}KB`;
399
- const errorMessage = this.instance.getIntl().formatMessage({ id: 'fileSharing_fileTooLarge' }, { maxSize });
400
- this.callback.setFileUploadStatus(upload.id, true, errorMessage);
401
- }
402
- });
403
- }
404
- /**
405
- * Tells the service desk that the user has requested to stop sharing their screen.
406
- */
407
- async screenShareStop() {
408
- Genesys('command', 'CobrowseService.stopSession');
409
- }
410
- /**
411
- * Ensures that the Genesys script is loaded.
412
- */
413
- async ensureGenesys(isReconnecting) {
414
- if (!scriptPromise) {
415
- scriptPromise = this.installGenesys(isReconnecting);
416
- }
417
- return scriptPromise;
418
- }
419
- /**
420
- * This installs Genesys using their embed code.
421
- */
422
- async installGenesys(isReconnecting) {
423
- const { environment, deploymentID, scriptURL } = this.config;
424
- debugLog(`${PREFIX} Creating integration using config`, this.config);
425
- if (!this.persistedState()) {
426
- this.updatePersistedState({ agentsJoined: {}, lastAgentMessageID: null }, false);
427
- }
428
- else {
429
- debugLog(`${PREFIX} Retrieved previous state`, this.persistedState());
430
- }
431
- const config = { environment, deploymentId: deploymentID, debug: this.instance.getState().isDebugEnabled };
432
- // This code is a simplified version of the Genesys embed script and is required by their SDK.
433
- const windowObject = window;
434
- const propertyName = 'Genesys';
435
- windowObject._genesysJs = propertyName;
436
- windowObject[propertyName] = {
437
- t: new Date(),
438
- c: config,
439
- q: [],
440
- };
441
- await loadScript(scriptURL);
442
- Genesys = windowObject[propertyName];
443
- // Uncomment for debugging/development purposes.
444
- // this.addAllEvents();
445
- const serviceStartedPromise = new Promise((resolve, reject) => {
446
- function serviceStartedHandler(event) {
447
- debugLog(`${PREFIX} MessagingService.started`, event);
448
- resolve(!event?.data?.newSession);
449
- }
450
- Genesys('subscribe', 'MessagingService.started', serviceStartedHandler, reject);
451
- });
452
- // Subscribe to all the events that we will need to listen to.
453
- Genesys('subscribe', 'MessagingService.messagesReceived', (event) => this.handleMessagesReceived(event));
454
- Genesys('subscribe', 'MessagingService.typingReceived', (event) => this.handleTypingReceived(event));
455
- Genesys('subscribe', 'MessagingService.typingTimeout', (event) => this.handleTypingTimeout(event));
456
- Genesys('subscribe', 'MessagingService.fileUploaded', (event) => this.handleFileUploaded(event));
457
- Genesys('subscribe', 'MessagingService.fileUploadError', (event) => this.handleFileUploadError(event));
458
- Genesys('subscribe', 'MessagingService.error', (event) => this.handleError(event));
459
- Genesys('subscribe', 'MessagingService.reconnected', (event) => this.handleReconnected(event));
460
- Genesys('subscribe', 'MessagingService.offline', (event) => this.handleOffline(event));
461
- Genesys('subscribe', 'MessagingService.restored', (event) => this.handleRestored(event));
462
- Genesys('subscribe', 'CobrowseService.sessionEnded', (event) => this.handleCoBrowseEnded(event));
463
- // Load the configuration data for the deployment.
464
- await resolveOrTimeout(new Promise((resolve, reject) => {
465
- Genesys('registerPlugin', 'ConfigPlugin', (plugin) => {
466
- plugin
467
- .command('GenesysJS.configuration')
468
- .then((data) => {
469
- this.genesysConfig = data;
470
- debugLog(`${PREFIX} Received GenesysJS.configuration`, this.genesysConfig);
471
- resolve();
472
- })
473
- .catch(reject);
474
- });
475
- }), INIT_TIMEOUT_SECS * 1000, `The GenesysJS.configuration command failed to return a configuration after ${INIT_TIMEOUT_SECS} seconds.`);
476
- // Create the plugin that would be used when using user authentication.
477
- if (this.genesysConfig?.auth.enabled) {
478
- debugLog(`${PREFIX} Authentication is enabled`);
479
- Genesys('registerPlugin', 'AuthProvider', (authProvider) => {
480
- authProvider.registerCommand('getAuthCode', (event) => {
481
- debugLog(`${PREFIX} AuthProvider.getAuthCode`, event);
482
- this.eventBus.fire({ type: "agent:genesysMessenger:getAuthCode" /* BusEventType.GENESYS_MESSENGER_GET_AUTH_CODE */, genesysEvent: event }, this.instance);
483
- });
484
- authProvider.registerCommand('reAuthenticate', (event) => {
485
- debugLog(`${PREFIX} AuthProvider.reAuthenticate`, event);
486
- this.eventBus.fire({ type: "agent:genesysMessenger:reAuthenticate" /* BusEventType.GENESYS_MESSENGER_REAUTHENTICATE */, genesysEvent: event }, this.instance);
487
- });
488
- authProvider.subscribe('Auth.loggedOut', (event) => {
489
- debugLog(`${PREFIX} AuthProvider.loggedOut`, event);
490
- this.eventBus.fire({ type: "agent:genesysMessenger:loggedOut" /* BusEventType.GENESYS_MESSENGER_LOGGED_OUT */, genesysEvent: event }, this.instance);
491
- });
492
- authProvider.subscribe('Auth.authError', (error) => {
493
- debugLog(`${PREFIX} AuthProvider.authError`, error);
494
- this.eventBus.fire({ type: "agent:genesysMessenger:authError" /* BusEventType.GENESYS_MESSENGER_AUTH_ERROR */, genesysError: error }, this.instance);
495
- });
496
- // Tell Messenger that your plugin is ready (mandatory).
497
- authProvider.ready();
498
- // Make the AuthProvider instance available to the client.
499
- this.eventBus.fire({ type: "agent:genesysMessenger:AuthProvider" /* BusEventType.GENESYS_MESSENGER_AUTH_PROVIDER */, authProvider }, this.instance);
500
- });
501
- }
502
- // Wait for the messaging service to become ready before completing the initialization.
503
- await resolveOrTimeout(new Promise(resolve => {
504
- Genesys('subscribe', 'MessagingService.ready', (event) => {
505
- debugLog(`${PREFIX} MessagingService.ready`, event);
506
- resolve();
507
- });
508
- }), INIT_TIMEOUT_SECS * 1000, `The Genesys MessagingService failed to report ready after ${INIT_TIMEOUT_SECS} seconds.`);
509
- let isNewSession = false;
510
- if (isReconnecting) {
511
- // This event only fires if reconnecting to an existing session.
512
- isNewSession = await resolveOrTimeout(serviceStartedPromise, INIT_TIMEOUT_SECS * 1000, `The MessagingService.started event failed to fire after ${INIT_TIMEOUT_SECS} seconds.`);
513
- }
514
- // We have to look through the file upload modes to see if there are any files allowed. The docs suggest there
515
- // should only be one object here but the schema does use an array so let's just go through all the objects to
516
- // be safe. We'll collect up the unique set of mime types allowed and figure out the largest file size allowed.
517
- // The servers will still do their own validation.
518
- const mimeTypesSet = new Set();
519
- if (this.genesysConfig?.messenger?.fileUpload?.modes) {
520
- Object.values(this.genesysConfig.messenger.fileUpload.modes).forEach((mode) => {
521
- if (mode.maxFileSizeKB > 0) {
522
- this.maxFileSizeKB = Math.max(this.maxFileSizeKB, mode.maxFileSizeKB);
523
- }
524
- mode.fileTypes?.forEach((type) => mimeTypesSet.add(type));
525
- });
526
- }
527
- const allowedFileUploadTypes = Array.from(mimeTypesSet).join(',') || undefined;
528
- this.callback.updateCapabilities({ allowFileUploads: this.maxFileSizeKB > 0, allowedFileUploadTypes });
529
- return isNewSession;
530
- }
531
- /**
532
- * This will be called when the service desk is first initialized and it is determined that the user was previously
533
- * connected to an agent. This function should perform whatever steps are necessary to reconnect the user. Web chat
534
- * will assume the user is permitted to send messages and is connected to the same agent when this function returns.
535
- *
536
- * @returns true to indicate that the reconnect was successful.
537
- */
538
- async reconnect() {
539
- debugLog(`${PREFIX} Reconnecting to agent...`);
540
- return this.ensureGenesys(true);
541
- }
542
- // Old code to support debugging.
543
- addAllEvents() {
544
- this.addEvent('MessagingService.ready');
545
- this.addEvent('MessagingService.started');
546
- this.addEvent('MessagingService.messagesReceived');
547
- this.addEvent('MessagingService.uploading');
548
- this.addEvent('MessagingService.uploadApproved');
549
- this.addEvent('MessagingService.fileUploaded');
550
- this.addEvent('MessagingService.fileUploadError');
551
- this.addEvent('MessagingService.fileUploadCancelled');
552
- this.addEvent('MessagingService.fileReceived');
553
- this.addEvent('MessagingService.messagesUpdated');
554
- this.addEvent('MessagingService.fileDownloaded');
555
- this.addEvent('MessagingService.fileDownloadError');
556
- this.addEvent('MessagingService.fileDeleted');
557
- this.addEvent('MessagingService.oldMessages');
558
- this.addEvent('MessagingService.historyComplete');
559
- this.addEvent('MessagingService.typingReceived');
560
- this.addEvent('MessagingService.typingTimeout');
561
- this.addEvent('MessagingService.typingStarted');
562
- this.addEvent('MessagingService.restored');
563
- this.addEvent('MessagingService.sessionCleared');
564
- this.addEvent('MessagingService.offline');
565
- this.addEvent('MessagingService.reconnecting');
566
- this.addEvent('MessagingService.reconnected');
567
- this.addEvent('MessagingService.conversationDisconnected');
568
- this.addEvent('MessagingService.readOnlyConversation');
569
- this.addEvent('MessagingService.conversationReset');
570
- this.addEvent('MessagingService.error');
571
- }
572
- addEvent(eventName) {
573
- Genesys('subscribe', eventName, (...args) => {
574
- console.log(`${PREFIX} (All) ${eventName}`, args);
575
- });
576
- }
577
- }
578
-
579
- export { GenesysMessengerServiceDesk };
1
+ import{t as e,o as s,L as t,a0 as i,a2 as a,ak as n,ad as r}from"./messageUtils.js";import{r as o}from"./domUtils.js";import{h as d,a4 as g,i as c,c as l,a7 as h}from"./aiChatEntry2.js";import{aL as u}from"./humanAgentUtils.js";import{S as v}from"./ServiceDeskImpl.js";import"@lit/react";import"react";import"lit";import"lit/decorators.js";import"react-dom";const p="[GenesysMessengerServiceDesk]";let S,m;class y extends v{constructor(){super(...arguments),this.maxFileSizeKB=0,this.doFileUpload=async e=>{const s=new DataTransfer;s.items.add(e.file);this.currentFileUploadID=e.id,d(`${p} MessagingService.requestUpload`,e),m("command","MessagingService.requestUpload",{file:s.files},null,(()=>{this.callback.setFileUploadStatus(e.id,!0,this.getIntlText("fileSharing_uploadFailed"))}))}}async startChat(s,t){this.updatePersistedState({agentsJoined:{},lastAgentMessageID:null},!1),await this.ensureGenesys(!1);const i=s.output.generic.find(e),{preStartChatPayload:a}=t,{sessionHistoryKey:n}=t.agentAppInfo,r={...a?.customAttributes,wacSessionHistoryKey:n};m("command","Database.set",{messaging:{customAttributes:r}});u(i,"Begin conversation").forEach((e=>{m("command","MessagingService.sendMessage",{message:e})}))}async handleMessagesReceived(e){d(`${p} MessagingService.messagesReceived`,e);const t=e.data.messages.filter((e=>"Outbound"===e?.direction));t.length&&(this.callback.agentTyping(!1),await s(t,(async e=>this.handleOutboundMessage(e,!0))))}async handleOutboundMessage(e,s){const t=e.channel?.from||e.from,i=t?.nickname||t?.name||null,a=t?.avatar||t?.image||null,n=i||"default-agent",{isConnected:r}=this.serviceManager.store.getState().persistedToBrowserStorage.chatState.agentState;this.persistedState().agentsJoined[i]&&r||(this.updatePersistedState({agentsJoined:{[i]:!0}}),await this.callback.agentJoined({id:n,nickname:i,profile_picture_url:a})),this.updatePersistedState({lastAgentMessageID:e.id}),"event"===e.type?.toLowerCase()?s&&this.handleMessagesReceivedEvent(e):e.text?this.handleMessagesReceivedText(e,n):(e.content?.length||e.files?.length)&&this.handleFileAttachments(e,n)}async handleMessagesReceivedEvent(e){s(e.events,(async e=>{if("CoBrowse"===e.eventType&&"OfferingExpired"===e.coBrowse?.type)d(`${p} The agent cancelled the co-browse request.`),await this.callback.screenShareEnded();else if("CoBrowse"===e.eventType&&"Offering"===e.coBrowse?.type){d(`${p} Requesting co-browse sharing from the user...`);const s=await this.callback.screenShareRequest();d(`${p} Got result for the co-browse request: ${s}`);const{sessionId:t,sessionJoinToken:i}=e.coBrowse,a={joinCode:i,sessionId:t};if(s===r.ACCEPTED){m("command","CobrowseService.acceptSession",a,(()=>d(`${p} Co-browse session successfully started`)),(e=>l(`${p} Error starting a co-browse session`,e)))}else m("command","CobrowseService.declineSession",a)}}))}async handleMessagesReceivedText(e,s){await this.callback.sendMessageToUser(e.text,s)}async handleFileAttachments(e,s){const n=this.getFileAttachments(e).map((({filename:e,url:s})=>g({response_type:t.BUTTON,kind:i.LINK,button_type:a.URL,url:s,label:e})));if(n.length){const e={id:null,output:{generic:n}};await this.callback.sendMessageToUser(e,s)}}getFileAttachments(e){const s=[];return e.content?.filter((e=>e?.attachment)).forEach((({attachment:e})=>s.push({filename:e.filename,url:e.url}))),e.files?.forEach((e=>s.push({filename:e.name,url:e.downloadUrl}))),s}handleTypingReceived(e){if(d(`${p} MessagingService.typingReceived`,e),!c(this.persistedState().agentsJoined)){this.agentTypingTimeout&&clearTimeout(this.agentTypingTimeout);const s="On"===e.data?.typing?.type;this.callback.agentTyping(s),s&&(this.agentTypingTimeout=setTimeout((()=>{this.callback.agentTyping(!1),this.agentTypingTimeout=null}),e.data?.typing?.duration||5e3))}}handleTypingTimeout(e){d(`${p} MessagingService.handleTypingTimeout`,e),this.callback.agentTyping(!1)}async handleFileUploaded(e){d(`${p} MessagingService.fileUploaded`,e),m("command","MessagingService.sendMessage",{message:this.getIntlText("fileSharing_agentMessageText")}),this.callback.setFileUploadStatus(this.currentFileUploadID)}handleFileUploadError(e){l(`${p} MessagingService.fileUploadError`,e),this.currentFileUploadID&&this.callback.setFileUploadStatus(this.currentFileUploadID,!0,this.getIntlText("fileSharing_uploadFailed"))}handleError(e){if(l(`${p} MessagingService.error`,e),this.currentFileUploadID){const s=e.data?.error?.body?.errorCode,t=e.data?.error?.body?.errorMessage||this.getIntlText("fileSharing_uploadFailed");switch(s){case 4001:case 4002:case 4003:case 4004:case 4005:case 4008:case 4010:this.callback.setFileUploadStatus(this.currentFileUploadID,!0,t)}}}async handleRestored(e){d(`${p} MessagingService.restored`,e);const{lastAgentMessageID:s}=this.persistedState();if(d(`${p} Last agent message: ${s}`),s&&e.data?.messages?.length){const{messages:t}=e.data,i=t.findIndex((e=>e.id===s));if(i>0)for(let e=i-1;e>=0;e--){const s=t[e];"outbound"===s.messageType&&await this.handleOutboundMessage(s,!1)}}}handleOffline(e){d(`${p} MessagingService.offline`,e),this.callback.setErrorStatus({type:n.DISCONNECTED,isDisconnected:!0})}handleReconnected(e){d(`${p} MessagingService.reconnected`,e),this.callback.setErrorStatus({type:n.DISCONNECTED,isDisconnected:!1})}async handleCoBrowseEnded(e){d(`${p} CobrowseService.sessionEnded`,e),await this.callback.screenShareEnded()}async endChat(){this.stopUserTypingInterval(),this.updatePersistedState({agentsJoined:{},lastAgentMessageID:null},!1)}async sendMessageToAgent(e,s,t){e.input.text&&m("command","MessagingService.sendMessage",{message:e.input.text}),t.filesToUpload.length&&this.doFileUpload(t.filesToUpload[0])}async userReadMessages(){}async userTyping(e){this.stopUserTypingInterval(),e&&(m("command","MessagingService.sendTyping"),this.userTypingInterval=window.setInterval((()=>{m("command","MessagingService.sendTyping")}),2500))}stopUserTypingInterval(){this.userTypingInterval&&(clearInterval(this.userTypingInterval),this.userTypingInterval=null)}async areAnyAgentsOnline(e){return!0}filesSelectedForUpload(e){e.forEach((e=>{if(e.file.size>1024*this.maxFileSizeKB){const s=`${this.maxFileSizeKB}KB`,t=this.instance.getIntl().formatMessage({id:"fileSharing_fileTooLarge"},{maxSize:s});this.callback.setFileUploadStatus(e.id,!0,t)}}))}async screenShareStop(){m("command","CobrowseService.stopSession")}async ensureGenesys(e){return S||(S=this.installGenesys(e)),S}async installGenesys(e){const{environment:s,deploymentID:t,scriptURL:i}=this.config;d(`${p} Creating integration using config`,this.config),this.persistedState()?d(`${p} Retrieved previous state`,this.persistedState()):this.updatePersistedState({agentsJoined:{},lastAgentMessageID:null},!1);const a={environment:s,deploymentId:t,debug:this.instance.getState().isDebugEnabled},n=window,r="Genesys";n._genesysJs=r,n[r]={t:new Date,c:a,q:[]},await o(i),m=n[r];const g=new Promise(((e,s)=>{m("subscribe","MessagingService.started",(function(s){d(`${p} MessagingService.started`,s),e(!s?.data?.newSession)}),s)}));m("subscribe","MessagingService.messagesReceived",(e=>this.handleMessagesReceived(e))),m("subscribe","MessagingService.typingReceived",(e=>this.handleTypingReceived(e))),m("subscribe","MessagingService.typingTimeout",(e=>this.handleTypingTimeout(e))),m("subscribe","MessagingService.fileUploaded",(e=>this.handleFileUploaded(e))),m("subscribe","MessagingService.fileUploadError",(e=>this.handleFileUploadError(e))),m("subscribe","MessagingService.error",(e=>this.handleError(e))),m("subscribe","MessagingService.reconnected",(e=>this.handleReconnected(e))),m("subscribe","MessagingService.offline",(e=>this.handleOffline(e))),m("subscribe","MessagingService.restored",(e=>this.handleRestored(e))),m("subscribe","CobrowseService.sessionEnded",(e=>this.handleCoBrowseEnded(e))),await h(new Promise(((e,s)=>{m("registerPlugin","ConfigPlugin",(t=>{t.command("GenesysJS.configuration").then((s=>{this.genesysConfig=s,d(`${p} Received GenesysJS.configuration`,this.genesysConfig),e()})).catch(s)}))})),1e4,"The GenesysJS.configuration command failed to return a configuration after 10 seconds."),this.genesysConfig?.auth.enabled&&(d(`${p} Authentication is enabled`),m("registerPlugin","AuthProvider",(e=>{e.registerCommand("getAuthCode",(e=>{d(`${p} AuthProvider.getAuthCode`,e),this.eventBus.fire({type:"agent:genesysMessenger:getAuthCode",genesysEvent:e},this.instance)})),e.registerCommand("reAuthenticate",(e=>{d(`${p} AuthProvider.reAuthenticate`,e),this.eventBus.fire({type:"agent:genesysMessenger:reAuthenticate",genesysEvent:e},this.instance)})),e.subscribe("Auth.loggedOut",(e=>{d(`${p} AuthProvider.loggedOut`,e),this.eventBus.fire({type:"agent:genesysMessenger:loggedOut",genesysEvent:e},this.instance)})),e.subscribe("Auth.authError",(e=>{d(`${p} AuthProvider.authError`,e),this.eventBus.fire({type:"agent:genesysMessenger:authError",genesysError:e},this.instance)})),e.ready(),this.eventBus.fire({type:"agent:genesysMessenger:AuthProvider",authProvider:e},this.instance)}))),await h(new Promise((e=>{m("subscribe","MessagingService.ready",(s=>{d(`${p} MessagingService.ready`,s),e()}))})),1e4,"The Genesys MessagingService failed to report ready after 10 seconds.");let c=!1;e&&(c=await h(g,1e4,"The MessagingService.started event failed to fire after 10 seconds."));const l=new Set;this.genesysConfig?.messenger?.fileUpload?.modes&&Object.values(this.genesysConfig.messenger.fileUpload.modes).forEach((e=>{e.maxFileSizeKB>0&&(this.maxFileSizeKB=Math.max(this.maxFileSizeKB,e.maxFileSizeKB)),e.fileTypes?.forEach((e=>l.add(e)))}));const u=Array.from(l).join(",")||void 0;return this.callback.updateCapabilities({allowFileUploads:this.maxFileSizeKB>0,allowedFileUploadTypes:u}),c}async reconnect(){return d(`${p} Reconnecting to agent...`),this.ensureGenesys(!0)}addAllEvents(){this.addEvent("MessagingService.ready"),this.addEvent("MessagingService.started"),this.addEvent("MessagingService.messagesReceived"),this.addEvent("MessagingService.uploading"),this.addEvent("MessagingService.uploadApproved"),this.addEvent("MessagingService.fileUploaded"),this.addEvent("MessagingService.fileUploadError"),this.addEvent("MessagingService.fileUploadCancelled"),this.addEvent("MessagingService.fileReceived"),this.addEvent("MessagingService.messagesUpdated"),this.addEvent("MessagingService.fileDownloaded"),this.addEvent("MessagingService.fileDownloadError"),this.addEvent("MessagingService.fileDeleted"),this.addEvent("MessagingService.oldMessages"),this.addEvent("MessagingService.historyComplete"),this.addEvent("MessagingService.typingReceived"),this.addEvent("MessagingService.typingTimeout"),this.addEvent("MessagingService.typingStarted"),this.addEvent("MessagingService.restored"),this.addEvent("MessagingService.sessionCleared"),this.addEvent("MessagingService.offline"),this.addEvent("MessagingService.reconnecting"),this.addEvent("MessagingService.reconnected"),this.addEvent("MessagingService.conversationDisconnected"),this.addEvent("MessagingService.readOnlyConversation"),this.addEvent("MessagingService.conversationReset"),this.addEvent("MessagingService.error")}addEvent(e){m("subscribe",e,((...s)=>{console.log(`${p} (All) ${e}`,s)}))}}export{y as GenesysMessengerServiceDesk};