@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.
Files changed (4) hide show
  1. package/index.cjs.js +539 -36
  2. package/index.js +539 -36
  3. package/index.mjs +539 -36
  4. 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=${() => { var _a; return this.redirect((_a = this.product) === null || _a === void 0 ? void 0 : _a.url); }}
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=${() => { var _a; return this.redirect((_a = this.product) === null || _a === void 0 ? void 0 : _a.url); }}
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=${() => { var _a; return this.redirect((_a = this.product) === null || _a === void 0 ? void 0 : _a.url); }}
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 = { messageId, comment };
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) => this.processMessage(e, prompt)}
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 class="prompt" href=${link} target="_blank" rel="noopener">
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 <a href="https://blotout.io">Blotout</a>
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).then(() => {
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 searchParam = new URLSearchParams(window.location.search);
4407
- const fromAd = searchParam.get('shopGPT') === '1';
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
- <div class="chatbot-hover-text">What are you looking for today?</div>
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];