@microsoft/omnichannel-chat-widget 1.0.5 → 1.0.6-main.0c19ff3

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 (41) hide show
  1. package/lib/cjs/common/Constants.js +1 -0
  2. package/lib/cjs/common/telemetry/TelemetryHelper.js +16 -15
  3. package/lib/cjs/common/utils.js +17 -2
  4. package/lib/cjs/components/footerstateful/FooterStateful.js +2 -2
  5. package/lib/cjs/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.js +21 -12
  6. package/lib/cjs/components/footerstateful/downloadtranscriptstateful/interfaces/IWebChatTranscriptConfig.js +1 -0
  7. package/lib/cjs/components/livechatwidget/common/createDownloadTranscriptProps.js +27 -0
  8. package/lib/cjs/components/livechatwidget/common/defaultProps/dummyDefaultProps.js +9 -1
  9. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +36 -28
  10. package/lib/cjs/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +6 -0
  11. package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +21 -11
  12. package/lib/cjs/components/webchatcontainerstateful/common/defaultStyles/defaultAdaptiveCardStyles.js +3 -1
  13. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultSentMessageAnchorStyles.js +10 -0
  14. package/lib/cjs/plugins/createChatTranscript.js +548 -0
  15. package/lib/esm/common/Constants.js +1 -0
  16. package/lib/esm/common/telemetry/TelemetryHelper.js +16 -15
  17. package/lib/esm/common/utils.js +15 -1
  18. package/lib/esm/components/footerstateful/FooterStateful.js +2 -2
  19. package/lib/esm/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.js +22 -13
  20. package/lib/esm/components/footerstateful/downloadtranscriptstateful/interfaces/IWebChatTranscriptConfig.js +1 -0
  21. package/lib/esm/components/livechatwidget/common/createDownloadTranscriptProps.js +20 -0
  22. package/lib/esm/components/livechatwidget/common/defaultProps/dummyDefaultProps.js +9 -1
  23. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +36 -28
  24. package/lib/esm/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +6 -0
  25. package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +21 -11
  26. package/lib/esm/components/webchatcontainerstateful/common/defaultStyles/defaultAdaptiveCardStyles.js +3 -1
  27. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultSentMessageAnchorStyles.js +3 -0
  28. package/lib/esm/plugins/createChatTranscript.js +543 -0
  29. package/lib/types/common/Constants.d.ts +1 -0
  30. package/lib/types/common/telemetry/definitions/Contracts.d.ts +1 -0
  31. package/lib/types/common/utils.d.ts +1 -0
  32. package/lib/types/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.d.ts +2 -1
  33. package/lib/types/components/footerstateful/downloadtranscriptstateful/interfaces/IDownloadTranscriptProps.d.ts +5 -0
  34. package/lib/types/components/footerstateful/downloadtranscriptstateful/interfaces/IWebChatTranscriptConfig.d.ts +13 -0
  35. package/lib/types/components/livechatwidget/common/createDownloadTranscriptProps.d.ts +24 -0
  36. package/lib/types/components/webchatcontainerstateful/interfaces/IAdaptiveCardStyles.d.ts +2 -0
  37. package/lib/types/components/webchatcontainerstateful/interfaces/IRenderingMiddlewareProps.d.ts +1 -0
  38. package/lib/types/components/webchatcontainerstateful/interfaces/IWebChatProps.d.ts +1 -0
  39. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultSentMessageAnchorStyles.d.ts +2 -0
  40. package/lib/types/plugins/createChatTranscript.d.ts +2 -0
  41. package/package.json +2 -2
@@ -0,0 +1,543 @@
1
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
3
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
4
+ /* eslint-disable no-useless-escape */
5
+
6
+ import { createFileAndDownload } from "../common/utils";
7
+ class TranscriptHTMLBuilder {
8
+ // eslint-disable-line @typescript-eslint/no-explicit-any
9
+
10
+ constructor(options) {
11
+ var _this$options, _this$options2, _this$options3, _this$options4, _this$options5, _this$options6, _this$options7, _this$options8, _this$options9, _this$options10, _this$options11;
12
+ _defineProperty(this, "options", void 0);
13
+ _defineProperty(this, "pageTitle", "Customer Transcript");
14
+ _defineProperty(this, "attachmentMessage", "The following attachment was uploaded during the conversation: ");
15
+ _defineProperty(this, "networkOnlineMessage", "Connection restored. Please refresh the page");
16
+ _defineProperty(this, "networkOfflineMessage", "Network Error. Please make sure you are connected to the internet.");
17
+ _defineProperty(this, "transcriptBackgroundColor", "#FFF");
18
+ _defineProperty(this, "agentAvatarBackgroundColor", "#E8E8E8");
19
+ _defineProperty(this, "agentAvatarFontColor", "#000");
20
+ _defineProperty(this, "customerAvatarBackgroundColor", "#2266E3");
21
+ _defineProperty(this, "customerAvatarFontColor", "#FFF");
22
+ _defineProperty(this, "disableMarkdownMessageFormatting", false);
23
+ _defineProperty(this, "disableNewLineMarkdownSupport", false);
24
+ // eslint-disable-line @typescript-eslint/no-explicit-any
25
+ this.options = options;
26
+ if (!this.options || !this.options.messages) {
27
+ this.options.messages = [];
28
+ }
29
+ if ((_this$options = this.options) !== null && _this$options !== void 0 && _this$options.pageTitle) {
30
+ this.pageTitle = this.options.pageTitle;
31
+ }
32
+ if ((_this$options2 = this.options) !== null && _this$options2 !== void 0 && _this$options2.attachmentMessage) {
33
+ this.attachmentMessage = this.options.attachmentMessage;
34
+ }
35
+ if ((_this$options3 = this.options) !== null && _this$options3 !== void 0 && _this$options3.networkOnlineMessage) {
36
+ this.networkOnlineMessage = this.options.networkOnlineMessage;
37
+ }
38
+ if ((_this$options4 = this.options) !== null && _this$options4 !== void 0 && _this$options4.networkOfflineMessage) {
39
+ this.networkOfflineMessage = this.options.networkOfflineMessage;
40
+ }
41
+ if ((_this$options5 = this.options) !== null && _this$options5 !== void 0 && _this$options5.transcriptBackgroundColor) {
42
+ this.transcriptBackgroundColor = this.options.transcriptBackgroundColor;
43
+ }
44
+ if ((_this$options6 = this.options) !== null && _this$options6 !== void 0 && _this$options6.agentAvatarBackgroundColor) {
45
+ this.agentAvatarBackgroundColor = this.options.agentAvatarBackgroundColor;
46
+ }
47
+ if ((_this$options7 = this.options) !== null && _this$options7 !== void 0 && _this$options7.agentAvatarFontColor) {
48
+ this.agentAvatarFontColor = this.options.agentAvatarFontColor;
49
+ }
50
+ if ((_this$options8 = this.options) !== null && _this$options8 !== void 0 && _this$options8.customerAvatarBackgroundColor) {
51
+ this.customerAvatarBackgroundColor = this.options.customerAvatarBackgroundColor;
52
+ }
53
+ if ((_this$options9 = this.options) !== null && _this$options9 !== void 0 && _this$options9.customerAvatarFontColor) {
54
+ this.customerAvatarFontColor = this.options.customerAvatarFontColor;
55
+ }
56
+ if ((_this$options10 = this.options) !== null && _this$options10 !== void 0 && _this$options10.disableMarkdownMessageFormatting) {
57
+ this.disableMarkdownMessageFormatting = this.options.disableMarkdownMessageFormatting;
58
+ }
59
+ if ((_this$options11 = this.options) !== null && _this$options11 !== void 0 && _this$options11.disableNewLineMarkdownSupport) {
60
+ this.disableNewLineMarkdownSupport = this.options.disableNewLineMarkdownSupport;
61
+ }
62
+ }
63
+ createTitleElement() {
64
+ const htmlData = `<title> ${this.pageTitle} </title>`;
65
+ return htmlData;
66
+ }
67
+ createExternalScriptElements() {
68
+ const htmlData = `
69
+ <script src="https://cdn.botframework.com/botframework-webchat/4.15.7/webchat.js"><\/script>
70
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.8.0/rxjs.umd.min.js" integrity="sha512-v0/YVjBcbjLN6scjmmJN+h86koeB7JhY4/2YeyA5l+rTdtKLv0VbDBNJ32rxJpsaW1QGMd1Z16lsLOSGI38Rbg==" crossorigin="anonymous" referrerpolicy="no-referrer"><\/script>
71
+ <script src="https://unpkg.com/react@18.2.0/umd/react.production.min.js"><\/script>
72
+ <script src="https://unpkg.com/react-dom@18.2.0/umd/react-dom.production.min.js"><\/script>
73
+ <script src="https://cdn.jsdelivr.net/npm/markdown-it@13.0.1/dist/markdown-it.min.js" integrity="sha256-hNyljag6giCsjv/yKmxK8/VeHzvMDvc5u8AzmRvm1BI=" crossorigin="anonymous"><\/script>
74
+ `;
75
+ return htmlData;
76
+ }
77
+ createHeadElement() {
78
+ const htmlData = `
79
+ <head>
80
+ ${this.createTitleElement()}
81
+ ${this.createExternalScriptElements()}
82
+ <script>
83
+ function shareObservable(observable) {
84
+ let observers = [];
85
+ let subscription;
86
+
87
+ return new Observable(observer => {
88
+ if (!subscription) {
89
+ subscription = observable.subscribe({
90
+ complete() {
91
+ observers.forEach(observer => observer.complete());
92
+ },
93
+ error(err) {
94
+ observers.forEach(observer => observer.error(err));
95
+ },
96
+ next(value) {
97
+ observers.forEach(observer => observer.next(value));
98
+ }
99
+ });
100
+ }
101
+
102
+ observers.push(observer);
103
+
104
+ return () => {
105
+ observers = observers.filter(o => o !== observer);
106
+
107
+ if (!observers.length) {
108
+ subscription.unsubscribe();
109
+ subscription = null;
110
+ }
111
+ };
112
+ });
113
+ }
114
+ <\/script>
115
+ <script>
116
+ const messages = ${JSON.stringify(this.options.messages)};
117
+ const disableMarkdownMessageFormatting = ${this.disableMarkdownMessageFormatting};
118
+ const disableNewLineMarkdownSupport = ${this.disableNewLineMarkdownSupport};
119
+ <\/script>
120
+ <script>
121
+ class Translator {
122
+ static convertTranscriptMessageToActivity(message) {
123
+ const {created, isControlMessage, content, tags, from, attachments, amsMetadata, amsReferences} = message;
124
+ const activity = {
125
+ from: {
126
+ role: 'bot'
127
+ },
128
+ type: 'message'
129
+ };
130
+
131
+ // Ignore control messages
132
+ if (isControlMessage) {
133
+ return false;
134
+ }
135
+
136
+ if (tags) {
137
+ const formattedTags = tags.split(',');
138
+
139
+ // Ignore system message
140
+ if (formattedTags.includes('system')) {
141
+ return false;
142
+ }
143
+
144
+ // Ignore hidden message
145
+ if (formattedTags.includes('Hidden')) {
146
+ return false;
147
+ }
148
+ }
149
+
150
+ // Add C1 user display name
151
+ if (from && from.user && from.user.displayName) {
152
+ activity.from.name = from.user.displayName;
153
+ }
154
+
155
+ // Add C2 user display name
156
+ if (from && from.application && from.application.displayName && from.application.displayName === 'Customer') {
157
+ activity.from = {
158
+ role: 'user',
159
+ name: from.application.displayName
160
+ };
161
+ }
162
+
163
+ // Attachments
164
+ if (amsReferences && amsMetadata) {
165
+ const metadata = JSON.parse(amsMetadata);
166
+ const { fileName } = metadata[0];
167
+ const text = \`${this.attachmentMessage}\${fileName}\`;
168
+
169
+ if (message.attachments && message.attachments.length > 0 && message.contentUrl) {
170
+ activity.attachments = message.attachments;
171
+ activity.attachments[0].contentUrl = message.contentUrl;
172
+ activity.attachments[0].thumbnailUrl = message.contentUrl;
173
+ };
174
+
175
+ return {
176
+ ...activity,
177
+ text,
178
+ timestamp: created
179
+ }
180
+ }
181
+
182
+ // Message
183
+ if (content) {
184
+ // Adaptive card formatting
185
+ if (content.includes('"text"') && content.includes('"attachments"') && content.includes('"suggestedActions"')) {
186
+ try {
187
+ const partialActivity = JSON.parse(content);
188
+ return {
189
+ ...activity,
190
+ ...partialActivity,
191
+ timestamp: created
192
+ };
193
+ } catch {
194
+
195
+ }
196
+ }
197
+ }
198
+
199
+ return {
200
+ ...activity,
201
+ text: content,
202
+ timestamp: created
203
+ };
204
+ }
205
+ }
206
+ <\/script>
207
+ <script>
208
+ class TranscriptAdapter {
209
+ constructor() {
210
+ this.connectionStatus$ = new window.rxjs.BehaviorSubject(0); // Uninitialized
211
+ this.activity$ = shareObservable(new Observable((observer) => {
212
+ this.activityObserver = observer;
213
+
214
+ this.connectionStatus$.next(1); // Connecting
215
+ this.connectionStatus$.next(2); // Online
216
+
217
+ // Retrieve messages
218
+ if (messages) {
219
+ setTimeout(() => { // setTimeout is needed due to some WebChat issues
220
+ messages.map((message) => {
221
+ this.activityObserver.next({
222
+ ...Translator.convertTranscriptMessageToActivity(message),
223
+ type: 'message'
224
+ });
225
+ });
226
+ }, 1);
227
+ }
228
+ }));
229
+ }
230
+ }
231
+ <\/script>
232
+ <style>
233
+ body {
234
+ margin: 0;
235
+ }
236
+
237
+ .message-name {
238
+ font-family: Segoe UI,SegoeUI,Helvetica Neue,Helvetica,Arial,sans-serif;
239
+ font-weight: 700;
240
+ font-size: 10px;
241
+ }
242
+
243
+ .message-timestamp {
244
+ font-family: Segoe UI,SegoeUI,Helvetica Neue,Helvetica,Arial,sans-serif;
245
+ font-weight: 500;
246
+ font-size: 10px;
247
+ }
248
+
249
+ .avatar {
250
+ width: 40px;
251
+ height: 40px;
252
+ border-radius: 50%;
253
+ text-align: center;
254
+ }
255
+
256
+ .avatar--bot {
257
+ background-color: ${this.agentAvatarBackgroundColor};
258
+ }
259
+
260
+ .avatar--user {
261
+ background-color: ${this.customerAvatarBackgroundColor};
262
+ }
263
+
264
+ .avatar > p {
265
+ font-weight: 600;
266
+ text-align: center;
267
+ line-height: 0.5;
268
+ font-family: "Segoe UI", Arial, sans-serif;
269
+ }
270
+
271
+ .avatar--bot > p {
272
+ color: ${this.agentAvatarFontColor};
273
+ }
274
+
275
+ .avatar--user > p {
276
+ color: ${this.customerAvatarFontColor};
277
+ }
278
+
279
+ .webchat__bubble__content>div.ms_lcw_webchat_adaptive_card {
280
+ background-color: #FFF;
281
+ }
282
+
283
+ div[class="ac-textBlock"] {
284
+ color: #000 !important;
285
+ }
286
+
287
+ .ms_lcw_webchat_received_message a:link, .ms_lcw_webchat_received_message a:visited, .ms_lcw_webchat_received_message a:hover, .ms_lcw_webchat_received_message a:active {
288
+ color: #FFF;
289
+ }
290
+ <\/style>
291
+ </head>
292
+ `;
293
+ return htmlData;
294
+ }
295
+ createBodyElement() {
296
+ const htmlData = `
297
+ <body>
298
+ <script>
299
+ if (!navigator.onLine) {
300
+ const offlineText = \`${this.networkOfflineMessage}\`;
301
+ document.body.innerHTML = offlineText;
302
+ }
303
+
304
+ window.addEventListener("online", () => {
305
+ document.body.innerHTML = \`${this.networkOnlineMessage} <button onclick="window.location.reload()"> Refresh </button>\`;
306
+ });
307
+ <\/script>
308
+ <div id="transcript"></div>
309
+ <script>
310
+ const getIconText = (text) => {
311
+ if (text) {
312
+ const initials = text.split(/\\s/).reduce((response, word) => response += word.slice(0, 1), '');
313
+ if (initials.length > 1) {
314
+ return initials.substring(0, 2).toUpperCase();
315
+ } else {
316
+ return text.substring(0, 2).toUpperCase();
317
+ }
318
+ }
319
+
320
+ return "";
321
+ }
322
+
323
+ const activityMiddleware = () => (next) => (...args) => {
324
+ const [card] = args;
325
+
326
+ if (card.activity) {
327
+ if (card.activity.from && card.activity.from.role === "channel") {
328
+ return () => false;
329
+ }
330
+
331
+ // Incoming text message
332
+ if (card.activity.text && card.activity.from && card.activity.from.role !== "user") {
333
+ return (...renderArgs) => (React.createElement(
334
+ 'div',
335
+ {className: 'ms_lcw_webchat_received_message'},
336
+ next(...args)(...renderArgs)
337
+ ))
338
+ }
339
+ }
340
+
341
+ return next(...args);
342
+ };
343
+
344
+ const activityStatusMiddleware = () => (next) => (...args) => {
345
+ const [card] = args;
346
+ const {activity} = card;
347
+
348
+ if (activity) {
349
+ const {from, timestamp} = activity;
350
+
351
+ const nameElement = React.createElement(
352
+ 'span',
353
+ {className: 'message-name'},
354
+ from.name
355
+ );
356
+
357
+ const formattedDate = new Date(timestamp);
358
+ const formattedTimeString = formattedDate.toLocaleTimeString("en-us", { year: "numeric", month:"numeric", day:"numeric", hour: "2-digit", minute: "2-digit"});
359
+
360
+ const timestampElement = React.createElement(
361
+ 'span',
362
+ {className: 'message-timestamp'},
363
+ formattedTimeString
364
+ );
365
+
366
+ return from.name && timestamp && React.createElement('span', null, nameElement, ' - ', timestampElement)
367
+ }
368
+
369
+ return next(...args);
370
+ };
371
+
372
+ const avatarMiddleware = () => (next) => (...args) => {
373
+ const [card] = args;
374
+ const {fromUser, activity} = card;
375
+ const initials = getIconText(activity.from.name);
376
+
377
+ const avatarElement = React.createElement(
378
+ "div",
379
+ {className: fromUser? "avatar avatar--user": "avatar avatar--bot"},
380
+ React.createElement(
381
+ "p",
382
+ null,
383
+ \`\${initials}\`
384
+ )
385
+ );
386
+
387
+ return avatarElement;
388
+ }
389
+
390
+ const attachmentMiddleware = () => (next) => (...args) => {
391
+ const [card] = args;
392
+ const {activity} = card;
393
+
394
+ if (activity) {
395
+ const { activity: { attachments }, attachment } = card;
396
+
397
+ // No attachment
398
+ if (!attachments || !attachments.length || !attachment) {
399
+ return next(...args);
400
+ }
401
+
402
+ let { content, contentType } = attachment || { content: "", contentType: "" };
403
+
404
+ // Adaptive card
405
+ if (contentType.startsWith("application/vnd.microsoft.card")) {
406
+ const adaptiveCardElement = React.createElement(
407
+ "div",
408
+ {className: 'ms_lcw_webchat_adaptive_card'},
409
+ next(...args)
410
+ );
411
+
412
+ return adaptiveCardElement;
413
+ }
414
+ }
415
+
416
+ return next(...args);
417
+ }
418
+
419
+ const createMarkdown = (disableMarkdownMessageFormatting, disableNewLineMarkdownSupport) => {
420
+ let markdown;
421
+ if (!disableMarkdownMessageFormatting) {
422
+ markdown = new window.markdownit(
423
+ "default",
424
+ {
425
+ html: true,
426
+ linkify: true,
427
+ breaks: (!disableNewLineMarkdownSupport)
428
+ }
429
+ );
430
+ } else {
431
+ markdown = new window.markdownit(
432
+ "zero",
433
+ {
434
+ html: true,
435
+ linkify: true,
436
+ breaks: (!disableNewLineMarkdownSupport)
437
+ }
438
+ );
439
+
440
+ markdown.enable([
441
+ "entity",
442
+ "linkify",
443
+ "html_block",
444
+ "html_inline",
445
+ "newline"
446
+ ]);
447
+ }
448
+
449
+ return markdown;
450
+ };
451
+
452
+ const markdown = createMarkdown(disableMarkdownMessageFormatting, disableNewLineMarkdownSupport);
453
+ const renderMarkdown = (text) => {
454
+ const render = disableNewLineMarkdownSupport? markdown.renderInline.bind(markdown): markdown.render.bind(markdown);
455
+ text = render(text);
456
+ return text;
457
+ };
458
+
459
+ const adapter = new TranscriptAdapter();
460
+ const styleOptions = {
461
+ hideSendBox: true,
462
+ backgroundColor: '${this.transcriptBackgroundColor}',
463
+ bubbleBackground: '${this.agentAvatarBackgroundColor}',
464
+ bubbleTextColor: '${this.agentAvatarFontColor}',
465
+ bubbleBorderRadius: 12,
466
+ bubbleNubSize: 1,
467
+ bubbleFromUserBackground: '${this.customerAvatarBackgroundColor}',
468
+ bubbleFromUserTextColor: '${this.customerAvatarFontColor}',
469
+ bubbleFromUserBorderRadius: 12,
470
+ bubbleFromUserNubSize: 1,
471
+ botAvatarInitials: 'C1',
472
+ userAvatarInitials: 'C2'
473
+ };
474
+
475
+ window.WebChat.renderWebChat({
476
+ directLine: adapter,
477
+ styleOptions,
478
+ activityMiddleware,
479
+ activityStatusMiddleware,
480
+ avatarMiddleware,
481
+ attachmentMiddleware,
482
+ renderMarkdown
483
+ },
484
+ document.getElementById('transcript'));
485
+ <\/script>
486
+ </body>
487
+ `;
488
+ return htmlData;
489
+ }
490
+ createHTML() {
491
+ const htmlData = `
492
+ <html>
493
+ ${this.createHeadElement()}
494
+ ${this.createBodyElement()}
495
+ </html>
496
+ `;
497
+ return htmlData;
498
+ }
499
+ }
500
+ const createChatTranscript = async function (transcript, chatSDK) {
501
+ let renderAttachments = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
502
+ let transcriptOptions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
503
+ // eslint-disable-line @typescript-eslint/no-explicit-any
504
+ const transcriptMessages = JSON.parse(transcript);
505
+ const convertBlobToBase64 = async blob => {
506
+ return new Promise(resolve => {
507
+ const reader = new FileReader();
508
+ reader.onloadend = () => resolve(reader.result);
509
+ reader.readAsDataURL(blob);
510
+ });
511
+ };
512
+ let messages = transcriptMessages;
513
+ if (renderAttachments) {
514
+ messages = await Promise.all(transcriptMessages.map(async message => {
515
+ // eslint-disable-line @typescript-eslint/no-explicit-any
516
+ const {
517
+ amsReferences,
518
+ amsMetadata
519
+ } = message;
520
+ if (amsReferences && amsMetadata) {
521
+ const references = JSON.parse(amsReferences);
522
+ const metadata = JSON.parse(amsMetadata);
523
+ const fileMetadata = {
524
+ id: references[0],
525
+ type: metadata[0].contentType
526
+ };
527
+ const blob = await chatSDK.downloadFileAttachment(fileMetadata);
528
+ const base64 = await convertBlobToBase64(blob);
529
+ message.contentUrl = base64;
530
+ }
531
+ return message;
532
+ }));
533
+ }
534
+ const options = {
535
+ ...transcriptOptions,
536
+ messages
537
+ };
538
+ const htmlBuilder = new TranscriptHTMLBuilder(options);
539
+ const text = htmlBuilder.createHTML();
540
+ const fileName = `${transcriptOptions.fileName || "transcript"}.html`;
541
+ createFileAndDownload(fileName, text, "text/html");
542
+ };
543
+ export default createChatTranscript;
@@ -127,6 +127,7 @@ export declare class HtmlAttributeNames {
127
127
  static readonly unorderedList = "UL";
128
128
  static readonly div = "div";
129
129
  static readonly aTagName = "a";
130
+ static readonly pTagName = "p";
130
131
  static readonly noopenerTag = "noopener";
131
132
  static readonly noreferrerTag = "noreferrer";
132
133
  static readonly adaptiveCardClassName = "ac-adaptiveCard";
@@ -5,6 +5,7 @@ export interface BaseContract {
5
5
  ConversationId: string;
6
6
  ElapsedTimeInMilliseconds?: number;
7
7
  OrganizationId: string;
8
+ OrganizationUrl: string;
8
9
  LCWRuntimeId: string;
9
10
  CurrentRequestId: string;
10
11
  ExceptionDetails?: any;
@@ -32,3 +32,4 @@ export declare const getWidgetCacheIdfromProps: (props: any, popoutChat?: boolea
32
32
  export declare const debounceLeading: (fn: any, ms?: number) => (...args: any[]) => void;
33
33
  export declare const getConversationDetailsCall: (chatSDK: any) => Promise<any>;
34
34
  export declare const checkContactIdError: (e: any) => void;
35
+ export declare const createFileAndDownload: (fileName: string, blobData: string, mimeType: string) => void;
@@ -1,2 +1,3 @@
1
1
  import { ILiveChatWidgetContext } from "../../../contexts/common/ILiveChatWidgetContext";
2
- export declare const downloadTranscript: (chatSDK: any, renderMarkDown?: ((transcriptContent: string) => string) | undefined, bannerMessageOnError?: string | undefined, attachmentMessage?: string | undefined, state?: ILiveChatWidgetContext | undefined) => Promise<void>;
2
+ import { IDownloadTranscriptProps } from "./interfaces/IDownloadTranscriptProps";
3
+ export declare const downloadTranscript: (chatSDK: any, downloadTranscriptProps: IDownloadTranscriptProps, state?: ILiveChatWidgetContext | undefined) => Promise<void>;
@@ -1,3 +1,4 @@
1
+ import { IWebChatTranscriptConfig } from "./IWebChatTranscriptConfig";
1
2
  export interface IDownloadTranscriptProps {
2
3
  /**
3
4
  * Attachment message prefix for download chat transcript
@@ -11,4 +12,8 @@ export interface IDownloadTranscriptProps {
11
12
  * Callback function for markdown render for chat transcript
12
13
  */
13
14
  renderMarkDown?: (transcriptContent: string) => string;
15
+ /**
16
+ * WebChat Transcript config
17
+ */
18
+ webChatTranscript?: IWebChatTranscriptConfig;
14
19
  }
@@ -0,0 +1,13 @@
1
+ export interface IWebChatTranscriptConfig {
2
+ disabled?: boolean;
3
+ fileName?: string;
4
+ pageTitle?: string;
5
+ attachmentMessage?: string;
6
+ networkOnlineMessage?: string;
7
+ networkOfflineMessage?: string;
8
+ transcriptBackgroundColor?: string;
9
+ agentAvatarBackgroundColor?: string;
10
+ agentAvatarFontColor?: string;
11
+ customerAvatarBackgroundColor?: string;
12
+ customerAvatarFontColor?: string;
13
+ }
@@ -0,0 +1,24 @@
1
+ import { StyleOptions } from "botframework-webchat-api";
2
+ import { IDownloadTranscriptProps } from "../../footerstateful/downloadtranscriptstateful/interfaces/IDownloadTranscriptProps";
3
+ import { IWebChatContainerStatefulProps } from "../../webchatcontainerstateful/interfaces/IWebChatContainerStatefulProps";
4
+ declare const createDownloadTranscriptProps: (downloadTranscriptProps: IDownloadTranscriptProps, webChatStyles: StyleOptions, webChatContainerProps?: IWebChatContainerStatefulProps | undefined) => {
5
+ webChatTranscript: {
6
+ disableNewLineMarkdownSupport: boolean | undefined;
7
+ disableMarkdownMessageFormatting: boolean | undefined;
8
+ transcriptBackgroundColor: string | undefined;
9
+ agentAvatarBackgroundColor: string | undefined;
10
+ agentAvatarFontColor: string | undefined;
11
+ customerAvatarBackgroundColor: string | undefined;
12
+ customerAvatarFontColor: string | undefined;
13
+ disabled?: boolean | undefined;
14
+ fileName?: string | undefined;
15
+ pageTitle?: string | undefined;
16
+ attachmentMessage?: string | undefined;
17
+ networkOnlineMessage?: string | undefined;
18
+ networkOfflineMessage?: string | undefined;
19
+ };
20
+ attachmentMessage?: string | undefined;
21
+ bannerMessageOnError?: string | undefined;
22
+ renderMarkDown?: ((transcriptContent: string) => string) | undefined;
23
+ };
24
+ export default createDownloadTranscriptProps;
@@ -1,4 +1,6 @@
1
1
  export interface IAdaptiveCardStyles {
2
2
  background?: string;
3
3
  color?: string;
4
+ buttonWhiteSpace?: string;
5
+ textWhiteSpace?: string;
4
6
  }
@@ -31,4 +31,5 @@ export interface IRenderingMiddlewareProps {
31
31
  attachmentContentStyles?: React.CSSProperties;
32
32
  attachmentSizeStyles?: React.CSSProperties;
33
33
  receivedMessageAnchorStyles?: React.CSSProperties;
34
+ sentMessageAnchorStyles?: React.CSSProperties;
34
35
  }
@@ -4,6 +4,7 @@ import { ReactNode } from "react";
4
4
  export interface IWebChatProps {
5
5
  activityMiddleware?: OneOrMany<ActivityMiddleware>;
6
6
  activityStatusMiddleware?: OneOrMany<ActivityStatusMiddleware>;
7
+ adaptiveCardsHostConfig?: any;
7
8
  attachmentForScreenReaderMiddleware?: OneOrMany<AttachmentForScreenReaderMiddleware>;
8
9
  attachmentMiddleware?: OneOrMany<AttachmentMiddleware>;
9
10
  avatarMiddleware?: OneOrMany<AvatarMiddleware>;
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export declare const defaultSentMessageAnchorStyles: React.CSSProperties;
@@ -0,0 +1,2 @@
1
+ declare const createChatTranscript: (transcript: string, chatSDK: any, renderAttachments?: boolean, transcriptOptions?: any) => Promise<void>;
2
+ export default createChatTranscript;