@blotoutio/providers-shop-gpt-sdk 1.9.0 → 1.10.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/index.cjs.js +539 -36
- package/index.js +539 -36
- package/index.mjs +539 -36
- package/package.json +1 -1
package/index.mjs
CHANGED
@@ -406,10 +406,65 @@ const createExperiment = (props) => {
|
|
406
406
|
}
|
407
407
|
};
|
408
408
|
|
409
|
+
const uiActions = new Set([
|
410
|
+
'shopGPTInitialized',
|
411
|
+
'chatbotOpened',
|
412
|
+
'queryInteractions',
|
413
|
+
'promptClicked',
|
414
|
+
'productRecommendationClicked',
|
415
|
+
]);
|
416
|
+
new Set([
|
417
|
+
...uiActions,
|
418
|
+
'pageView',
|
419
|
+
'productRecommendationViewed',
|
420
|
+
'productRecommendationAddedToCart',
|
421
|
+
'productRecommendationInitiatedCheckout',
|
422
|
+
'orderPlaced',
|
423
|
+
]);
|
424
|
+
|
409
425
|
const packageName = 'shopGPT';
|
410
|
-
const DEFAULT_MAX_THREAD_AGE = 14;
|
426
|
+
const DEFAULT_MAX_THREAD_AGE = 14; // in days
|
427
|
+
const DEFAULT_NUDGE_TIMEOUT = 10; // in seconds
|
411
428
|
const previewKeyName = 'previewShopGPT';
|
412
429
|
|
430
|
+
const keyPrefix = `_worker`;
|
431
|
+
|
432
|
+
const getCookieValue = (key) => {
|
433
|
+
var _a;
|
434
|
+
try {
|
435
|
+
if (!document || !document.cookie) {
|
436
|
+
return '';
|
437
|
+
}
|
438
|
+
const cookies = parseCookies(document.cookie);
|
439
|
+
return (_a = cookies[key]) !== null && _a !== void 0 ? _a : '';
|
440
|
+
}
|
441
|
+
catch {
|
442
|
+
return '';
|
443
|
+
}
|
444
|
+
};
|
445
|
+
const parseCookies = (cookie) => {
|
446
|
+
return Object.fromEntries(cookie
|
447
|
+
.split(/;\s+/)
|
448
|
+
.map((r) => r.split('=').map((str) => str.trim()))
|
449
|
+
.map(([cookieKey, ...cookieValues]) => {
|
450
|
+
const cookieValue = cookieValues.join('=');
|
451
|
+
if (!cookieKey) {
|
452
|
+
return [];
|
453
|
+
}
|
454
|
+
let decodedValue = '';
|
455
|
+
if (cookieValue) {
|
456
|
+
try {
|
457
|
+
decodedValue = decodeURIComponent(cookieValue);
|
458
|
+
}
|
459
|
+
catch (e) {
|
460
|
+
console.log(`Unable to decode cookie ${cookieKey}: ${e}`);
|
461
|
+
decodedValue = cookieValue;
|
462
|
+
}
|
463
|
+
}
|
464
|
+
return [cookieKey, decodedValue];
|
465
|
+
}));
|
466
|
+
};
|
467
|
+
|
413
468
|
const canLog = () => {
|
414
469
|
try {
|
415
470
|
return localStorage.getItem('edgeTagDebug') === '1';
|
@@ -442,12 +497,188 @@ const logger = {
|
|
442
497
|
},
|
443
498
|
};
|
444
499
|
|
500
|
+
const initKey = `${keyPrefix}StoreMultiple`;
|
501
|
+
const saveData = (destination, persistType, value, key = initKey) => {
|
502
|
+
if (persistType === 'session') {
|
503
|
+
const data = getSession(key);
|
504
|
+
data[destination] = value;
|
505
|
+
saveSession(data, key);
|
506
|
+
return;
|
507
|
+
}
|
508
|
+
const data = getLocal(key);
|
509
|
+
data[destination] = value;
|
510
|
+
saveLocal(data, key);
|
511
|
+
};
|
512
|
+
const getData = (destination, persistType, key = initKey) => {
|
513
|
+
let data;
|
514
|
+
if (persistType === 'session') {
|
515
|
+
data = getSession(key);
|
516
|
+
}
|
517
|
+
else {
|
518
|
+
data = getLocal(key);
|
519
|
+
}
|
520
|
+
return (data === null || data === void 0 ? void 0 : data[destination]) || {};
|
521
|
+
};
|
522
|
+
const saveLocal = (value, key) => {
|
523
|
+
try {
|
524
|
+
if (!localStorage) {
|
525
|
+
return;
|
526
|
+
}
|
527
|
+
localStorage.setItem(key, JSON.stringify(value));
|
528
|
+
}
|
529
|
+
catch {
|
530
|
+
logger.log('Local storage not supported.');
|
531
|
+
}
|
532
|
+
};
|
533
|
+
const getLocal = (key) => {
|
534
|
+
try {
|
535
|
+
if (!localStorage) {
|
536
|
+
return {};
|
537
|
+
}
|
538
|
+
const data = localStorage.getItem(key);
|
539
|
+
if (!data) {
|
540
|
+
return {};
|
541
|
+
}
|
542
|
+
return JSON.parse(data) || {};
|
543
|
+
}
|
544
|
+
catch {
|
545
|
+
return {};
|
546
|
+
}
|
547
|
+
};
|
548
|
+
const saveSession = (value, key) => {
|
549
|
+
try {
|
550
|
+
if (!sessionStorage) {
|
551
|
+
return;
|
552
|
+
}
|
553
|
+
sessionStorage.setItem(key, JSON.stringify(value));
|
554
|
+
}
|
555
|
+
catch {
|
556
|
+
logger.log('Session storage not supported.');
|
557
|
+
}
|
558
|
+
};
|
559
|
+
const getSession = (key) => {
|
560
|
+
try {
|
561
|
+
if (!sessionStorage) {
|
562
|
+
return {};
|
563
|
+
}
|
564
|
+
const data = sessionStorage.getItem(key);
|
565
|
+
if (!data) {
|
566
|
+
return {};
|
567
|
+
}
|
568
|
+
return JSON.parse(data) || {};
|
569
|
+
}
|
570
|
+
catch {
|
571
|
+
return {};
|
572
|
+
}
|
573
|
+
};
|
574
|
+
|
445
575
|
var _a$1;
|
446
576
|
const registryKey = Symbol.for('shop-gpt');
|
447
577
|
if (typeof window != 'undefined') {
|
448
578
|
(_a$1 = window[registryKey]) !== null && _a$1 !== void 0 ? _a$1 : (window[registryKey] = {});
|
449
579
|
}
|
450
580
|
|
581
|
+
const SHOP_GPT_SESSION_KEY = 'shopGPTSession';
|
582
|
+
const SHOP_GPT_LOCAL_STORAGE_KEY = 'shopGPTLocalStorage';
|
583
|
+
const getSessionData = (destination) => {
|
584
|
+
const session = getData(destination, 'session', SHOP_GPT_SESSION_KEY);
|
585
|
+
return session;
|
586
|
+
};
|
587
|
+
const saveSessionData = (destination, data) => {
|
588
|
+
saveData(destination, 'session', data, SHOP_GPT_SESSION_KEY);
|
589
|
+
};
|
590
|
+
const getLocalStorageData = (destination) => {
|
591
|
+
const local = getData(destination, 'local', SHOP_GPT_LOCAL_STORAGE_KEY);
|
592
|
+
return local;
|
593
|
+
};
|
594
|
+
const saveLocalStorageData = (destination, data) => {
|
595
|
+
saveData(destination, 'local', data, SHOP_GPT_LOCAL_STORAGE_KEY);
|
596
|
+
};
|
597
|
+
const getSessionId = () => {
|
598
|
+
return getCookieValue('tag_session');
|
599
|
+
};
|
600
|
+
|
601
|
+
// eslint-disable-next-line @nx/enforce-module-boundaries
|
602
|
+
const hasPreviewKey = () => {
|
603
|
+
var _a;
|
604
|
+
try {
|
605
|
+
return ((_a = sessionStorage.getItem(previewKeyName)) !== null && _a !== void 0 ? _a : '0') == '1';
|
606
|
+
}
|
607
|
+
catch {
|
608
|
+
return false;
|
609
|
+
}
|
610
|
+
};
|
611
|
+
const isUserInteracted = (destination) => {
|
612
|
+
var _a;
|
613
|
+
const session = getSessionData(destination);
|
614
|
+
return !!((_a = session === null || session === void 0 ? void 0 : session.chatbot) === null || _a === void 0 ? void 0 : _a.hasUserInteracted);
|
615
|
+
};
|
616
|
+
const setUserInteracted = (destination) => {
|
617
|
+
const session = getSessionData(destination);
|
618
|
+
saveSessionData(destination, {
|
619
|
+
...session,
|
620
|
+
chatbot: { ...session === null || session === void 0 ? void 0 : session.chatbot, hasUserInteracted: true },
|
621
|
+
});
|
622
|
+
};
|
623
|
+
const getProductActions = (destination) => {
|
624
|
+
var _a;
|
625
|
+
const local = getLocalStorageData(destination);
|
626
|
+
const sessionId = getSessionId();
|
627
|
+
if (!local || !sessionId) {
|
628
|
+
logger.error('No local storage data or session id');
|
629
|
+
return null;
|
630
|
+
}
|
631
|
+
return (_a = local[sessionId]) === null || _a === void 0 ? void 0 : _a.products;
|
632
|
+
};
|
633
|
+
const setProductAction = (destination, productId, action, value) => {
|
634
|
+
var _a, _b, _c;
|
635
|
+
const local = getLocalStorageData(destination);
|
636
|
+
const sessionId = getSessionId();
|
637
|
+
if (!local || !sessionId) {
|
638
|
+
logger.error('No local storage data or session id');
|
639
|
+
return;
|
640
|
+
}
|
641
|
+
const productTags = (_b = (_a = local[sessionId]) === null || _a === void 0 ? void 0 : _a.products) === null || _b === void 0 ? void 0 : _b[productId];
|
642
|
+
local[sessionId] = {
|
643
|
+
...local[sessionId],
|
644
|
+
products: {
|
645
|
+
...(_c = local[sessionId]) === null || _c === void 0 ? void 0 : _c.products,
|
646
|
+
[productId]: {
|
647
|
+
...productTags,
|
648
|
+
[action]: value,
|
649
|
+
},
|
650
|
+
},
|
651
|
+
};
|
652
|
+
// Clear other sessions
|
653
|
+
const updatedLocal = { [sessionId]: local[sessionId] };
|
654
|
+
saveLocalStorageData(destination, updatedLocal);
|
655
|
+
};
|
656
|
+
const getShopGPTLoaded = (destination) => {
|
657
|
+
var _a, _b;
|
658
|
+
const local = getLocalStorageData(destination);
|
659
|
+
const sessionId = getSessionId();
|
660
|
+
if (!local || !sessionId) {
|
661
|
+
logger.error('No local storage data or session id');
|
662
|
+
return false;
|
663
|
+
}
|
664
|
+
return (_b = (_a = local[sessionId]) === null || _a === void 0 ? void 0 : _a.isShopGPTLoaded) !== null && _b !== void 0 ? _b : false;
|
665
|
+
};
|
666
|
+
const setShopGPTLoaded = (destination, value) => {
|
667
|
+
const local = getLocalStorageData(destination);
|
668
|
+
const sessionId = getSessionId();
|
669
|
+
if (!local || !sessionId) {
|
670
|
+
logger.error('No local storage data or session id');
|
671
|
+
return;
|
672
|
+
}
|
673
|
+
local[sessionId] = {
|
674
|
+
...local[sessionId],
|
675
|
+
isShopGPTLoaded: value,
|
676
|
+
};
|
677
|
+
// Clear other sessions
|
678
|
+
const updatedLocal = { [sessionId]: local[sessionId] };
|
679
|
+
saveLocalStorageData(destination, updatedLocal);
|
680
|
+
};
|
681
|
+
|
451
682
|
const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, storeAPI, }) => {
|
452
683
|
if (!baseURL) {
|
453
684
|
throw new Error(`baseURL missing`);
|
@@ -550,13 +781,14 @@ const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, st
|
|
550
781
|
throw new Error(`Failed to delete all chat threads - ${response.status}: ${await response.text()}`);
|
551
782
|
}
|
552
783
|
};
|
553
|
-
const saveFeedback = async (messageId, feedback) => {
|
784
|
+
const saveFeedback = async (messageId, threadId, feedback) => {
|
554
785
|
const response = await fetchImpl(getURL('/feedback'), {
|
555
786
|
method: 'POST',
|
556
787
|
headers: getHeaders(),
|
557
788
|
credentials: 'include',
|
558
789
|
body: JSON.stringify({
|
559
790
|
messageId,
|
791
|
+
threadId,
|
560
792
|
feedback,
|
561
793
|
}),
|
562
794
|
});
|
@@ -576,6 +808,28 @@ const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, st
|
|
576
808
|
const data = (await response.json());
|
577
809
|
return data.customPrompts;
|
578
810
|
};
|
811
|
+
const sendEvent = async (action, currency, actionData) => {
|
812
|
+
var _a;
|
813
|
+
const storageData = (_a = getProductActions(baseURL)) !== null && _a !== void 0 ? _a : {};
|
814
|
+
const response = await fetchImpl(getURL('/user/event'), {
|
815
|
+
method: 'POST',
|
816
|
+
headers: getHeaders(true),
|
817
|
+
body: JSON.stringify({
|
818
|
+
action,
|
819
|
+
currency,
|
820
|
+
actionData,
|
821
|
+
storageData: {
|
822
|
+
session: storageData,
|
823
|
+
preview: hasPreviewKey(),
|
824
|
+
isShopGPTLoaded: true, // The fact that sendEvent was called means that the ShopGPT is loaded
|
825
|
+
},
|
826
|
+
}),
|
827
|
+
credentials: 'include',
|
828
|
+
});
|
829
|
+
if (!response.ok) {
|
830
|
+
throw new Error(`Error while recording user event - ${response.status}: ${response.statusText}\n\n${await response.text()}`);
|
831
|
+
}
|
832
|
+
};
|
579
833
|
return {
|
580
834
|
processQuery,
|
581
835
|
fetchChatHistory,
|
@@ -585,20 +839,12 @@ const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, st
|
|
585
839
|
deleteAllThreads,
|
586
840
|
saveFeedback,
|
587
841
|
fetchCustomPrompts,
|
842
|
+
sendEvent,
|
588
843
|
};
|
589
844
|
};
|
590
845
|
|
591
846
|
// eslint-disable-next-line @nx/enforce-module-boundaries
|
592
847
|
const error = (message) => console.error(message);
|
593
|
-
const hasPreviewKey = () => {
|
594
|
-
var _a;
|
595
|
-
try {
|
596
|
-
return ((_a = sessionStorage.getItem(previewKeyName)) !== null && _a !== void 0 ? _a : '0') == '1';
|
597
|
-
}
|
598
|
-
catch {
|
599
|
-
return false;
|
600
|
-
}
|
601
|
-
};
|
602
848
|
const init = (params) => {
|
603
849
|
var _a, _b, _c;
|
604
850
|
if (typeof window == 'undefined' || typeof document == 'undefined') {
|
@@ -618,7 +864,8 @@ const init = (params) => {
|
|
618
864
|
// exit if not in top window
|
619
865
|
return;
|
620
866
|
}
|
621
|
-
const { enabled, mode, devMode, merchantUrl, profiles, productHandles, targetPath, view, brandName, quickPrompts, merchantImage, latestThreadLoad, botIconUrl, css, } = (_c = params.manifest.variables) !== null && _c !== void 0 ? _c : {};
|
867
|
+
const { enabled, mode, devMode, merchantUrl, profiles, productHandles, targetPath, view, brandName, quickPrompts, merchantImage, latestThreadLoad, botIconUrl, css, nudge, loadUiManually, } = (_c = params.manifest.variables) !== null && _c !== void 0 ? _c : {};
|
868
|
+
setShopGPTLoaded(params.baseUrl, !loadUiManually);
|
622
869
|
const experiment = createExperiment({
|
623
870
|
name: getExperimentName(mode),
|
624
871
|
userId: params.userId,
|
@@ -640,6 +887,7 @@ const init = (params) => {
|
|
640
887
|
userId: params.userId,
|
641
888
|
});
|
642
889
|
uiImplementation.init({
|
890
|
+
destination: params.baseUrl,
|
643
891
|
storeAPI,
|
644
892
|
shopGPTAPI,
|
645
893
|
devMode,
|
@@ -654,14 +902,47 @@ const init = (params) => {
|
|
654
902
|
latestThreadLoad: latestThreadLoad !== null && latestThreadLoad !== void 0 ? latestThreadLoad : DEFAULT_MAX_THREAD_AGE,
|
655
903
|
botIconUrl,
|
656
904
|
css,
|
905
|
+
nudge,
|
906
|
+
});
|
907
|
+
if (!loadUiManually) {
|
908
|
+
uiImplementation.loadUI();
|
909
|
+
}
|
910
|
+
}
|
911
|
+
};
|
912
|
+
|
913
|
+
const getClickedProductsInContents = (destination, data) => {
|
914
|
+
const storedData = getProductActions(destination);
|
915
|
+
const contents = data['contents'];
|
916
|
+
if (!contents || !Array.isArray(contents) || !storedData) {
|
917
|
+
return;
|
918
|
+
}
|
919
|
+
return contents.flatMap((content) => { var _a; return ((_a = storedData[content.id]) === null || _a === void 0 ? void 0 : _a.clicked) ? [content.id] : []; });
|
920
|
+
};
|
921
|
+
const tag = ({ eventName, destination, data, }) => {
|
922
|
+
var _a;
|
923
|
+
const clickedProducts = getClickedProductsInContents(destination, data);
|
924
|
+
if (eventName === 'AddToCart') {
|
925
|
+
clickedProducts === null || clickedProducts === void 0 ? void 0 : clickedProducts.forEach((id) => {
|
926
|
+
setProductAction(destination, id, 'addToCart', true);
|
657
927
|
});
|
658
928
|
}
|
929
|
+
else if (eventName == 'RemoveFromCart') {
|
930
|
+
clickedProducts === null || clickedProducts === void 0 ? void 0 : clickedProducts.forEach((id) => {
|
931
|
+
setProductAction(destination, id, 'addToCart', false);
|
932
|
+
});
|
933
|
+
}
|
934
|
+
return {
|
935
|
+
session: getProductActions(destination),
|
936
|
+
preview: hasPreviewKey(),
|
937
|
+
isShopGPTLoaded: (_a = getShopGPTLoaded(destination)) !== null && _a !== void 0 ? _a : false,
|
938
|
+
};
|
659
939
|
};
|
660
940
|
|
661
941
|
// eslint-disable-next-line @nx/enforce-module-boundaries
|
662
942
|
const data = {
|
663
943
|
name: packageName,
|
664
944
|
init,
|
945
|
+
tag,
|
665
946
|
};
|
666
947
|
try {
|
667
948
|
if (typeof window !== 'undefined') {
|
@@ -874,6 +1155,29 @@ const shopGPTStyles = i$4 `
|
|
874
1155
|
line-height: 150%;
|
875
1156
|
}
|
876
1157
|
|
1158
|
+
.nudge {
|
1159
|
+
position: absolute;
|
1160
|
+
color: var(--shopgpt-secondary);
|
1161
|
+
padding: 12px 16px;
|
1162
|
+
font-size: 16px;
|
1163
|
+
line-height: 21px;
|
1164
|
+
background: var(--shopgpt-warning);
|
1165
|
+
border-radius: 5px;
|
1166
|
+
box-shadow: 0px 4px 6px -1px rgba(0, 0, 0, 0.1),
|
1167
|
+
0px 2px 4px -1px rgba(0, 0, 0, 0.06);
|
1168
|
+
font-weight: 400;
|
1169
|
+
line-height: 150%;
|
1170
|
+
right: calc(100% + 10px);
|
1171
|
+
top: 0%;
|
1172
|
+
transform: translateY(-50%);
|
1173
|
+
animation: slideIn 0.5s ease-out forwards;
|
1174
|
+
opacity: 0;
|
1175
|
+
cursor: pointer;
|
1176
|
+
width: 260px;
|
1177
|
+
white-space: normal;
|
1178
|
+
word-wrap: break-word;
|
1179
|
+
}
|
1180
|
+
|
877
1181
|
&:hover {
|
878
1182
|
.chatbot-hover-text {
|
879
1183
|
opacity: 1;
|
@@ -881,6 +1185,17 @@ const shopGPTStyles = i$4 `
|
|
881
1185
|
}
|
882
1186
|
}
|
883
1187
|
|
1188
|
+
@keyframes slideIn {
|
1189
|
+
from {
|
1190
|
+
transform: translate(20px, -50%);
|
1191
|
+
opacity: 0;
|
1192
|
+
}
|
1193
|
+
to {
|
1194
|
+
transform: translate(0, -50%);
|
1195
|
+
opacity: 1;
|
1196
|
+
}
|
1197
|
+
}
|
1198
|
+
|
884
1199
|
.mobile-version {
|
885
1200
|
display: none;
|
886
1201
|
|
@@ -1631,19 +1946,38 @@ class ProductItem extends r$2 {
|
|
1631
1946
|
<p class="product-variation-details">${option.name}: ${option.value}</p>
|
1632
1947
|
`);
|
1633
1948
|
}
|
1949
|
+
productClicked(productId, price, url) {
|
1950
|
+
if (productId) {
|
1951
|
+
this.dispatchEvent(new CustomEvent('product-clicked', {
|
1952
|
+
detail: {
|
1953
|
+
productId,
|
1954
|
+
value: price ? parseFloat(price) : undefined,
|
1955
|
+
},
|
1956
|
+
composed: true,
|
1957
|
+
bubbles: true,
|
1958
|
+
}));
|
1959
|
+
}
|
1960
|
+
this.redirect(url);
|
1961
|
+
}
|
1634
1962
|
render() {
|
1635
1963
|
return x `
|
1636
1964
|
<div class="product">
|
1637
1965
|
<img
|
1638
1966
|
src=${this.product.image.url}
|
1639
1967
|
alt=${this.product.image.alt}
|
1640
|
-
@click=${() => {
|
1968
|
+
@click=${() => {
|
1969
|
+
var _a;
|
1970
|
+
return this.productClicked(this.product.id, this.product.variants[0].price, (_a = this.product) === null || _a === void 0 ? void 0 : _a.url);
|
1971
|
+
}}
|
1641
1972
|
/>
|
1642
1973
|
<div class="content">
|
1643
1974
|
<p
|
1644
1975
|
class="product-name"
|
1645
1976
|
title=${this.product.title}
|
1646
|
-
@click=${() => {
|
1977
|
+
@click=${() => {
|
1978
|
+
var _a;
|
1979
|
+
return this.productClicked(this.product.id, this.product.variants[0].price, (_a = this.product) === null || _a === void 0 ? void 0 : _a.url);
|
1980
|
+
}}
|
1647
1981
|
>
|
1648
1982
|
${this.product.title}
|
1649
1983
|
</p>
|
@@ -1654,7 +1988,10 @@ class ProductItem extends r$2 {
|
|
1654
1988
|
</div>
|
1655
1989
|
<button
|
1656
1990
|
class="btn-view-product"
|
1657
|
-
@click=${() => {
|
1991
|
+
@click=${() => {
|
1992
|
+
var _a;
|
1993
|
+
return this.productClicked(this.product.id, this.product.variants[0].price, (_a = this.product) === null || _a === void 0 ? void 0 : _a.url);
|
1994
|
+
}}
|
1658
1995
|
>
|
1659
1996
|
View Product
|
1660
1997
|
</button>
|
@@ -2460,6 +2797,22 @@ const chatSectionStyles = i$4 `
|
|
2460
2797
|
const capitalizeEachWord = (str) => {
|
2461
2798
|
return str === null || str === void 0 ? void 0 : str.replace(/^\w/, (char) => char.toUpperCase());
|
2462
2799
|
};
|
2800
|
+
const adParams = new Set([
|
2801
|
+
'fbclid',
|
2802
|
+
'gclid',
|
2803
|
+
'sccid',
|
2804
|
+
'ttclid',
|
2805
|
+
'epik',
|
2806
|
+
'li_fat_id',
|
2807
|
+
'twclid',
|
2808
|
+
'rdt_cid',
|
2809
|
+
'aleid',
|
2810
|
+
'tabclid',
|
2811
|
+
'msclkid',
|
2812
|
+
'dclid',
|
2813
|
+
'wbraid',
|
2814
|
+
]);
|
2815
|
+
const isFromAd = (params) => [...params.keys()].some((key) => adParams.has(key.toLowerCase()));
|
2463
2816
|
|
2464
2817
|
const plusBtn = b `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
|
2465
2818
|
<path d="M12.75 11.25V6H11.25V11.25H6V12.75H11.25V18H12.75V12.75H18V11.25H12.75Z" fill="white"/>
|
@@ -3516,6 +3869,7 @@ class FeedbackDialog extends r$2 {
|
|
3516
3869
|
this.dispatchEvent(new CustomEvent('submit-feedback', {
|
3517
3870
|
detail: {
|
3518
3871
|
messageId: this.messageId,
|
3872
|
+
threadId: this.threadId,
|
3519
3873
|
feedback,
|
3520
3874
|
},
|
3521
3875
|
composed: true,
|
@@ -3587,6 +3941,10 @@ __decorate([
|
|
3587
3941
|
n({ type: String }),
|
3588
3942
|
__metadata("design:type", Object)
|
3589
3943
|
], FeedbackDialog.prototype, "messageId", void 0);
|
3944
|
+
__decorate([
|
3945
|
+
n({ type: String }),
|
3946
|
+
__metadata("design:type", Object)
|
3947
|
+
], FeedbackDialog.prototype, "threadId", void 0);
|
3590
3948
|
__decorate([
|
3591
3949
|
n({ type: String }),
|
3592
3950
|
__metadata("design:type", Object)
|
@@ -3619,19 +3977,26 @@ class ChatSection extends r$2 {
|
|
3619
3977
|
behavior: 'smooth',
|
3620
3978
|
});
|
3621
3979
|
}
|
3622
|
-
async processMessage(e, message) {
|
3980
|
+
async processMessage(e, message, isPrompt = false) {
|
3623
3981
|
this.scrollToBottom();
|
3624
3982
|
if (!this.thread) {
|
3625
3983
|
await this.createChatThread({ title: '' }, false);
|
3626
3984
|
}
|
3627
|
-
await this.sendMessageToServer(e, message);
|
3985
|
+
await this.sendMessageToServer(e, message, isPrompt);
|
3986
|
+
}
|
3987
|
+
sendEvent(action, actionData) {
|
3988
|
+
this.dispatchEvent(new CustomEvent('send-event', {
|
3989
|
+
detail: { action, actionData },
|
3990
|
+
composed: true,
|
3991
|
+
bubbles: true,
|
3992
|
+
}));
|
3628
3993
|
}
|
3629
3994
|
async onSubmit(e) {
|
3630
3995
|
var _a;
|
3631
3996
|
e.preventDefault();
|
3632
3997
|
const message = (_a = this.userQuery) === null || _a === void 0 ? void 0 : _a.trim();
|
3633
3998
|
this.userQuery = '';
|
3634
|
-
await this.processMessage(e, message);
|
3999
|
+
await this.processMessage(e, message, false);
|
3635
4000
|
}
|
3636
4001
|
handleThreadDelete() {
|
3637
4002
|
if (this.deleteAllThreads) {
|
@@ -3653,13 +4018,19 @@ class ChatSection extends r$2 {
|
|
3653
4018
|
this.deleteThreadId = '';
|
3654
4019
|
}
|
3655
4020
|
handleFeedback(rating, messageId, comment) {
|
4021
|
+
var _a, _b;
|
3656
4022
|
if (rating === 'bad') {
|
3657
|
-
this.feedbackDetails = {
|
4023
|
+
this.feedbackDetails = {
|
4024
|
+
messageId,
|
4025
|
+
threadId: ((_a = this.thread) === null || _a === void 0 ? void 0 : _a.threadId) || '',
|
4026
|
+
comment,
|
4027
|
+
};
|
3658
4028
|
return;
|
3659
4029
|
}
|
3660
4030
|
this.dispatchEvent(new CustomEvent('submit-feedback', {
|
3661
4031
|
detail: {
|
3662
4032
|
messageId: messageId,
|
4033
|
+
threadId: (_b = this.thread) === null || _b === void 0 ? void 0 : _b.threadId,
|
3663
4034
|
feedback: {
|
3664
4035
|
rating,
|
3665
4036
|
comment: null,
|
@@ -3806,7 +4177,10 @@ class ChatSection extends r$2 {
|
|
3806
4177
|
return x `
|
3807
4178
|
<div
|
3808
4179
|
class="prompt"
|
3809
|
-
@click=${(e) =>
|
4180
|
+
@click=${(e) => {
|
4181
|
+
this.processMessage(e, prompt, true);
|
4182
|
+
this.sendEvent('promptClicked');
|
4183
|
+
}}
|
3810
4184
|
>
|
3811
4185
|
${prompt}
|
3812
4186
|
</div>
|
@@ -3814,7 +4188,13 @@ class ChatSection extends r$2 {
|
|
3814
4188
|
})}
|
3815
4189
|
${o$1(customPrompts, ({ prompt, link }) => {
|
3816
4190
|
return x `
|
3817
|
-
<a
|
4191
|
+
<a
|
4192
|
+
class="prompt"
|
4193
|
+
href=${link}
|
4194
|
+
target="_blank"
|
4195
|
+
rel="noopener"
|
4196
|
+
@click=${() => this.sendEvent('promptClicked')}
|
4197
|
+
>
|
3818
4198
|
${prompt}
|
3819
4199
|
</a>
|
3820
4200
|
`;
|
@@ -4090,7 +4470,10 @@ class ChatSection extends r$2 {
|
|
4090
4470
|
</form>
|
4091
4471
|
${this.viewType === 'modal'
|
4092
4472
|
? x ` <footer>
|
4093
|
-
Powered by
|
4473
|
+
Powered by
|
4474
|
+
<a target="_blank" href="https://shopgpt.edgeagents.ai"
|
4475
|
+
>Blotout</a
|
4476
|
+
>
|
4094
4477
|
</footer>`
|
4095
4478
|
: E}
|
4096
4479
|
</div>
|
@@ -4130,6 +4513,7 @@ class ChatSection extends r$2 {
|
|
4130
4513
|
? x `
|
4131
4514
|
<feedback-dialog
|
4132
4515
|
.messageId=${this.feedbackDetails.messageId}
|
4516
|
+
.threadId=${this.feedbackDetails.threadId}
|
4133
4517
|
.comment=${this.feedbackDetails.comment}
|
4134
4518
|
@submit-feedback=${() => {
|
4135
4519
|
this.feedbackDetails = undefined;
|
@@ -4249,13 +4633,22 @@ if (!customElements.get('chat-section')) {
|
|
4249
4633
|
customElements.define('chat-section', ChatSection);
|
4250
4634
|
}
|
4251
4635
|
|
4636
|
+
async function* streamToIterable(stream) {
|
4637
|
+
const reader = stream.getReader();
|
4638
|
+
while (true) {
|
4639
|
+
const { done, value } = await reader.read();
|
4640
|
+
if (done)
|
4641
|
+
return;
|
4642
|
+
yield value;
|
4643
|
+
}
|
4644
|
+
}
|
4252
4645
|
const handleEventSource = async (response, onEvent) => {
|
4253
4646
|
var _a, _b;
|
4254
4647
|
if (!response.body) {
|
4255
4648
|
throw new Error('No body found in response');
|
4256
4649
|
}
|
4257
4650
|
let buffer = '';
|
4258
|
-
for await (const chunk of response.body.pipeThrough(new TextDecoderStream())) {
|
4651
|
+
for await (const chunk of streamToIterable(response.body.pipeThrough(new TextDecoderStream()))) {
|
4259
4652
|
buffer += chunk;
|
4260
4653
|
const sections = buffer.split('\n\n');
|
4261
4654
|
buffer = sections.pop() || '';
|
@@ -4298,12 +4691,15 @@ const parseMessage = (message, parseDataAsJSON) => {
|
|
4298
4691
|
return result;
|
4299
4692
|
};
|
4300
4693
|
|
4694
|
+
const soothingWaterDropSound = 'data:audio/mpeg;base64,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iBeym4zYFAAkYAVmuxNNv+v7c+5J93kKUxDKOKWyMt3ZVsrLlNp3Ib///////7s611TkOqXWZl3uhSiSOQewv1FYTZFKdhJVZBMgiKlDgeGlFFOoqUzGFzKYeAg0RO4QCQcFYedRiB5hURMHA6HQkKGqCXYGAAAAABGgApJl0h7bdv/r82S1SFSqqfmOjO4Wm5alsNMFG/////b9dVlyWpEKmqe9aHhMak+HhGsqBxxQOCxAeEChIKHAKEuwM4PIAACtABSTNSHt//uURO6CIqCNR2qAE/pZMgjtUAJ+DWJBF6oE2cG0yCL1QBX4t2rX16KCd9t30sqUWzrubZLKdC9a3az71olrf//////////T/t0Pp3IzIqdpblOje9GO7Vq6MhpGbRjEdEe4dgUA6KIBGwAq9dj2r///////////6W/eDhP1ZcjzJWbcDYTA0WE///////8uT5Zf9azM11Vxps81NTe63cJduNWlkq5ShrwPgRqhhppVlmu6EHCxk5tqaLA4HSCrD1D0gaM2QTGwJB4jiiCRsAKvXY9q7///////////8pPXQrb9l97FaKqad0uiKqLfVOqE////////W6JfMjW2K+v6bfFIfEspmm2OPb5lv/Z7llsUapI0XhNl30zkDXTZIq0aKBUSy9ImIjqwkOIZGymx8KTVFCDEAFAAbQAPquiW9Xb9v/+r///////X5cpV5I9ZjVCEsMyBIJ7LqqX//////Mv6JSLfFev2nda4Zrx8Km2io+FM1XRobWl0v4DX//uURNmGYkU6SHqAE/hREakPUAKbTLI/F6oFGcGhR6L1QRs5Ao+prOmkimTgXyZNBA1DB6wUnLlJJGijDhQCSMBRQIpycHiihiCAABxoAH1XRJfOdv2/f///////+1/PekqIdq7KiLDq7sOxJjr1q3O6Pf62///////6n2mfT7/m5GN2p2XnmlemqGhc2+zu+2KlsjnPBMFsfHHG0IcposI7mkSiMo6zJ8/UDkOe8jSY4aefp5AUQQCgVsAKrXRNN+3+n/////////5eAyMgGMzOqlnUebFkm5rRSdiUSHX///////8iM+fHvc/b/P3drfb+G3XZJqmV+sqzaxiSUGkD7zYktN+kcKPZZh0lEDTiybgbECfnAeO5Rjl7FbZAYQACi1sAKrXNS5v/+tvr6vIhqleWdHN22tT3b60XZ6ZE0VU///////3m9JJvsdKUs7I5M52kR2Z0UjRyHGGq4kwgOFmOwmUwDB9WExESOivUVYouLEMg0sTcOiAycKIY//ukRNOCI22QRWqBNnBvcgitUEbODTpBF6oE2cGUyCL1QBagWGgRQ4oYSjAAAACIgBTjQPba9f2lZF1qSU6EWjIc5mlMxtmV6HUrOdSMV3QtdVb////////+1eV3dWkZbkZjyDllIlWOplzrGMNynsyIVHMdDHOchzKQIoxhRBkXQxVYy3Rx9g8JEHEoAAAAAtgAU4zQq7a/99PZkdndankap3PkTmIJyUR56VnXRrV////////5fvyt+1L6OVKmWplIUtxJXj0UeR2PNO4kgmiJOQWOGjRyWMZWKxROY4aYzlcTDg8wmEhW4IABGwAq9cwapt9///////////oajVpKYiofa790LnJKO52cjGujXoxZVQs////////V8tJN9m7bt1nzMqHX3110dv6NVi+nmouWVGAqokJTckosMtmIQWSVPNCTjj5KUXBZBXVJpaBR9O5YJCRoNQrbEAAjQAVeuYNU2+///////////w1LsmB8PUySiIApz5pXEueQvL///////+oZBr5PMj9q25R7EantpRahl50b2unDPb6YZbjNWMWmIMZ1EM0nTgjkuZbkTRp+r50BQQsyY+HVGSFGu2nN6TTdEYYAAAAegD6rmDVd///////////9/Zn7//ukRNuCIw6QRuqAK/heEgjdUAV+Di5BFaoI2cG2SCK1QKc4vopluyIyIRjgjuRhyPT9+yZ/X//////b0Mnc5SF9bTxuv8x3b7TIIPb5VoVq3MQU6kDlEkkjzET0LWxJcL0GYEzSXsUes8UFGFkwoIBQesLIkmSOocchqWBgaRIjYgAAADoAfVcoNU3of//////////9k/KWWv/OGYSAzsXxKU4D6//z////+mdish1u/JQb2GVsH6rn8emS9X1iGEWpNqLZNE5A7uVblEsvWWTwSVznj0WXIJv16ZFiw20bUP2VXUExBHBlKqK8TtpicSjACyABTzsmZ7b////t7f/////skbIyzcvmO7kAxOZmFMONiogsDGSEkAZf///////5aMv8+cO5F5+Z1Vgd96JswiPNgwOh1CzUOochYq4d+I5M4A+B6sDGIXhhQCQwtFVKqCglEgowAAB6gFPO1e3oN907XqtPzOxGYqWndnVEqjmc7ohp6LJVZ7Vndf////////6+Wr6qrElOixGNY6TGQUdxIYxDVI5o4ysVqUZCniJhlo8PTDI8OCwmhzECDh1jxIimK4fEih/BQBuAALGAFOMfNEwq1f+hvTSX/VdkMWhU3m3NYhFFlW9Fot7L//ukROoEA5+QROKCNnBvkgicUCnODNZBGaoEecGPyCMxQBW8uZ1Wv//////+/6p96rRtKKiLSpVVplPIdXdlaYOB5GO7tlmF1FB0hiIZhylQxIi4Fh5Rx1FRYeOINMLDAcRUoiHCjXCgAAAAREAKSZZ1Vav7PVbNTNa9lqpKEVltRD6rZL+6J2RFT/////////p6du62ewPOqKxW3BsppGvO6IiCxRJpgamFsFSIAzIZArhGCqziTlKOrIRWLBuPKAABIiAFLMnHtV/95tGN6mfRCNOY102HIRndHoU6GVW3ya3ejU2b/////////6ptU+2l6UUWZCLVTVFHQqJdTEQyEbIOiysw0ggc4rkBCHKJOriaIg8SOPFJhpBASMDBUuAaMAGREmsMr/////7IdIDxh8owNTpM0LLMi8okxrBdE8//////+xt+1G4j9SgKi9i3JNykqKJFCIbC1RpAKAAAAI2AFTMn3U1fpVf//////////czlKQXntGnKNVMSoFpSEWiwjZFZf/////8PO5/3H3XGku1vWkaJLrzB++pZDtxRYrXSmvFb2IJUuzsSqoKixOKwaUo44sYzjAiYPaMH04c0SMQsaosgFAAAAEbACpmX6mr96v////////////uURPEEY0GQRmqALUBZEgjtUAJ/DAo9G6oArej0AaS9JIgEm7zzpZa8tDqh0YspmrZ0ZWVGop1cYm47B//////9PXdNzrfZvfkfXfS21te9i87xtU7m7Mmpi2PSIpnGF5Zvl0BAtJ7SoYdBygCieKTWmPqVFngcmoxCRM6SUiExSRg0kAAwCnmTle9//st2////////+/+EOfloy9FCeOQKHjY+dGzn///////+fj/f8l893LMZjUcjid21C9hvv5FPY7U8S1hS7g+Opw2XggyK4x0key5VXMk+C023IGFSFV+snynTukZQWugUABTzLlNrqS/V//////////yc1xk3S95nOjMHxSvQ0eJ2nP///////+cyq/+/zPjxr7H+ed+vpMrcb7h55+SReJ2SRMhLHaYUkWlqGlGn1BRx0iC2hSRg9iSZGL3ZIHEwSFkUMJoZ0AAAAACRgBTjJ1TWf////////////d3QjynB4DJKFkxsUTZW1Z6sxAn///////ukRO+DM2GQRWqBRnB10gitUEbODN5BFooFOcGfyCLRQJs4///qfmvuN/65eld5y/ypx6Xklc7ZpsozrhhtaqjXMy7NJxAFf52kCZepE9womyXLQWZ6OeG24aUolMe/AAAAARogBSTJ1SNB1f/3o0vS6EWzd70uhpmUYjFOjEdnorGZ2fZ2WitVf/////////1SRcp7MptCZSs9GWxmZ21VSzidBcg48YUP3LONGSEYhBKg5iDHJQWqOF2OwM5IZ2XAASQAKWZXd6VVeyuv75ddq6nI61cznMRrVnchZ1RZVViaM3///////sn/ptuqujo59KzjXkGsY5pRMpR67OPO4TEhw7ElDkzCphcaJoJKLCwsEVVRYTOQoSixBJQ4BzCrEFiCIztFAAsYAUszd3pVe3prWh08YzNszSIpmrQm7WTZz9e8jV////////tp0Oaq6tvdSIsjKs7HUqOQgo0hjpMRXJOIKJEOrRpFEiiruICjuODzud3ZCua4iNQcx2EzDXCFMgAAAOgCpmfXt///////////8/MiS5NKXgCdWeVyTrzQDo5SHB/////L/8srH5V7hDYX4+qncnZ9Y7pT1TXosbl5uxXqJWj8ZKzLZiBYdYmzkmjESxxDnYIM//uURPUCI0KQReqBNnBhkejdUAVvTNZBGaoAr8F9SCM1QBX4lJMsqjp6RM4e0gBGYVZRkSBCRRbEDkgAAAfAFTLn17V2r///////////0XR9LV7HWd1Ocp56OPkV7tVmTZkozp/T////+3VE1cpiu/2N7L+svbyZXZVJROcspHq9k93SklZKcgd+T5qclemWmUVUYWmoRzSH2JEeIh5kPQJkRwyK7ttRGIiZpCVvny6WEQskAAdAoACpEniCmxqkip1f/6yfUpa///zEYy////2W4doWS8C4DszAA2zMZnMDs5w6ep5////+8qRQwAfUPZSu/7pPJfMTYaMblJ1APmE0aBKaZCmsgbYRKLulJRa2B0uvbaFpZGVNK+KLzXKsNlSpGolJkeLqiojiPLoyxowJxdY0UQkwscAAlAoDZAAVIk8QU2NUlqdX/6k1l9Wr//+6nJ////Qmzre50qpjud6oFM5MjupkSb3SitRetX9P+n///rtuq3azK3xm19h8//u0RNsBA3KQRMqBTnB58gicUEnOELJBEaoFOcIjyCI1QSc4jN05t1bVPjsimzhHwlpZ2Et5FWc8iKlSza6OBE2oefFEQomyXzXJgqVZQCptpokVONECKbMyeCAtAo5cTEAmSWVRAAAQhlIAHYHhywnUgyKX//czJs4////Ohjf/6a5L07HLsmTuLJeqkspbSMzyN1Vn92S7o1VtJ3PT///W3ojVkndw4IqoJmC/as1+V0F0NhyExr8dXVEZ0scrQoLGRWeFds7ZZSKfPnWSebHrjhTHhe2VCQOCLGTx5IK0p6g2JooHlWiVoR0ifLLK8Okg/lI9XefLTuxZJBfClxgAAQAQBIAAegqF1QuEixql//1pk2c///85DG////+1HXLux8azIrh3Ei3IjGKRXmdWctF0tbv7M2j+/v/T9ur3dOplKbfcpB/t5r0MLPwu3on23Rw1Mmr3Pbtrjy7CWb38nHaxxtsO0kLB2fOqkQteq6+4pKy+wgvuJqxIRqhFYyEsKTgHiwPiozOyeJI+tHJ7TUIhWIAABgBeDtjyVkf//RUkv//+Yn////////wi3IXxOKH5Cfk/mv//////zCTCs8pSl/5S///tZFqsYxjnlqrKzUlorCpqiJq40RNUia9qylsalKSLLoiehQsrQFR0SiI1AVE0VASPuRTQodQs1vtDCMgAAIBgAAAUghyMUkf//qS///zEL///////81//f+zD5CNC4TRfn////kzXxM/E8lt/uPpEinGrqKFl//u0RO2DBNSQQuKCZnCVsghtUEzODe5BDIgFOcHeyCFw0Kc4ZFJbfGviyLVYYIg1NmSxoQvQpItuMcKkqSLbQoUKwqXFLpWhhGmvIqCJLhUMnGyUs24VHB4KmUSwWBIVKkxBTUUzLjEwMKqqqqqqqqqqqqqqqqqqqqqqqqpMQU1FMy4xMDCqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq//sUZOGP8AAAf4AAAAgAAA/wAAABAAABpAAAACAAADSAAAAEqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq';
|
4695
|
+
|
4301
4696
|
const DIALOG_DELAY = 1000;
|
4302
4697
|
const normalizePath = (path) => path.replace(/\/$/, '');
|
4303
4698
|
class ShopGPT extends r$2 {
|
4304
4699
|
constructor() {
|
4305
4700
|
super(...arguments);
|
4306
4701
|
this.isStylesheetInjected = false;
|
4702
|
+
this.isPreviousMessagePrompt = false;
|
4307
4703
|
this.latestThreadLoad = DEFAULT_MAX_THREAD_AGE;
|
4308
4704
|
this.modalState = 'close';
|
4309
4705
|
this.isLoadingHistory = false;
|
@@ -4315,6 +4711,8 @@ class ShopGPT extends r$2 {
|
|
4315
4711
|
this.messages = [];
|
4316
4712
|
this.chatThreads = new Map();
|
4317
4713
|
this.customPrompts = [];
|
4714
|
+
this.hasUserInteracted = false;
|
4715
|
+
this.showNudge = false;
|
4318
4716
|
this.loadData = async () => {
|
4319
4717
|
if (!this.shopGPTAPI) {
|
4320
4718
|
return;
|
@@ -4355,17 +4753,23 @@ class ShopGPT extends r$2 {
|
|
4355
4753
|
}
|
4356
4754
|
}
|
4357
4755
|
this.init();
|
4756
|
+
this.startNudgeTimer();
|
4358
4757
|
}
|
4359
4758
|
disconnectedCallback() {
|
4360
4759
|
window.removeEventListener('edgetag-initialized', this.loadData);
|
4361
4760
|
window.removeEventListener('popstate', this.onPopState);
|
4761
|
+
if (this.nudgeTimer) {
|
4762
|
+
window.clearTimeout(this.nudgeTimer);
|
4763
|
+
}
|
4362
4764
|
super.disconnectedCallback();
|
4363
4765
|
}
|
4364
4766
|
init() {
|
4365
4767
|
window.addEventListener('edgetag-initialized', this.loadData);
|
4366
4768
|
window.addEventListener('popstate', this.onPopState);
|
4769
|
+
this.shopGPTAPI.sendEvent('shopGPTInitialized', this.getSiteCurrency().currency);
|
4367
4770
|
if (!this.view || this.view === 'overlay') {
|
4368
|
-
delay(DIALOG_DELAY)
|
4771
|
+
delay(DIALOG_DELAY)
|
4772
|
+
.then(() => {
|
4369
4773
|
var _a;
|
4370
4774
|
if (document.hidden) {
|
4371
4775
|
document.addEventListener('visibilitychange', () => { var _a; return (_a = this.shopGPTDialog) === null || _a === void 0 ? void 0 : _a.showModal(); }, {
|
@@ -4375,7 +4779,8 @@ class ShopGPT extends r$2 {
|
|
4375
4779
|
else {
|
4376
4780
|
(_a = this.shopGPTDialog) === null || _a === void 0 ? void 0 : _a.showModal();
|
4377
4781
|
}
|
4378
|
-
})
|
4782
|
+
})
|
4783
|
+
.catch(logger.error);
|
4379
4784
|
}
|
4380
4785
|
}
|
4381
4786
|
setChatTitle(threadId, title) {
|
@@ -4403,8 +4808,8 @@ class ShopGPT extends r$2 {
|
|
4403
4808
|
if (!thread) {
|
4404
4809
|
return;
|
4405
4810
|
}
|
4406
|
-
const
|
4407
|
-
const fromAd =
|
4811
|
+
const searchParams = new URLSearchParams(window.location.search);
|
4812
|
+
const fromAd = isFromAd(searchParams) || searchParams.get('shopGPT') === '1';
|
4408
4813
|
const productHandle = this.devMode
|
4409
4814
|
? (_a = thread === null || thread === void 0 ? void 0 : thread.devContext) === null || _a === void 0 ? void 0 : _a.productHandle
|
4410
4815
|
: fromAd
|
@@ -4641,7 +5046,7 @@ class ShopGPT extends r$2 {
|
|
4641
5046
|
}
|
4642
5047
|
});
|
4643
5048
|
}
|
4644
|
-
async sendMessageToServer(e, message) {
|
5049
|
+
async sendMessageToServer(e, message, isPrompt = false) {
|
4645
5050
|
e.preventDefault();
|
4646
5051
|
e.stopPropagation();
|
4647
5052
|
if (!message || this.isTyping || this.isLoadingHistory) {
|
@@ -4649,6 +5054,10 @@ class ShopGPT extends r$2 {
|
|
4649
5054
|
}
|
4650
5055
|
this.isFailed = false;
|
4651
5056
|
try {
|
5057
|
+
this.isPreviousMessagePrompt = isPrompt;
|
5058
|
+
if (!isPrompt) {
|
5059
|
+
this.shopGPTAPI.sendEvent('queryInteractions', this.getSiteCurrency().currency);
|
5060
|
+
}
|
4652
5061
|
this.messages = [{ sender: 'user', message }, ...this.messages];
|
4653
5062
|
this.isTyping = true;
|
4654
5063
|
const response = await this.submitQuery(message);
|
@@ -4663,7 +5072,7 @@ class ShopGPT extends r$2 {
|
|
4663
5072
|
submitFeedback(e) {
|
4664
5073
|
e.stopPropagation();
|
4665
5074
|
this.shopGPTAPI
|
4666
|
-
.saveFeedback(e.detail.messageId, e.detail.feedback)
|
5075
|
+
.saveFeedback(e.detail.messageId, e.detail.threadId, e.detail.feedback)
|
4667
5076
|
.then(() => {
|
4668
5077
|
const messages = this.messages;
|
4669
5078
|
const messageIndex = messages.findIndex(({ messageId }) => messageId === e.detail.messageId);
|
@@ -4672,17 +5081,25 @@ class ShopGPT extends r$2 {
|
|
4672
5081
|
feedback: e.detail.feedback,
|
4673
5082
|
};
|
4674
5083
|
this.messages = [...messages];
|
5084
|
+
})
|
5085
|
+
.catch(logger.error);
|
5086
|
+
}
|
5087
|
+
sendEvent(e) {
|
5088
|
+
e.stopPropagation();
|
5089
|
+
this.shopGPTAPI.sendEvent(e.detail.action, this.getSiteCurrency().currency, e.detail.actionData);
|
5090
|
+
}
|
5091
|
+
productClicked(e) {
|
5092
|
+
e.stopPropagation();
|
5093
|
+
setProductAction(this.destination, e.detail.productId, 'clicked', true);
|
5094
|
+
this.shopGPTAPI.sendEvent('productRecommendationClicked', this.getSiteCurrency().currency, {
|
5095
|
+
productId: e.detail.productId,
|
5096
|
+
value: e.detail.value,
|
5097
|
+
isPrompt: this.isPreviousMessagePrompt,
|
4675
5098
|
});
|
4676
5099
|
}
|
4677
5100
|
getSiteCurrency() {
|
4678
5101
|
return this.storeAPI.getSiteCurrency();
|
4679
5102
|
}
|
4680
|
-
render() {
|
4681
|
-
if (this.view === 'modal') {
|
4682
|
-
return this.modalMode();
|
4683
|
-
}
|
4684
|
-
return this.overlayMode();
|
4685
|
-
}
|
4686
5103
|
overlayMode() {
|
4687
5104
|
const thread = this.chatThreads.get(this.selectedThreadId);
|
4688
5105
|
return x `
|
@@ -4691,6 +5108,8 @@ class ShopGPT extends r$2 {
|
|
4691
5108
|
@delete-thread=${this.handleThreadDelete}
|
4692
5109
|
@delete-all-threads=${this.handleAllThreadsDelete}
|
4693
5110
|
@submit-feedback=${this.submitFeedback}
|
5111
|
+
@send-event=${this.sendEvent}
|
5112
|
+
@product-clicked=${this.productClicked}
|
4694
5113
|
>
|
4695
5114
|
<div class="mobile-version">
|
4696
5115
|
Please switch to the desktop version for the best experience.
|
@@ -4738,6 +5157,7 @@ class ShopGPT extends r$2 {
|
|
4738
5157
|
`;
|
4739
5158
|
}
|
4740
5159
|
modalMode() {
|
5160
|
+
var _a;
|
4741
5161
|
const thread = this.chatThreads.get(this.selectedThreadId);
|
4742
5162
|
const closeModal = () => {
|
4743
5163
|
this.modalState = 'close';
|
@@ -4747,12 +5167,28 @@ class ShopGPT extends r$2 {
|
|
4747
5167
|
<button
|
4748
5168
|
@click=${(e) => {
|
4749
5169
|
e.preventDefault();
|
5170
|
+
this.shopGPTAPI.sendEvent('chatbotOpened', this.getSiteCurrency().currency);
|
4750
5171
|
this.modalState = 'open';
|
5172
|
+
this.handleUserInteraction();
|
4751
5173
|
}}
|
4752
5174
|
>
|
4753
5175
|
${chatIcon}
|
4754
5176
|
</button>
|
4755
|
-
|
5177
|
+
${((_a = this.nudge) === null || _a === void 0 ? void 0 : _a.show) && this.showNudge
|
5178
|
+
? x `<div
|
5179
|
+
class="nudge"
|
5180
|
+
@click=${(e) => {
|
5181
|
+
e.preventDefault();
|
5182
|
+
this.modalState = 'open';
|
5183
|
+
this.handleUserInteraction();
|
5184
|
+
}}
|
5185
|
+
>
|
5186
|
+
Hi there! I'm an AI Agent to help you find the perfect product.
|
5187
|
+
What are you looking for today?
|
5188
|
+
</div>`
|
5189
|
+
: x `<div class="chatbot-hover-text">
|
5190
|
+
What are you looking for today?
|
5191
|
+
</div>`}
|
4756
5192
|
</div>`;
|
4757
5193
|
}
|
4758
5194
|
return x `
|
@@ -4761,6 +5197,9 @@ class ShopGPT extends r$2 {
|
|
4761
5197
|
@delete-thread=${this.handleThreadDelete}
|
4762
5198
|
@delete-all-threads=${this.handleAllThreadsDelete}
|
4763
5199
|
@submit-feedback=${this.submitFeedback}
|
5200
|
+
@click=${this.handleUserInteraction}
|
5201
|
+
@send-event=${this.sendEvent}
|
5202
|
+
@product-clicked=${this.productClicked}
|
4764
5203
|
>
|
4765
5204
|
<chat-section
|
4766
5205
|
.prompts=${this.quickPrompts}
|
@@ -4789,6 +5228,48 @@ class ShopGPT extends r$2 {
|
|
4789
5228
|
</div>
|
4790
5229
|
`;
|
4791
5230
|
}
|
5231
|
+
startNudgeTimer() {
|
5232
|
+
var _a, _b;
|
5233
|
+
if (this.view !== 'modal' || !((_a = this.nudge) === null || _a === void 0 ? void 0 : _a.show)) {
|
5234
|
+
return;
|
5235
|
+
}
|
5236
|
+
this.hasUserInteracted = isUserInteracted(this.destination);
|
5237
|
+
if (this.hasUserInteracted || this.nudgeTimer) {
|
5238
|
+
return;
|
5239
|
+
}
|
5240
|
+
this.nudgeTimer = window.setTimeout(() => {
|
5241
|
+
if (!this.hasUserInteracted) {
|
5242
|
+
this.playNudgeSound();
|
5243
|
+
this.showNudge = true;
|
5244
|
+
}
|
5245
|
+
}, (((_b = this.nudge) === null || _b === void 0 ? void 0 : _b.timeout) || DEFAULT_NUDGE_TIMEOUT) * 1000);
|
5246
|
+
}
|
5247
|
+
playNudgeSound() {
|
5248
|
+
var _a;
|
5249
|
+
if (!((_a = this.nudge) === null || _a === void 0 ? void 0 : _a.sound) || !navigator.userActivation.hasBeenActive) {
|
5250
|
+
return;
|
5251
|
+
}
|
5252
|
+
const audio = new Audio(soothingWaterDropSound);
|
5253
|
+
audio
|
5254
|
+
.play()
|
5255
|
+
.catch((error) => logger.error('Error playing nudge sound', error));
|
5256
|
+
}
|
5257
|
+
handleUserInteraction() {
|
5258
|
+
if (!this.hasUserInteracted) {
|
5259
|
+
this.hasUserInteracted = true;
|
5260
|
+
this.showNudge = false;
|
5261
|
+
if (this.nudgeTimer) {
|
5262
|
+
window.clearTimeout(this.nudgeTimer);
|
5263
|
+
}
|
5264
|
+
setUserInteracted(this.destination);
|
5265
|
+
}
|
5266
|
+
}
|
5267
|
+
render() {
|
5268
|
+
if (this.view === 'modal') {
|
5269
|
+
return this.modalMode();
|
5270
|
+
}
|
5271
|
+
return this.overlayMode();
|
5272
|
+
}
|
4792
5273
|
}
|
4793
5274
|
ShopGPT.styles = [shopGPTStyles];
|
4794
5275
|
__decorate([
|
@@ -4839,6 +5320,14 @@ __decorate([
|
|
4839
5320
|
n({ type: Array }),
|
4840
5321
|
__metadata("design:type", Array)
|
4841
5322
|
], ShopGPT.prototype, "customPrompts", void 0);
|
5323
|
+
__decorate([
|
5324
|
+
r(),
|
5325
|
+
__metadata("design:type", Object)
|
5326
|
+
], ShopGPT.prototype, "hasUserInteracted", void 0);
|
5327
|
+
__decorate([
|
5328
|
+
r(),
|
5329
|
+
__metadata("design:type", Object)
|
5330
|
+
], ShopGPT.prototype, "showNudge", void 0);
|
4842
5331
|
if (!customElements.get('shop-gpt')) {
|
4843
5332
|
customElements.define('shop-gpt', ShopGPT);
|
4844
5333
|
}
|
@@ -4854,6 +5343,7 @@ if (typeof window != 'undefined' && typeof document != 'undefined') {
|
|
4854
5343
|
return;
|
4855
5344
|
}
|
4856
5345
|
shopGPT = document.createElement('shop-gpt');
|
5346
|
+
shopGPT.destination = params.destination;
|
4857
5347
|
shopGPT.storeAPI = params.storeAPI;
|
4858
5348
|
shopGPT.shopGPTAPI = params.shopGPTAPI;
|
4859
5349
|
shopGPT.devMode = params.devMode;
|
@@ -4868,12 +5358,25 @@ if (typeof window != 'undefined' && typeof document != 'undefined') {
|
|
4868
5358
|
shopGPT.latestThreadLoad = params.latestThreadLoad;
|
4869
5359
|
shopGPT.botIconUrl = params.botIconUrl;
|
4870
5360
|
shopGPT.css = params.css;
|
5361
|
+
shopGPT.nudge = params.nudge;
|
5362
|
+
},
|
5363
|
+
loadUI() {
|
5364
|
+
if (!shopGPT) {
|
5365
|
+
logger.error('ShopGPT component not found!');
|
5366
|
+
return;
|
5367
|
+
}
|
5368
|
+
if (shopGPT.parentNode) {
|
5369
|
+
logger.log('ShopGPT component added already!');
|
5370
|
+
return;
|
5371
|
+
}
|
4871
5372
|
document.body.append(shopGPT);
|
5373
|
+
setShopGPTLoaded(shopGPT.destination, true);
|
4872
5374
|
},
|
4873
5375
|
destroy() {
|
4874
5376
|
if (!shopGPT) {
|
4875
5377
|
return;
|
4876
5378
|
}
|
5379
|
+
setShopGPTLoaded(shopGPT.destination, false);
|
4877
5380
|
shopGPT.remove();
|
4878
5381
|
shopGPT = undefined;
|
4879
5382
|
delete window[registryKey];
|