@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.cjs.js
CHANGED
@@ -408,10 +408,65 @@ const createExperiment = (props) => {
|
|
408
408
|
}
|
409
409
|
};
|
410
410
|
|
411
|
+
const uiActions = new Set([
|
412
|
+
'shopGPTInitialized',
|
413
|
+
'chatbotOpened',
|
414
|
+
'queryInteractions',
|
415
|
+
'promptClicked',
|
416
|
+
'productRecommendationClicked',
|
417
|
+
]);
|
418
|
+
new Set([
|
419
|
+
...uiActions,
|
420
|
+
'pageView',
|
421
|
+
'productRecommendationViewed',
|
422
|
+
'productRecommendationAddedToCart',
|
423
|
+
'productRecommendationInitiatedCheckout',
|
424
|
+
'orderPlaced',
|
425
|
+
]);
|
426
|
+
|
411
427
|
const packageName = 'shopGPT';
|
412
|
-
const DEFAULT_MAX_THREAD_AGE = 14;
|
428
|
+
const DEFAULT_MAX_THREAD_AGE = 14; // in days
|
429
|
+
const DEFAULT_NUDGE_TIMEOUT = 10; // in seconds
|
413
430
|
const previewKeyName = 'previewShopGPT';
|
414
431
|
|
432
|
+
const keyPrefix = `_worker`;
|
433
|
+
|
434
|
+
const getCookieValue = (key) => {
|
435
|
+
var _a;
|
436
|
+
try {
|
437
|
+
if (!document || !document.cookie) {
|
438
|
+
return '';
|
439
|
+
}
|
440
|
+
const cookies = parseCookies(document.cookie);
|
441
|
+
return (_a = cookies[key]) !== null && _a !== void 0 ? _a : '';
|
442
|
+
}
|
443
|
+
catch {
|
444
|
+
return '';
|
445
|
+
}
|
446
|
+
};
|
447
|
+
const parseCookies = (cookie) => {
|
448
|
+
return Object.fromEntries(cookie
|
449
|
+
.split(/;\s+/)
|
450
|
+
.map((r) => r.split('=').map((str) => str.trim()))
|
451
|
+
.map(([cookieKey, ...cookieValues]) => {
|
452
|
+
const cookieValue = cookieValues.join('=');
|
453
|
+
if (!cookieKey) {
|
454
|
+
return [];
|
455
|
+
}
|
456
|
+
let decodedValue = '';
|
457
|
+
if (cookieValue) {
|
458
|
+
try {
|
459
|
+
decodedValue = decodeURIComponent(cookieValue);
|
460
|
+
}
|
461
|
+
catch (e) {
|
462
|
+
console.log(`Unable to decode cookie ${cookieKey}: ${e}`);
|
463
|
+
decodedValue = cookieValue;
|
464
|
+
}
|
465
|
+
}
|
466
|
+
return [cookieKey, decodedValue];
|
467
|
+
}));
|
468
|
+
};
|
469
|
+
|
415
470
|
const canLog = () => {
|
416
471
|
try {
|
417
472
|
return localStorage.getItem('edgeTagDebug') === '1';
|
@@ -444,12 +499,188 @@ const logger = {
|
|
444
499
|
},
|
445
500
|
};
|
446
501
|
|
502
|
+
const initKey = `${keyPrefix}StoreMultiple`;
|
503
|
+
const saveData = (destination, persistType, value, key = initKey) => {
|
504
|
+
if (persistType === 'session') {
|
505
|
+
const data = getSession(key);
|
506
|
+
data[destination] = value;
|
507
|
+
saveSession(data, key);
|
508
|
+
return;
|
509
|
+
}
|
510
|
+
const data = getLocal(key);
|
511
|
+
data[destination] = value;
|
512
|
+
saveLocal(data, key);
|
513
|
+
};
|
514
|
+
const getData = (destination, persistType, key = initKey) => {
|
515
|
+
let data;
|
516
|
+
if (persistType === 'session') {
|
517
|
+
data = getSession(key);
|
518
|
+
}
|
519
|
+
else {
|
520
|
+
data = getLocal(key);
|
521
|
+
}
|
522
|
+
return (data === null || data === void 0 ? void 0 : data[destination]) || {};
|
523
|
+
};
|
524
|
+
const saveLocal = (value, key) => {
|
525
|
+
try {
|
526
|
+
if (!localStorage) {
|
527
|
+
return;
|
528
|
+
}
|
529
|
+
localStorage.setItem(key, JSON.stringify(value));
|
530
|
+
}
|
531
|
+
catch {
|
532
|
+
logger.log('Local storage not supported.');
|
533
|
+
}
|
534
|
+
};
|
535
|
+
const getLocal = (key) => {
|
536
|
+
try {
|
537
|
+
if (!localStorage) {
|
538
|
+
return {};
|
539
|
+
}
|
540
|
+
const data = localStorage.getItem(key);
|
541
|
+
if (!data) {
|
542
|
+
return {};
|
543
|
+
}
|
544
|
+
return JSON.parse(data) || {};
|
545
|
+
}
|
546
|
+
catch {
|
547
|
+
return {};
|
548
|
+
}
|
549
|
+
};
|
550
|
+
const saveSession = (value, key) => {
|
551
|
+
try {
|
552
|
+
if (!sessionStorage) {
|
553
|
+
return;
|
554
|
+
}
|
555
|
+
sessionStorage.setItem(key, JSON.stringify(value));
|
556
|
+
}
|
557
|
+
catch {
|
558
|
+
logger.log('Session storage not supported.');
|
559
|
+
}
|
560
|
+
};
|
561
|
+
const getSession = (key) => {
|
562
|
+
try {
|
563
|
+
if (!sessionStorage) {
|
564
|
+
return {};
|
565
|
+
}
|
566
|
+
const data = sessionStorage.getItem(key);
|
567
|
+
if (!data) {
|
568
|
+
return {};
|
569
|
+
}
|
570
|
+
return JSON.parse(data) || {};
|
571
|
+
}
|
572
|
+
catch {
|
573
|
+
return {};
|
574
|
+
}
|
575
|
+
};
|
576
|
+
|
447
577
|
var _a$1;
|
448
578
|
const registryKey = Symbol.for('shop-gpt');
|
449
579
|
if (typeof window != 'undefined') {
|
450
580
|
(_a$1 = window[registryKey]) !== null && _a$1 !== void 0 ? _a$1 : (window[registryKey] = {});
|
451
581
|
}
|
452
582
|
|
583
|
+
const SHOP_GPT_SESSION_KEY = 'shopGPTSession';
|
584
|
+
const SHOP_GPT_LOCAL_STORAGE_KEY = 'shopGPTLocalStorage';
|
585
|
+
const getSessionData = (destination) => {
|
586
|
+
const session = getData(destination, 'session', SHOP_GPT_SESSION_KEY);
|
587
|
+
return session;
|
588
|
+
};
|
589
|
+
const saveSessionData = (destination, data) => {
|
590
|
+
saveData(destination, 'session', data, SHOP_GPT_SESSION_KEY);
|
591
|
+
};
|
592
|
+
const getLocalStorageData = (destination) => {
|
593
|
+
const local = getData(destination, 'local', SHOP_GPT_LOCAL_STORAGE_KEY);
|
594
|
+
return local;
|
595
|
+
};
|
596
|
+
const saveLocalStorageData = (destination, data) => {
|
597
|
+
saveData(destination, 'local', data, SHOP_GPT_LOCAL_STORAGE_KEY);
|
598
|
+
};
|
599
|
+
const getSessionId = () => {
|
600
|
+
return getCookieValue('tag_session');
|
601
|
+
};
|
602
|
+
|
603
|
+
// eslint-disable-next-line @nx/enforce-module-boundaries
|
604
|
+
const hasPreviewKey = () => {
|
605
|
+
var _a;
|
606
|
+
try {
|
607
|
+
return ((_a = sessionStorage.getItem(previewKeyName)) !== null && _a !== void 0 ? _a : '0') == '1';
|
608
|
+
}
|
609
|
+
catch {
|
610
|
+
return false;
|
611
|
+
}
|
612
|
+
};
|
613
|
+
const isUserInteracted = (destination) => {
|
614
|
+
var _a;
|
615
|
+
const session = getSessionData(destination);
|
616
|
+
return !!((_a = session === null || session === void 0 ? void 0 : session.chatbot) === null || _a === void 0 ? void 0 : _a.hasUserInteracted);
|
617
|
+
};
|
618
|
+
const setUserInteracted = (destination) => {
|
619
|
+
const session = getSessionData(destination);
|
620
|
+
saveSessionData(destination, {
|
621
|
+
...session,
|
622
|
+
chatbot: { ...session === null || session === void 0 ? void 0 : session.chatbot, hasUserInteracted: true },
|
623
|
+
});
|
624
|
+
};
|
625
|
+
const getProductActions = (destination) => {
|
626
|
+
var _a;
|
627
|
+
const local = getLocalStorageData(destination);
|
628
|
+
const sessionId = getSessionId();
|
629
|
+
if (!local || !sessionId) {
|
630
|
+
logger.error('No local storage data or session id');
|
631
|
+
return null;
|
632
|
+
}
|
633
|
+
return (_a = local[sessionId]) === null || _a === void 0 ? void 0 : _a.products;
|
634
|
+
};
|
635
|
+
const setProductAction = (destination, productId, action, value) => {
|
636
|
+
var _a, _b, _c;
|
637
|
+
const local = getLocalStorageData(destination);
|
638
|
+
const sessionId = getSessionId();
|
639
|
+
if (!local || !sessionId) {
|
640
|
+
logger.error('No local storage data or session id');
|
641
|
+
return;
|
642
|
+
}
|
643
|
+
const productTags = (_b = (_a = local[sessionId]) === null || _a === void 0 ? void 0 : _a.products) === null || _b === void 0 ? void 0 : _b[productId];
|
644
|
+
local[sessionId] = {
|
645
|
+
...local[sessionId],
|
646
|
+
products: {
|
647
|
+
...(_c = local[sessionId]) === null || _c === void 0 ? void 0 : _c.products,
|
648
|
+
[productId]: {
|
649
|
+
...productTags,
|
650
|
+
[action]: value,
|
651
|
+
},
|
652
|
+
},
|
653
|
+
};
|
654
|
+
// Clear other sessions
|
655
|
+
const updatedLocal = { [sessionId]: local[sessionId] };
|
656
|
+
saveLocalStorageData(destination, updatedLocal);
|
657
|
+
};
|
658
|
+
const getShopGPTLoaded = (destination) => {
|
659
|
+
var _a, _b;
|
660
|
+
const local = getLocalStorageData(destination);
|
661
|
+
const sessionId = getSessionId();
|
662
|
+
if (!local || !sessionId) {
|
663
|
+
logger.error('No local storage data or session id');
|
664
|
+
return false;
|
665
|
+
}
|
666
|
+
return (_b = (_a = local[sessionId]) === null || _a === void 0 ? void 0 : _a.isShopGPTLoaded) !== null && _b !== void 0 ? _b : false;
|
667
|
+
};
|
668
|
+
const setShopGPTLoaded = (destination, value) => {
|
669
|
+
const local = getLocalStorageData(destination);
|
670
|
+
const sessionId = getSessionId();
|
671
|
+
if (!local || !sessionId) {
|
672
|
+
logger.error('No local storage data or session id');
|
673
|
+
return;
|
674
|
+
}
|
675
|
+
local[sessionId] = {
|
676
|
+
...local[sessionId],
|
677
|
+
isShopGPTLoaded: value,
|
678
|
+
};
|
679
|
+
// Clear other sessions
|
680
|
+
const updatedLocal = { [sessionId]: local[sessionId] };
|
681
|
+
saveLocalStorageData(destination, updatedLocal);
|
682
|
+
};
|
683
|
+
|
453
684
|
const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, storeAPI, }) => {
|
454
685
|
if (!baseURL) {
|
455
686
|
throw new Error(`baseURL missing`);
|
@@ -552,13 +783,14 @@ const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, st
|
|
552
783
|
throw new Error(`Failed to delete all chat threads - ${response.status}: ${await response.text()}`);
|
553
784
|
}
|
554
785
|
};
|
555
|
-
const saveFeedback = async (messageId, feedback) => {
|
786
|
+
const saveFeedback = async (messageId, threadId, feedback) => {
|
556
787
|
const response = await fetchImpl(getURL('/feedback'), {
|
557
788
|
method: 'POST',
|
558
789
|
headers: getHeaders(),
|
559
790
|
credentials: 'include',
|
560
791
|
body: JSON.stringify({
|
561
792
|
messageId,
|
793
|
+
threadId,
|
562
794
|
feedback,
|
563
795
|
}),
|
564
796
|
});
|
@@ -578,6 +810,28 @@ const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, st
|
|
578
810
|
const data = (await response.json());
|
579
811
|
return data.customPrompts;
|
580
812
|
};
|
813
|
+
const sendEvent = async (action, currency, actionData) => {
|
814
|
+
var _a;
|
815
|
+
const storageData = (_a = getProductActions(baseURL)) !== null && _a !== void 0 ? _a : {};
|
816
|
+
const response = await fetchImpl(getURL('/user/event'), {
|
817
|
+
method: 'POST',
|
818
|
+
headers: getHeaders(true),
|
819
|
+
body: JSON.stringify({
|
820
|
+
action,
|
821
|
+
currency,
|
822
|
+
actionData,
|
823
|
+
storageData: {
|
824
|
+
session: storageData,
|
825
|
+
preview: hasPreviewKey(),
|
826
|
+
isShopGPTLoaded: true, // The fact that sendEvent was called means that the ShopGPT is loaded
|
827
|
+
},
|
828
|
+
}),
|
829
|
+
credentials: 'include',
|
830
|
+
});
|
831
|
+
if (!response.ok) {
|
832
|
+
throw new Error(`Error while recording user event - ${response.status}: ${response.statusText}\n\n${await response.text()}`);
|
833
|
+
}
|
834
|
+
};
|
581
835
|
return {
|
582
836
|
processQuery,
|
583
837
|
fetchChatHistory,
|
@@ -587,20 +841,12 @@ const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, st
|
|
587
841
|
deleteAllThreads,
|
588
842
|
saveFeedback,
|
589
843
|
fetchCustomPrompts,
|
844
|
+
sendEvent,
|
590
845
|
};
|
591
846
|
};
|
592
847
|
|
593
848
|
// eslint-disable-next-line @nx/enforce-module-boundaries
|
594
849
|
const error = (message) => console.error(message);
|
595
|
-
const hasPreviewKey = () => {
|
596
|
-
var _a;
|
597
|
-
try {
|
598
|
-
return ((_a = sessionStorage.getItem(previewKeyName)) !== null && _a !== void 0 ? _a : '0') == '1';
|
599
|
-
}
|
600
|
-
catch {
|
601
|
-
return false;
|
602
|
-
}
|
603
|
-
};
|
604
850
|
const init = (params) => {
|
605
851
|
var _a, _b, _c;
|
606
852
|
if (typeof window == 'undefined' || typeof document == 'undefined') {
|
@@ -620,7 +866,8 @@ const init = (params) => {
|
|
620
866
|
// exit if not in top window
|
621
867
|
return;
|
622
868
|
}
|
623
|
-
const { enabled, mode, devMode, merchantUrl, profiles, productHandles, targetPath, view, brandName, quickPrompts, merchantImage, latestThreadLoad, botIconUrl, css, } = (_c = params.manifest.variables) !== null && _c !== void 0 ? _c : {};
|
869
|
+
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 : {};
|
870
|
+
setShopGPTLoaded(params.baseUrl, !loadUiManually);
|
624
871
|
const experiment = createExperiment({
|
625
872
|
name: getExperimentName(mode),
|
626
873
|
userId: params.userId,
|
@@ -642,6 +889,7 @@ const init = (params) => {
|
|
642
889
|
userId: params.userId,
|
643
890
|
});
|
644
891
|
uiImplementation.init({
|
892
|
+
destination: params.baseUrl,
|
645
893
|
storeAPI,
|
646
894
|
shopGPTAPI,
|
647
895
|
devMode,
|
@@ -656,14 +904,47 @@ const init = (params) => {
|
|
656
904
|
latestThreadLoad: latestThreadLoad !== null && latestThreadLoad !== void 0 ? latestThreadLoad : DEFAULT_MAX_THREAD_AGE,
|
657
905
|
botIconUrl,
|
658
906
|
css,
|
907
|
+
nudge,
|
908
|
+
});
|
909
|
+
if (!loadUiManually) {
|
910
|
+
uiImplementation.loadUI();
|
911
|
+
}
|
912
|
+
}
|
913
|
+
};
|
914
|
+
|
915
|
+
const getClickedProductsInContents = (destination, data) => {
|
916
|
+
const storedData = getProductActions(destination);
|
917
|
+
const contents = data['contents'];
|
918
|
+
if (!contents || !Array.isArray(contents) || !storedData) {
|
919
|
+
return;
|
920
|
+
}
|
921
|
+
return contents.flatMap((content) => { var _a; return ((_a = storedData[content.id]) === null || _a === void 0 ? void 0 : _a.clicked) ? [content.id] : []; });
|
922
|
+
};
|
923
|
+
const tag = ({ eventName, destination, data, }) => {
|
924
|
+
var _a;
|
925
|
+
const clickedProducts = getClickedProductsInContents(destination, data);
|
926
|
+
if (eventName === 'AddToCart') {
|
927
|
+
clickedProducts === null || clickedProducts === void 0 ? void 0 : clickedProducts.forEach((id) => {
|
928
|
+
setProductAction(destination, id, 'addToCart', true);
|
659
929
|
});
|
660
930
|
}
|
931
|
+
else if (eventName == 'RemoveFromCart') {
|
932
|
+
clickedProducts === null || clickedProducts === void 0 ? void 0 : clickedProducts.forEach((id) => {
|
933
|
+
setProductAction(destination, id, 'addToCart', false);
|
934
|
+
});
|
935
|
+
}
|
936
|
+
return {
|
937
|
+
session: getProductActions(destination),
|
938
|
+
preview: hasPreviewKey(),
|
939
|
+
isShopGPTLoaded: (_a = getShopGPTLoaded(destination)) !== null && _a !== void 0 ? _a : false,
|
940
|
+
};
|
661
941
|
};
|
662
942
|
|
663
943
|
// eslint-disable-next-line @nx/enforce-module-boundaries
|
664
944
|
const data = {
|
665
945
|
name: packageName,
|
666
946
|
init,
|
947
|
+
tag,
|
667
948
|
};
|
668
949
|
try {
|
669
950
|
if (typeof window !== 'undefined') {
|
@@ -876,6 +1157,29 @@ const shopGPTStyles = i$4 `
|
|
876
1157
|
line-height: 150%;
|
877
1158
|
}
|
878
1159
|
|
1160
|
+
.nudge {
|
1161
|
+
position: absolute;
|
1162
|
+
color: var(--shopgpt-secondary);
|
1163
|
+
padding: 12px 16px;
|
1164
|
+
font-size: 16px;
|
1165
|
+
line-height: 21px;
|
1166
|
+
background: var(--shopgpt-warning);
|
1167
|
+
border-radius: 5px;
|
1168
|
+
box-shadow: 0px 4px 6px -1px rgba(0, 0, 0, 0.1),
|
1169
|
+
0px 2px 4px -1px rgba(0, 0, 0, 0.06);
|
1170
|
+
font-weight: 400;
|
1171
|
+
line-height: 150%;
|
1172
|
+
right: calc(100% + 10px);
|
1173
|
+
top: 0%;
|
1174
|
+
transform: translateY(-50%);
|
1175
|
+
animation: slideIn 0.5s ease-out forwards;
|
1176
|
+
opacity: 0;
|
1177
|
+
cursor: pointer;
|
1178
|
+
width: 260px;
|
1179
|
+
white-space: normal;
|
1180
|
+
word-wrap: break-word;
|
1181
|
+
}
|
1182
|
+
|
879
1183
|
&:hover {
|
880
1184
|
.chatbot-hover-text {
|
881
1185
|
opacity: 1;
|
@@ -883,6 +1187,17 @@ const shopGPTStyles = i$4 `
|
|
883
1187
|
}
|
884
1188
|
}
|
885
1189
|
|
1190
|
+
@keyframes slideIn {
|
1191
|
+
from {
|
1192
|
+
transform: translate(20px, -50%);
|
1193
|
+
opacity: 0;
|
1194
|
+
}
|
1195
|
+
to {
|
1196
|
+
transform: translate(0, -50%);
|
1197
|
+
opacity: 1;
|
1198
|
+
}
|
1199
|
+
}
|
1200
|
+
|
886
1201
|
.mobile-version {
|
887
1202
|
display: none;
|
888
1203
|
|
@@ -1633,19 +1948,38 @@ class ProductItem extends r$2 {
|
|
1633
1948
|
<p class="product-variation-details">${option.name}: ${option.value}</p>
|
1634
1949
|
`);
|
1635
1950
|
}
|
1951
|
+
productClicked(productId, price, url) {
|
1952
|
+
if (productId) {
|
1953
|
+
this.dispatchEvent(new CustomEvent('product-clicked', {
|
1954
|
+
detail: {
|
1955
|
+
productId,
|
1956
|
+
value: price ? parseFloat(price) : undefined,
|
1957
|
+
},
|
1958
|
+
composed: true,
|
1959
|
+
bubbles: true,
|
1960
|
+
}));
|
1961
|
+
}
|
1962
|
+
this.redirect(url);
|
1963
|
+
}
|
1636
1964
|
render() {
|
1637
1965
|
return x `
|
1638
1966
|
<div class="product">
|
1639
1967
|
<img
|
1640
1968
|
src=${this.product.image.url}
|
1641
1969
|
alt=${this.product.image.alt}
|
1642
|
-
@click=${() => {
|
1970
|
+
@click=${() => {
|
1971
|
+
var _a;
|
1972
|
+
return this.productClicked(this.product.id, this.product.variants[0].price, (_a = this.product) === null || _a === void 0 ? void 0 : _a.url);
|
1973
|
+
}}
|
1643
1974
|
/>
|
1644
1975
|
<div class="content">
|
1645
1976
|
<p
|
1646
1977
|
class="product-name"
|
1647
1978
|
title=${this.product.title}
|
1648
|
-
@click=${() => {
|
1979
|
+
@click=${() => {
|
1980
|
+
var _a;
|
1981
|
+
return this.productClicked(this.product.id, this.product.variants[0].price, (_a = this.product) === null || _a === void 0 ? void 0 : _a.url);
|
1982
|
+
}}
|
1649
1983
|
>
|
1650
1984
|
${this.product.title}
|
1651
1985
|
</p>
|
@@ -1656,7 +1990,10 @@ class ProductItem extends r$2 {
|
|
1656
1990
|
</div>
|
1657
1991
|
<button
|
1658
1992
|
class="btn-view-product"
|
1659
|
-
@click=${() => {
|
1993
|
+
@click=${() => {
|
1994
|
+
var _a;
|
1995
|
+
return this.productClicked(this.product.id, this.product.variants[0].price, (_a = this.product) === null || _a === void 0 ? void 0 : _a.url);
|
1996
|
+
}}
|
1660
1997
|
>
|
1661
1998
|
View Product
|
1662
1999
|
</button>
|
@@ -2462,6 +2799,22 @@ const chatSectionStyles = i$4 `
|
|
2462
2799
|
const capitalizeEachWord = (str) => {
|
2463
2800
|
return str === null || str === void 0 ? void 0 : str.replace(/^\w/, (char) => char.toUpperCase());
|
2464
2801
|
};
|
2802
|
+
const adParams = new Set([
|
2803
|
+
'fbclid',
|
2804
|
+
'gclid',
|
2805
|
+
'sccid',
|
2806
|
+
'ttclid',
|
2807
|
+
'epik',
|
2808
|
+
'li_fat_id',
|
2809
|
+
'twclid',
|
2810
|
+
'rdt_cid',
|
2811
|
+
'aleid',
|
2812
|
+
'tabclid',
|
2813
|
+
'msclkid',
|
2814
|
+
'dclid',
|
2815
|
+
'wbraid',
|
2816
|
+
]);
|
2817
|
+
const isFromAd = (params) => [...params.keys()].some((key) => adParams.has(key.toLowerCase()));
|
2465
2818
|
|
2466
2819
|
const plusBtn = b `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
|
2467
2820
|
<path d="M12.75 11.25V6H11.25V11.25H6V12.75H11.25V18H12.75V12.75H18V11.25H12.75Z" fill="white"/>
|
@@ -3518,6 +3871,7 @@ class FeedbackDialog extends r$2 {
|
|
3518
3871
|
this.dispatchEvent(new CustomEvent('submit-feedback', {
|
3519
3872
|
detail: {
|
3520
3873
|
messageId: this.messageId,
|
3874
|
+
threadId: this.threadId,
|
3521
3875
|
feedback,
|
3522
3876
|
},
|
3523
3877
|
composed: true,
|
@@ -3589,6 +3943,10 @@ __decorate([
|
|
3589
3943
|
n({ type: String }),
|
3590
3944
|
__metadata("design:type", Object)
|
3591
3945
|
], FeedbackDialog.prototype, "messageId", void 0);
|
3946
|
+
__decorate([
|
3947
|
+
n({ type: String }),
|
3948
|
+
__metadata("design:type", Object)
|
3949
|
+
], FeedbackDialog.prototype, "threadId", void 0);
|
3592
3950
|
__decorate([
|
3593
3951
|
n({ type: String }),
|
3594
3952
|
__metadata("design:type", Object)
|
@@ -3621,19 +3979,26 @@ class ChatSection extends r$2 {
|
|
3621
3979
|
behavior: 'smooth',
|
3622
3980
|
});
|
3623
3981
|
}
|
3624
|
-
async processMessage(e, message) {
|
3982
|
+
async processMessage(e, message, isPrompt = false) {
|
3625
3983
|
this.scrollToBottom();
|
3626
3984
|
if (!this.thread) {
|
3627
3985
|
await this.createChatThread({ title: '' }, false);
|
3628
3986
|
}
|
3629
|
-
await this.sendMessageToServer(e, message);
|
3987
|
+
await this.sendMessageToServer(e, message, isPrompt);
|
3988
|
+
}
|
3989
|
+
sendEvent(action, actionData) {
|
3990
|
+
this.dispatchEvent(new CustomEvent('send-event', {
|
3991
|
+
detail: { action, actionData },
|
3992
|
+
composed: true,
|
3993
|
+
bubbles: true,
|
3994
|
+
}));
|
3630
3995
|
}
|
3631
3996
|
async onSubmit(e) {
|
3632
3997
|
var _a;
|
3633
3998
|
e.preventDefault();
|
3634
3999
|
const message = (_a = this.userQuery) === null || _a === void 0 ? void 0 : _a.trim();
|
3635
4000
|
this.userQuery = '';
|
3636
|
-
await this.processMessage(e, message);
|
4001
|
+
await this.processMessage(e, message, false);
|
3637
4002
|
}
|
3638
4003
|
handleThreadDelete() {
|
3639
4004
|
if (this.deleteAllThreads) {
|
@@ -3655,13 +4020,19 @@ class ChatSection extends r$2 {
|
|
3655
4020
|
this.deleteThreadId = '';
|
3656
4021
|
}
|
3657
4022
|
handleFeedback(rating, messageId, comment) {
|
4023
|
+
var _a, _b;
|
3658
4024
|
if (rating === 'bad') {
|
3659
|
-
this.feedbackDetails = {
|
4025
|
+
this.feedbackDetails = {
|
4026
|
+
messageId,
|
4027
|
+
threadId: ((_a = this.thread) === null || _a === void 0 ? void 0 : _a.threadId) || '',
|
4028
|
+
comment,
|
4029
|
+
};
|
3660
4030
|
return;
|
3661
4031
|
}
|
3662
4032
|
this.dispatchEvent(new CustomEvent('submit-feedback', {
|
3663
4033
|
detail: {
|
3664
4034
|
messageId: messageId,
|
4035
|
+
threadId: (_b = this.thread) === null || _b === void 0 ? void 0 : _b.threadId,
|
3665
4036
|
feedback: {
|
3666
4037
|
rating,
|
3667
4038
|
comment: null,
|
@@ -3808,7 +4179,10 @@ class ChatSection extends r$2 {
|
|
3808
4179
|
return x `
|
3809
4180
|
<div
|
3810
4181
|
class="prompt"
|
3811
|
-
@click=${(e) =>
|
4182
|
+
@click=${(e) => {
|
4183
|
+
this.processMessage(e, prompt, true);
|
4184
|
+
this.sendEvent('promptClicked');
|
4185
|
+
}}
|
3812
4186
|
>
|
3813
4187
|
${prompt}
|
3814
4188
|
</div>
|
@@ -3816,7 +4190,13 @@ class ChatSection extends r$2 {
|
|
3816
4190
|
})}
|
3817
4191
|
${o$1(customPrompts, ({ prompt, link }) => {
|
3818
4192
|
return x `
|
3819
|
-
<a
|
4193
|
+
<a
|
4194
|
+
class="prompt"
|
4195
|
+
href=${link}
|
4196
|
+
target="_blank"
|
4197
|
+
rel="noopener"
|
4198
|
+
@click=${() => this.sendEvent('promptClicked')}
|
4199
|
+
>
|
3820
4200
|
${prompt}
|
3821
4201
|
</a>
|
3822
4202
|
`;
|
@@ -4092,7 +4472,10 @@ class ChatSection extends r$2 {
|
|
4092
4472
|
</form>
|
4093
4473
|
${this.viewType === 'modal'
|
4094
4474
|
? x ` <footer>
|
4095
|
-
Powered by
|
4475
|
+
Powered by
|
4476
|
+
<a target="_blank" href="https://shopgpt.edgeagents.ai"
|
4477
|
+
>Blotout</a
|
4478
|
+
>
|
4096
4479
|
</footer>`
|
4097
4480
|
: E}
|
4098
4481
|
</div>
|
@@ -4132,6 +4515,7 @@ class ChatSection extends r$2 {
|
|
4132
4515
|
? x `
|
4133
4516
|
<feedback-dialog
|
4134
4517
|
.messageId=${this.feedbackDetails.messageId}
|
4518
|
+
.threadId=${this.feedbackDetails.threadId}
|
4135
4519
|
.comment=${this.feedbackDetails.comment}
|
4136
4520
|
@submit-feedback=${() => {
|
4137
4521
|
this.feedbackDetails = undefined;
|
@@ -4251,13 +4635,22 @@ if (!customElements.get('chat-section')) {
|
|
4251
4635
|
customElements.define('chat-section', ChatSection);
|
4252
4636
|
}
|
4253
4637
|
|
4638
|
+
async function* streamToIterable(stream) {
|
4639
|
+
const reader = stream.getReader();
|
4640
|
+
while (true) {
|
4641
|
+
const { done, value } = await reader.read();
|
4642
|
+
if (done)
|
4643
|
+
return;
|
4644
|
+
yield value;
|
4645
|
+
}
|
4646
|
+
}
|
4254
4647
|
const handleEventSource = async (response, onEvent) => {
|
4255
4648
|
var _a, _b;
|
4256
4649
|
if (!response.body) {
|
4257
4650
|
throw new Error('No body found in response');
|
4258
4651
|
}
|
4259
4652
|
let buffer = '';
|
4260
|
-
for await (const chunk of response.body.pipeThrough(new TextDecoderStream())) {
|
4653
|
+
for await (const chunk of streamToIterable(response.body.pipeThrough(new TextDecoderStream()))) {
|
4261
4654
|
buffer += chunk;
|
4262
4655
|
const sections = buffer.split('\n\n');
|
4263
4656
|
buffer = sections.pop() || '';
|
@@ -4300,12 +4693,15 @@ const parseMessage = (message, parseDataAsJSON) => {
|
|
4300
4693
|
return result;
|
4301
4694
|
};
|
4302
4695
|
|
4696
|
+
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';
|
4697
|
+
|
4303
4698
|
const DIALOG_DELAY = 1000;
|
4304
4699
|
const normalizePath = (path) => path.replace(/\/$/, '');
|
4305
4700
|
class ShopGPT extends r$2 {
|
4306
4701
|
constructor() {
|
4307
4702
|
super(...arguments);
|
4308
4703
|
this.isStylesheetInjected = false;
|
4704
|
+
this.isPreviousMessagePrompt = false;
|
4309
4705
|
this.latestThreadLoad = DEFAULT_MAX_THREAD_AGE;
|
4310
4706
|
this.modalState = 'close';
|
4311
4707
|
this.isLoadingHistory = false;
|
@@ -4317,6 +4713,8 @@ class ShopGPT extends r$2 {
|
|
4317
4713
|
this.messages = [];
|
4318
4714
|
this.chatThreads = new Map();
|
4319
4715
|
this.customPrompts = [];
|
4716
|
+
this.hasUserInteracted = false;
|
4717
|
+
this.showNudge = false;
|
4320
4718
|
this.loadData = async () => {
|
4321
4719
|
if (!this.shopGPTAPI) {
|
4322
4720
|
return;
|
@@ -4357,17 +4755,23 @@ class ShopGPT extends r$2 {
|
|
4357
4755
|
}
|
4358
4756
|
}
|
4359
4757
|
this.init();
|
4758
|
+
this.startNudgeTimer();
|
4360
4759
|
}
|
4361
4760
|
disconnectedCallback() {
|
4362
4761
|
window.removeEventListener('edgetag-initialized', this.loadData);
|
4363
4762
|
window.removeEventListener('popstate', this.onPopState);
|
4763
|
+
if (this.nudgeTimer) {
|
4764
|
+
window.clearTimeout(this.nudgeTimer);
|
4765
|
+
}
|
4364
4766
|
super.disconnectedCallback();
|
4365
4767
|
}
|
4366
4768
|
init() {
|
4367
4769
|
window.addEventListener('edgetag-initialized', this.loadData);
|
4368
4770
|
window.addEventListener('popstate', this.onPopState);
|
4771
|
+
this.shopGPTAPI.sendEvent('shopGPTInitialized', this.getSiteCurrency().currency);
|
4369
4772
|
if (!this.view || this.view === 'overlay') {
|
4370
|
-
delay(DIALOG_DELAY)
|
4773
|
+
delay(DIALOG_DELAY)
|
4774
|
+
.then(() => {
|
4371
4775
|
var _a;
|
4372
4776
|
if (document.hidden) {
|
4373
4777
|
document.addEventListener('visibilitychange', () => { var _a; return (_a = this.shopGPTDialog) === null || _a === void 0 ? void 0 : _a.showModal(); }, {
|
@@ -4377,7 +4781,8 @@ class ShopGPT extends r$2 {
|
|
4377
4781
|
else {
|
4378
4782
|
(_a = this.shopGPTDialog) === null || _a === void 0 ? void 0 : _a.showModal();
|
4379
4783
|
}
|
4380
|
-
})
|
4784
|
+
})
|
4785
|
+
.catch(logger.error);
|
4381
4786
|
}
|
4382
4787
|
}
|
4383
4788
|
setChatTitle(threadId, title) {
|
@@ -4405,8 +4810,8 @@ class ShopGPT extends r$2 {
|
|
4405
4810
|
if (!thread) {
|
4406
4811
|
return;
|
4407
4812
|
}
|
4408
|
-
const
|
4409
|
-
const fromAd =
|
4813
|
+
const searchParams = new URLSearchParams(window.location.search);
|
4814
|
+
const fromAd = isFromAd(searchParams) || searchParams.get('shopGPT') === '1';
|
4410
4815
|
const productHandle = this.devMode
|
4411
4816
|
? (_a = thread === null || thread === void 0 ? void 0 : thread.devContext) === null || _a === void 0 ? void 0 : _a.productHandle
|
4412
4817
|
: fromAd
|
@@ -4643,7 +5048,7 @@ class ShopGPT extends r$2 {
|
|
4643
5048
|
}
|
4644
5049
|
});
|
4645
5050
|
}
|
4646
|
-
async sendMessageToServer(e, message) {
|
5051
|
+
async sendMessageToServer(e, message, isPrompt = false) {
|
4647
5052
|
e.preventDefault();
|
4648
5053
|
e.stopPropagation();
|
4649
5054
|
if (!message || this.isTyping || this.isLoadingHistory) {
|
@@ -4651,6 +5056,10 @@ class ShopGPT extends r$2 {
|
|
4651
5056
|
}
|
4652
5057
|
this.isFailed = false;
|
4653
5058
|
try {
|
5059
|
+
this.isPreviousMessagePrompt = isPrompt;
|
5060
|
+
if (!isPrompt) {
|
5061
|
+
this.shopGPTAPI.sendEvent('queryInteractions', this.getSiteCurrency().currency);
|
5062
|
+
}
|
4654
5063
|
this.messages = [{ sender: 'user', message }, ...this.messages];
|
4655
5064
|
this.isTyping = true;
|
4656
5065
|
const response = await this.submitQuery(message);
|
@@ -4665,7 +5074,7 @@ class ShopGPT extends r$2 {
|
|
4665
5074
|
submitFeedback(e) {
|
4666
5075
|
e.stopPropagation();
|
4667
5076
|
this.shopGPTAPI
|
4668
|
-
.saveFeedback(e.detail.messageId, e.detail.feedback)
|
5077
|
+
.saveFeedback(e.detail.messageId, e.detail.threadId, e.detail.feedback)
|
4669
5078
|
.then(() => {
|
4670
5079
|
const messages = this.messages;
|
4671
5080
|
const messageIndex = messages.findIndex(({ messageId }) => messageId === e.detail.messageId);
|
@@ -4674,17 +5083,25 @@ class ShopGPT extends r$2 {
|
|
4674
5083
|
feedback: e.detail.feedback,
|
4675
5084
|
};
|
4676
5085
|
this.messages = [...messages];
|
5086
|
+
})
|
5087
|
+
.catch(logger.error);
|
5088
|
+
}
|
5089
|
+
sendEvent(e) {
|
5090
|
+
e.stopPropagation();
|
5091
|
+
this.shopGPTAPI.sendEvent(e.detail.action, this.getSiteCurrency().currency, e.detail.actionData);
|
5092
|
+
}
|
5093
|
+
productClicked(e) {
|
5094
|
+
e.stopPropagation();
|
5095
|
+
setProductAction(this.destination, e.detail.productId, 'clicked', true);
|
5096
|
+
this.shopGPTAPI.sendEvent('productRecommendationClicked', this.getSiteCurrency().currency, {
|
5097
|
+
productId: e.detail.productId,
|
5098
|
+
value: e.detail.value,
|
5099
|
+
isPrompt: this.isPreviousMessagePrompt,
|
4677
5100
|
});
|
4678
5101
|
}
|
4679
5102
|
getSiteCurrency() {
|
4680
5103
|
return this.storeAPI.getSiteCurrency();
|
4681
5104
|
}
|
4682
|
-
render() {
|
4683
|
-
if (this.view === 'modal') {
|
4684
|
-
return this.modalMode();
|
4685
|
-
}
|
4686
|
-
return this.overlayMode();
|
4687
|
-
}
|
4688
5105
|
overlayMode() {
|
4689
5106
|
const thread = this.chatThreads.get(this.selectedThreadId);
|
4690
5107
|
return x `
|
@@ -4693,6 +5110,8 @@ class ShopGPT extends r$2 {
|
|
4693
5110
|
@delete-thread=${this.handleThreadDelete}
|
4694
5111
|
@delete-all-threads=${this.handleAllThreadsDelete}
|
4695
5112
|
@submit-feedback=${this.submitFeedback}
|
5113
|
+
@send-event=${this.sendEvent}
|
5114
|
+
@product-clicked=${this.productClicked}
|
4696
5115
|
>
|
4697
5116
|
<div class="mobile-version">
|
4698
5117
|
Please switch to the desktop version for the best experience.
|
@@ -4740,6 +5159,7 @@ class ShopGPT extends r$2 {
|
|
4740
5159
|
`;
|
4741
5160
|
}
|
4742
5161
|
modalMode() {
|
5162
|
+
var _a;
|
4743
5163
|
const thread = this.chatThreads.get(this.selectedThreadId);
|
4744
5164
|
const closeModal = () => {
|
4745
5165
|
this.modalState = 'close';
|
@@ -4749,12 +5169,28 @@ class ShopGPT extends r$2 {
|
|
4749
5169
|
<button
|
4750
5170
|
@click=${(e) => {
|
4751
5171
|
e.preventDefault();
|
5172
|
+
this.shopGPTAPI.sendEvent('chatbotOpened', this.getSiteCurrency().currency);
|
4752
5173
|
this.modalState = 'open';
|
5174
|
+
this.handleUserInteraction();
|
4753
5175
|
}}
|
4754
5176
|
>
|
4755
5177
|
${chatIcon}
|
4756
5178
|
</button>
|
4757
|
-
|
5179
|
+
${((_a = this.nudge) === null || _a === void 0 ? void 0 : _a.show) && this.showNudge
|
5180
|
+
? x `<div
|
5181
|
+
class="nudge"
|
5182
|
+
@click=${(e) => {
|
5183
|
+
e.preventDefault();
|
5184
|
+
this.modalState = 'open';
|
5185
|
+
this.handleUserInteraction();
|
5186
|
+
}}
|
5187
|
+
>
|
5188
|
+
Hi there! I'm an AI Agent to help you find the perfect product.
|
5189
|
+
What are you looking for today?
|
5190
|
+
</div>`
|
5191
|
+
: x `<div class="chatbot-hover-text">
|
5192
|
+
What are you looking for today?
|
5193
|
+
</div>`}
|
4758
5194
|
</div>`;
|
4759
5195
|
}
|
4760
5196
|
return x `
|
@@ -4763,6 +5199,9 @@ class ShopGPT extends r$2 {
|
|
4763
5199
|
@delete-thread=${this.handleThreadDelete}
|
4764
5200
|
@delete-all-threads=${this.handleAllThreadsDelete}
|
4765
5201
|
@submit-feedback=${this.submitFeedback}
|
5202
|
+
@click=${this.handleUserInteraction}
|
5203
|
+
@send-event=${this.sendEvent}
|
5204
|
+
@product-clicked=${this.productClicked}
|
4766
5205
|
>
|
4767
5206
|
<chat-section
|
4768
5207
|
.prompts=${this.quickPrompts}
|
@@ -4791,6 +5230,48 @@ class ShopGPT extends r$2 {
|
|
4791
5230
|
</div>
|
4792
5231
|
`;
|
4793
5232
|
}
|
5233
|
+
startNudgeTimer() {
|
5234
|
+
var _a, _b;
|
5235
|
+
if (this.view !== 'modal' || !((_a = this.nudge) === null || _a === void 0 ? void 0 : _a.show)) {
|
5236
|
+
return;
|
5237
|
+
}
|
5238
|
+
this.hasUserInteracted = isUserInteracted(this.destination);
|
5239
|
+
if (this.hasUserInteracted || this.nudgeTimer) {
|
5240
|
+
return;
|
5241
|
+
}
|
5242
|
+
this.nudgeTimer = window.setTimeout(() => {
|
5243
|
+
if (!this.hasUserInteracted) {
|
5244
|
+
this.playNudgeSound();
|
5245
|
+
this.showNudge = true;
|
5246
|
+
}
|
5247
|
+
}, (((_b = this.nudge) === null || _b === void 0 ? void 0 : _b.timeout) || DEFAULT_NUDGE_TIMEOUT) * 1000);
|
5248
|
+
}
|
5249
|
+
playNudgeSound() {
|
5250
|
+
var _a;
|
5251
|
+
if (!((_a = this.nudge) === null || _a === void 0 ? void 0 : _a.sound) || !navigator.userActivation.hasBeenActive) {
|
5252
|
+
return;
|
5253
|
+
}
|
5254
|
+
const audio = new Audio(soothingWaterDropSound);
|
5255
|
+
audio
|
5256
|
+
.play()
|
5257
|
+
.catch((error) => logger.error('Error playing nudge sound', error));
|
5258
|
+
}
|
5259
|
+
handleUserInteraction() {
|
5260
|
+
if (!this.hasUserInteracted) {
|
5261
|
+
this.hasUserInteracted = true;
|
5262
|
+
this.showNudge = false;
|
5263
|
+
if (this.nudgeTimer) {
|
5264
|
+
window.clearTimeout(this.nudgeTimer);
|
5265
|
+
}
|
5266
|
+
setUserInteracted(this.destination);
|
5267
|
+
}
|
5268
|
+
}
|
5269
|
+
render() {
|
5270
|
+
if (this.view === 'modal') {
|
5271
|
+
return this.modalMode();
|
5272
|
+
}
|
5273
|
+
return this.overlayMode();
|
5274
|
+
}
|
4794
5275
|
}
|
4795
5276
|
ShopGPT.styles = [shopGPTStyles];
|
4796
5277
|
__decorate([
|
@@ -4841,6 +5322,14 @@ __decorate([
|
|
4841
5322
|
n({ type: Array }),
|
4842
5323
|
__metadata("design:type", Array)
|
4843
5324
|
], ShopGPT.prototype, "customPrompts", void 0);
|
5325
|
+
__decorate([
|
5326
|
+
r(),
|
5327
|
+
__metadata("design:type", Object)
|
5328
|
+
], ShopGPT.prototype, "hasUserInteracted", void 0);
|
5329
|
+
__decorate([
|
5330
|
+
r(),
|
5331
|
+
__metadata("design:type", Object)
|
5332
|
+
], ShopGPT.prototype, "showNudge", void 0);
|
4844
5333
|
if (!customElements.get('shop-gpt')) {
|
4845
5334
|
customElements.define('shop-gpt', ShopGPT);
|
4846
5335
|
}
|
@@ -4856,6 +5345,7 @@ if (typeof window != 'undefined' && typeof document != 'undefined') {
|
|
4856
5345
|
return;
|
4857
5346
|
}
|
4858
5347
|
shopGPT = document.createElement('shop-gpt');
|
5348
|
+
shopGPT.destination = params.destination;
|
4859
5349
|
shopGPT.storeAPI = params.storeAPI;
|
4860
5350
|
shopGPT.shopGPTAPI = params.shopGPTAPI;
|
4861
5351
|
shopGPT.devMode = params.devMode;
|
@@ -4870,12 +5360,25 @@ if (typeof window != 'undefined' && typeof document != 'undefined') {
|
|
4870
5360
|
shopGPT.latestThreadLoad = params.latestThreadLoad;
|
4871
5361
|
shopGPT.botIconUrl = params.botIconUrl;
|
4872
5362
|
shopGPT.css = params.css;
|
5363
|
+
shopGPT.nudge = params.nudge;
|
5364
|
+
},
|
5365
|
+
loadUI() {
|
5366
|
+
if (!shopGPT) {
|
5367
|
+
logger.error('ShopGPT component not found!');
|
5368
|
+
return;
|
5369
|
+
}
|
5370
|
+
if (shopGPT.parentNode) {
|
5371
|
+
logger.log('ShopGPT component added already!');
|
5372
|
+
return;
|
5373
|
+
}
|
4873
5374
|
document.body.append(shopGPT);
|
5375
|
+
setShopGPTLoaded(shopGPT.destination, true);
|
4874
5376
|
},
|
4875
5377
|
destroy() {
|
4876
5378
|
if (!shopGPT) {
|
4877
5379
|
return;
|
4878
5380
|
}
|
5381
|
+
setShopGPTLoaded(shopGPT.destination, false);
|
4879
5382
|
shopGPT.remove();
|
4880
5383
|
shopGPT = undefined;
|
4881
5384
|
delete window[registryKey];
|