embeddedaichatux 1.9.0 → 2.0.0
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 +117 -19
- 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,13 @@
|
|
|
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
|
+
|
|
23
|
+
try {
|
|
24
|
+
this.targetOrigin = new URL(this.serverUrl).origin;
|
|
25
|
+
} catch {
|
|
26
|
+
this.targetOrigin = "*";
|
|
27
|
+
}
|
|
21
28
|
|
|
22
29
|
// Determine transition styles
|
|
23
30
|
const transitionStyle = this.enableAnimation ? 'transition: height 0.3s ease, opacity 0.3s ease;' : '';
|
|
@@ -70,40 +77,81 @@
|
|
|
70
77
|
}
|
|
71
78
|
}
|
|
72
79
|
|
|
73
|
-
init() {
|
|
74
|
-
this.updateIframes();
|
|
75
|
-
this.addEventListeners();
|
|
80
|
+
async init() {
|
|
81
|
+
await this.updateIframes();
|
|
76
82
|
}
|
|
77
83
|
|
|
78
84
|
async updateIframes() {
|
|
79
|
-
const cleanedServerUrl = this.serverUrl.endsWith('/')
|
|
85
|
+
const cleanedServerUrl = this.serverUrl.endsWith('/')
|
|
86
|
+
? this.serverUrl.slice(0, -1)
|
|
87
|
+
: this.serverUrl;
|
|
80
88
|
const baseIframeUrl = `${cleanedServerUrl}/ChatUX/${this.chatId}`;
|
|
81
|
-
const minimizedPositionStyle = `
|
|
89
|
+
const minimizedPositionStyle = `
|
|
90
|
+
position: fixed; right: 0; bottom: 0;
|
|
91
|
+
width: ${this.width}px;
|
|
92
|
+
height: ${this.minimizedHeight};
|
|
93
|
+
z-index: 100000;
|
|
94
|
+
${this.enableAnimation ? 'transition: height 0.3s ease, opacity 0.3s ease;' : ''}
|
|
95
|
+
`;
|
|
96
|
+
|
|
97
|
+
const params = {
|
|
98
|
+
isPreview: this.isPreview,
|
|
99
|
+
mode: this.mode,
|
|
100
|
+
locale: this.locale,
|
|
101
|
+
conversationId: this.conversationId
|
|
102
|
+
};
|
|
82
103
|
|
|
83
104
|
const iframeHtml = `
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
105
|
+
<iframe
|
|
106
|
+
id="embedded-chat"
|
|
107
|
+
style="${this.positionStyle}; display: none; border:none; overflow:hidden;"
|
|
108
|
+
frameborder="0"
|
|
109
|
+
sandbox="allow-same-origin allow-scripts allow-popups allow-forms allow-top-navigation-by-user-activation"
|
|
110
|
+
src="${this.buildIframeUrl(baseIframeUrl, params)}"
|
|
111
|
+
></iframe>
|
|
112
|
+
<iframe
|
|
113
|
+
id="embedded-chat-minimized"
|
|
114
|
+
style="${minimizedPositionStyle}; display: none; border:none; overflow:hidden;"
|
|
115
|
+
frameborder="0"
|
|
116
|
+
sandbox="allow-same-origin allow-scripts allow-popups allow-forms"
|
|
117
|
+
src="${this.buildIframeUrl(baseIframeUrl, { ...params, isMinimized: true })}"
|
|
118
|
+
></iframe>
|
|
119
|
+
`;
|
|
120
|
+
|
|
121
|
+
// inject and capture references
|
|
88
122
|
this.containerDiv.innerHTML = iframeHtml;
|
|
89
|
-
this.iframe = this.containerDiv.querySelector(
|
|
90
|
-
this.minimizedIframe = this.containerDiv.querySelector(
|
|
123
|
+
this.iframe = this.containerDiv.querySelector('#embedded-chat');
|
|
124
|
+
this.minimizedIframe = this.containerDiv.querySelector('#embedded-chat-minimized');
|
|
91
125
|
|
|
126
|
+
// wait for the real <iframe> element to load
|
|
92
127
|
await this.waitForIframeLoad(this.iframe);
|
|
93
128
|
|
|
129
|
+
// now that this.iframe & this.minimizedIframe exist, hook up events
|
|
130
|
+
this.addEventListeners();
|
|
131
|
+
|
|
132
|
+
// Send auth to iframes after load
|
|
133
|
+
await this.postAuthToIframes();
|
|
134
|
+
|
|
135
|
+
// restore your ContactForm logic
|
|
94
136
|
if (this.mode === 'ContactForm') {
|
|
95
|
-
this.iframe.style.maxWidth =
|
|
96
|
-
this.iframe.style.display =
|
|
137
|
+
this.iframe.style.maxWidth = '100%';
|
|
138
|
+
this.iframe.style.display = 'block';
|
|
97
139
|
}
|
|
98
140
|
}
|
|
99
141
|
|
|
100
142
|
addEventListeners() {
|
|
143
|
+
if (!this.iframe || !this.minimizedIframe) {
|
|
144
|
+
console.error('EmbeddedChat: iframe or minimizedIframe is not defined when trying to add event listeners.', this.iframe, this.minimizedIframe);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
101
147
|
this.iframe.addEventListener("mouseenter", () => { this.mouseInsideChat = true; });
|
|
102
148
|
this.iframe.addEventListener("mouseleave", () => { this.mouseInsideChat = false; });
|
|
103
149
|
this.minimizedIframe.addEventListener("mouseenter", () => { this.mouseInsideChat = true; });
|
|
104
150
|
this.minimizedIframe.addEventListener("mouseleave", () => { this.mouseInsideChat = false; });
|
|
105
151
|
|
|
106
152
|
window.addEventListener("message", (e) => {
|
|
153
|
+
// Only trust messages from our server (when targetOrigin is not "*")
|
|
154
|
+
if (this.targetOrigin !== "*" && e.origin !== this.targetOrigin) return;
|
|
107
155
|
this.handleMessage(e);
|
|
108
156
|
});
|
|
109
157
|
|
|
@@ -128,11 +176,26 @@
|
|
|
128
176
|
message: "resize",
|
|
129
177
|
width: window.innerWidth, // Ensure correct size
|
|
130
178
|
height: window.innerHeight
|
|
131
|
-
},
|
|
179
|
+
}, this.targetOrigin);
|
|
132
180
|
}
|
|
133
181
|
}
|
|
134
182
|
|
|
135
183
|
handleMessage(e) {
|
|
184
|
+
console.log('[EmbeddedChat] Received message:', {
|
|
185
|
+
origin: e.origin,
|
|
186
|
+
type: e.data?.type,
|
|
187
|
+
message: e.data?.message,
|
|
188
|
+
chatId: e.data?.chatId,
|
|
189
|
+
data: e.data
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// Allow the iframe to request a fresh token
|
|
193
|
+
if (typeof e.data === "object" && e.data?.type === "requestAuth") {
|
|
194
|
+
console.log('[EmbeddedChat] Received requestAuth message, calling postAuthToIframes');
|
|
195
|
+
this.postAuthToIframes();
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
|
|
136
199
|
if (typeof e.data === "object" && (!e.data.chatId || e.data.chatId === this.chatId)) {
|
|
137
200
|
const updates = {};
|
|
138
201
|
|
|
@@ -335,7 +398,7 @@
|
|
|
335
398
|
this.iframe.contentWindow.postMessage({
|
|
336
399
|
message: "show",
|
|
337
400
|
sessionInfo: this.sessionInfo || null
|
|
338
|
-
},
|
|
401
|
+
}, this.targetOrigin);
|
|
339
402
|
} else {
|
|
340
403
|
// Schedule a single retry with a delay
|
|
341
404
|
setTimeout(() => {
|
|
@@ -343,7 +406,7 @@
|
|
|
343
406
|
this.iframe.contentWindow.postMessage({
|
|
344
407
|
message: "show",
|
|
345
408
|
sessionInfo: this.sessionInfo || null
|
|
346
|
-
},
|
|
409
|
+
}, this.targetOrigin);
|
|
347
410
|
} else {
|
|
348
411
|
console.warn("iframe contentWindow is not available.");
|
|
349
412
|
}
|
|
@@ -387,7 +450,7 @@
|
|
|
387
450
|
|
|
388
451
|
// Send session info immediately if the chat is already maximized
|
|
389
452
|
if (this.iframe?.contentWindow && this.iframe.style.display !== "none") {
|
|
390
|
-
this.iframe.contentWindow.postMessage({ type: 'setSessionInfo', sessionInfo: this.sessionInfo },
|
|
453
|
+
this.iframe.contentWindow.postMessage({ type: 'setSessionInfo', sessionInfo: this.sessionInfo }, this.targetOrigin);
|
|
391
454
|
}
|
|
392
455
|
}
|
|
393
456
|
|
|
@@ -419,7 +482,7 @@
|
|
|
419
482
|
}
|
|
420
483
|
|
|
421
484
|
for (const [key, value] of Object.entries(params)) {
|
|
422
|
-
if (key !== 'mode' && key !== 'isPreview' && key !== 'conversationId' && value !== null && value !== undefined) {
|
|
485
|
+
if (key !== 'mode' && key !== 'isPreview' && key !== 'conversationId' && key !== 'userToken' && value !== null && value !== undefined) {
|
|
423
486
|
urlParams.set(key, value);
|
|
424
487
|
}
|
|
425
488
|
}
|
|
@@ -447,6 +510,41 @@
|
|
|
447
510
|
}, { once: true }); // Ensure the listener is triggered only once
|
|
448
511
|
});
|
|
449
512
|
}
|
|
513
|
+
|
|
514
|
+
async postAuthToIframes() {
|
|
515
|
+
console.log('[EmbeddedChat] postAuthToIframes called');
|
|
516
|
+
if (typeof this.userTokenProvider !== 'function') {
|
|
517
|
+
console.warn('[EmbeddedChat] No userTokenProvider function provided');
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
try {
|
|
522
|
+
console.log('[EmbeddedChat] Calling userTokenProvider...');
|
|
523
|
+
const userToken = await this.userTokenProvider();
|
|
524
|
+
|
|
525
|
+
if (!userToken) {
|
|
526
|
+
console.warn('[EmbeddedChat] userTokenProvider returned null/empty token');
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
console.log('[EmbeddedChat] Got user token, length:', userToken?.length || 0);
|
|
531
|
+
|
|
532
|
+
if (this.iframe?.contentWindow) {
|
|
533
|
+
console.log('[EmbeddedChat] Sending auth message to iframe with targetOrigin:', this.targetOrigin);
|
|
534
|
+
this.iframe.contentWindow.postMessage({
|
|
535
|
+
type: 'auth',
|
|
536
|
+
userToken: userToken,
|
|
537
|
+
chatId: this.chatId
|
|
538
|
+
}, this.targetOrigin);
|
|
539
|
+
console.log('[EmbeddedChat] Auth message sent successfully');
|
|
540
|
+
} else {
|
|
541
|
+
console.error('[EmbeddedChat] iframe.contentWindow is not available');
|
|
542
|
+
}
|
|
543
|
+
// No longer send auth to minimizedIframe
|
|
544
|
+
} catch (err) {
|
|
545
|
+
console.error('[EmbeddedChat] Failed to get user token:', err);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
450
548
|
}
|
|
451
549
|
|
|
452
550
|
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.0",
|
|
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": {
|