embeddedaichatux 1.9.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/EmbeddedChat.js +113 -20
- package/package.json +1 -1
package/EmbeddedChat.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
this.isPreview = this.options.isPreview || false;
|
|
10
10
|
this.locale = options.locale || 'en';
|
|
11
11
|
this.previewParam = this.isPreview ? "?isPreview=true" : "";
|
|
12
|
-
this.serverUrl = this.options.serverUrl || 'https://
|
|
12
|
+
this.serverUrl = this.options.serverUrl || 'https://app.bizdriver.ai/';
|
|
13
13
|
this.height = options.height || 600; // Default height
|
|
14
14
|
this.width = options.width || 320; // Default width
|
|
15
15
|
this.marginBottom = options.marginBottom || 0;
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
this.mouseInsideChat = false;
|
|
19
19
|
this.hasRefreshed = false; // Flag to prevent endless loop
|
|
20
20
|
this.conversationId = null;
|
|
21
|
+
this.userTokenProvider = options.userTokenProvider;
|
|
22
|
+
this.targetOrigin = "*";
|
|
21
23
|
|
|
22
24
|
// Determine transition styles
|
|
23
25
|
const transitionStyle = this.enableAnimation ? 'transition: height 0.3s ease, opacity 0.3s ease;' : '';
|
|
@@ -39,7 +41,7 @@
|
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
isSafari() {
|
|
42
|
-
|
|
44
|
+
const ua = navigator.userAgent.toLowerCase();
|
|
43
45
|
return ua.indexOf('safari') != -1 && ua.indexOf('chrome') == -1;
|
|
44
46
|
}
|
|
45
47
|
|
|
@@ -70,40 +72,81 @@
|
|
|
70
72
|
}
|
|
71
73
|
}
|
|
72
74
|
|
|
73
|
-
init() {
|
|
74
|
-
this.updateIframes();
|
|
75
|
-
this.addEventListeners();
|
|
75
|
+
async init() {
|
|
76
|
+
await this.updateIframes();
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
async updateIframes() {
|
|
79
|
-
const cleanedServerUrl = this.serverUrl.endsWith('/')
|
|
80
|
+
const cleanedServerUrl = this.serverUrl.endsWith('/')
|
|
81
|
+
? this.serverUrl.slice(0, -1)
|
|
82
|
+
: this.serverUrl;
|
|
80
83
|
const baseIframeUrl = `${cleanedServerUrl}/ChatUX/${this.chatId}`;
|
|
81
|
-
const minimizedPositionStyle = `
|
|
84
|
+
const minimizedPositionStyle = `
|
|
85
|
+
position: fixed; right: 0; bottom: 0;
|
|
86
|
+
width: ${this.width}px;
|
|
87
|
+
height: ${this.minimizedHeight};
|
|
88
|
+
z-index: 100000;
|
|
89
|
+
${this.enableAnimation ? 'transition: height 0.3s ease, opacity 0.3s ease;' : ''}
|
|
90
|
+
`;
|
|
91
|
+
|
|
92
|
+
const params = {
|
|
93
|
+
isPreview: this.isPreview,
|
|
94
|
+
mode: this.mode,
|
|
95
|
+
locale: this.locale,
|
|
96
|
+
conversationId: this.conversationId
|
|
97
|
+
};
|
|
82
98
|
|
|
83
99
|
const iframeHtml = `
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
100
|
+
<iframe
|
|
101
|
+
id="embedded-chat"
|
|
102
|
+
style="${this.positionStyle}; display: none; border:none; overflow:hidden;"
|
|
103
|
+
frameborder="0"
|
|
104
|
+
sandbox="allow-same-origin allow-scripts allow-popups allow-forms allow-top-navigation-by-user-activation"
|
|
105
|
+
src="${this.buildIframeUrl(baseIframeUrl, params)}"
|
|
106
|
+
></iframe>
|
|
107
|
+
<iframe
|
|
108
|
+
id="embedded-chat-minimized"
|
|
109
|
+
style="${minimizedPositionStyle}; display: none; border:none; overflow:hidden;"
|
|
110
|
+
frameborder="0"
|
|
111
|
+
sandbox="allow-same-origin allow-scripts allow-popups allow-forms"
|
|
112
|
+
src="${this.buildIframeUrl(baseIframeUrl, { ...params, isMinimized: true })}"
|
|
113
|
+
></iframe>
|
|
114
|
+
`;
|
|
115
|
+
|
|
116
|
+
// inject and capture references
|
|
88
117
|
this.containerDiv.innerHTML = iframeHtml;
|
|
89
|
-
this.iframe = this.containerDiv.querySelector(
|
|
90
|
-
this.minimizedIframe = this.containerDiv.querySelector(
|
|
118
|
+
this.iframe = this.containerDiv.querySelector('#embedded-chat');
|
|
119
|
+
this.minimizedIframe = this.containerDiv.querySelector('#embedded-chat-minimized');
|
|
91
120
|
|
|
121
|
+
// wait for the real <iframe> element to load
|
|
92
122
|
await this.waitForIframeLoad(this.iframe);
|
|
93
123
|
|
|
124
|
+
// now that this.iframe & this.minimizedIframe exist, hook up events
|
|
125
|
+
this.addEventListeners();
|
|
126
|
+
|
|
127
|
+
// Send auth to iframes after load
|
|
128
|
+
await this.postAuthToIframes();
|
|
129
|
+
|
|
130
|
+
// restore your ContactForm logic
|
|
94
131
|
if (this.mode === 'ContactForm') {
|
|
95
|
-
this.iframe.style.maxWidth =
|
|
96
|
-
this.iframe.style.display =
|
|
132
|
+
this.iframe.style.maxWidth = '100%';
|
|
133
|
+
this.iframe.style.display = 'block';
|
|
97
134
|
}
|
|
98
135
|
}
|
|
99
136
|
|
|
100
137
|
addEventListeners() {
|
|
138
|
+
if (!this.iframe || !this.minimizedIframe) {
|
|
139
|
+
console.error('EmbeddedChat: iframe or minimizedIframe is not defined when trying to add event listeners.', this.iframe, this.minimizedIframe);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
101
142
|
this.iframe.addEventListener("mouseenter", () => { this.mouseInsideChat = true; });
|
|
102
143
|
this.iframe.addEventListener("mouseleave", () => { this.mouseInsideChat = false; });
|
|
103
144
|
this.minimizedIframe.addEventListener("mouseenter", () => { this.mouseInsideChat = true; });
|
|
104
145
|
this.minimizedIframe.addEventListener("mouseleave", () => { this.mouseInsideChat = false; });
|
|
105
146
|
|
|
106
147
|
window.addEventListener("message", (e) => {
|
|
148
|
+
// Only trust messages from our server (when targetOrigin is not "*")
|
|
149
|
+
if (this.targetOrigin !== "*" && e.origin !== this.targetOrigin) return;
|
|
107
150
|
this.handleMessage(e);
|
|
108
151
|
});
|
|
109
152
|
|
|
@@ -128,11 +171,26 @@
|
|
|
128
171
|
message: "resize",
|
|
129
172
|
width: window.innerWidth, // Ensure correct size
|
|
130
173
|
height: window.innerHeight
|
|
131
|
-
},
|
|
174
|
+
}, this.targetOrigin);
|
|
132
175
|
}
|
|
133
176
|
}
|
|
134
177
|
|
|
135
178
|
handleMessage(e) {
|
|
179
|
+
console.log('[EmbeddedChat] Received message:', {
|
|
180
|
+
origin: e.origin,
|
|
181
|
+
type: e.data?.type,
|
|
182
|
+
message: e.data?.message,
|
|
183
|
+
chatId: e.data?.chatId,
|
|
184
|
+
data: e.data
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// Allow the iframe to request a fresh token
|
|
188
|
+
if (typeof e.data === "object" && e.data?.type === "requestAuth") {
|
|
189
|
+
console.log('[EmbeddedChat] Received requestAuth message, calling postAuthToIframes');
|
|
190
|
+
this.postAuthToIframes();
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
|
|
136
194
|
if (typeof e.data === "object" && (!e.data.chatId || e.data.chatId === this.chatId)) {
|
|
137
195
|
const updates = {};
|
|
138
196
|
|
|
@@ -335,7 +393,7 @@
|
|
|
335
393
|
this.iframe.contentWindow.postMessage({
|
|
336
394
|
message: "show",
|
|
337
395
|
sessionInfo: this.sessionInfo || null
|
|
338
|
-
},
|
|
396
|
+
}, this.targetOrigin);
|
|
339
397
|
} else {
|
|
340
398
|
// Schedule a single retry with a delay
|
|
341
399
|
setTimeout(() => {
|
|
@@ -343,7 +401,7 @@
|
|
|
343
401
|
this.iframe.contentWindow.postMessage({
|
|
344
402
|
message: "show",
|
|
345
403
|
sessionInfo: this.sessionInfo || null
|
|
346
|
-
},
|
|
404
|
+
}, this.targetOrigin);
|
|
347
405
|
} else {
|
|
348
406
|
console.warn("iframe contentWindow is not available.");
|
|
349
407
|
}
|
|
@@ -387,7 +445,7 @@
|
|
|
387
445
|
|
|
388
446
|
// Send session info immediately if the chat is already maximized
|
|
389
447
|
if (this.iframe?.contentWindow && this.iframe.style.display !== "none") {
|
|
390
|
-
this.iframe.contentWindow.postMessage({ type: 'setSessionInfo', sessionInfo: this.sessionInfo },
|
|
448
|
+
this.iframe.contentWindow.postMessage({ type: 'setSessionInfo', sessionInfo: this.sessionInfo }, this.targetOrigin);
|
|
391
449
|
}
|
|
392
450
|
}
|
|
393
451
|
|
|
@@ -419,7 +477,7 @@
|
|
|
419
477
|
}
|
|
420
478
|
|
|
421
479
|
for (const [key, value] of Object.entries(params)) {
|
|
422
|
-
if (key !== 'mode' && key !== 'isPreview' && key !== 'conversationId' && value !== null && value !== undefined) {
|
|
480
|
+
if (key !== 'mode' && key !== 'isPreview' && key !== 'conversationId' && key !== 'userToken' && value !== null && value !== undefined) {
|
|
423
481
|
urlParams.set(key, value);
|
|
424
482
|
}
|
|
425
483
|
}
|
|
@@ -447,6 +505,41 @@
|
|
|
447
505
|
}, { once: true }); // Ensure the listener is triggered only once
|
|
448
506
|
});
|
|
449
507
|
}
|
|
508
|
+
|
|
509
|
+
async postAuthToIframes() {
|
|
510
|
+
console.log('[EmbeddedChat] postAuthToIframes called');
|
|
511
|
+
if (typeof this.userTokenProvider !== 'function') {
|
|
512
|
+
console.warn('[EmbeddedChat] No userTokenProvider function provided');
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
try {
|
|
517
|
+
console.log('[EmbeddedChat] Calling userTokenProvider...');
|
|
518
|
+
const userToken = await this.userTokenProvider();
|
|
519
|
+
|
|
520
|
+
if (!userToken) {
|
|
521
|
+
console.warn('[EmbeddedChat] userTokenProvider returned null/empty token');
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
console.log('[EmbeddedChat] Got user token, length:', userToken?.length || 0);
|
|
526
|
+
|
|
527
|
+
if (this.iframe?.contentWindow) {
|
|
528
|
+
console.log('[EmbeddedChat] Sending auth message to iframe with targetOrigin:', this.targetOrigin);
|
|
529
|
+
this.iframe.contentWindow.postMessage({
|
|
530
|
+
type: 'auth',
|
|
531
|
+
userToken: userToken,
|
|
532
|
+
chatId: this.chatId
|
|
533
|
+
}, this.targetOrigin);
|
|
534
|
+
console.log('[EmbeddedChat] Auth message sent successfully');
|
|
535
|
+
} else {
|
|
536
|
+
console.error('[EmbeddedChat] iframe.contentWindow is not available');
|
|
537
|
+
}
|
|
538
|
+
// No longer send auth to minimizedIframe
|
|
539
|
+
} catch (err) {
|
|
540
|
+
console.error('[EmbeddedChat] Failed to get user token:', err);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
450
543
|
}
|
|
451
544
|
|
|
452
545
|
export function initEmbeddedChat(containerDiv, chatId, options) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "embeddedaichatux",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "A lightweight and customizable embedded AI chat UI component that seamlessly integrates into web applications, offering minimized and expanded views, with iframe-based content rendering.",
|
|
5
5
|
"main": "EmbeddedChat.js",
|
|
6
6
|
"scripts": {
|