@blotoutio/providers-shop-gpt-sdk 1.11.3 → 1.11.4

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 +292 -130
  2. package/index.js +292 -130
  3. package/index.mjs +292 -130
  4. package/package.json +1 -1
package/index.js CHANGED
@@ -377,6 +377,8 @@ var ProvidersShopGptSdk = (function () {
377
377
  groupName: '',
378
378
  isEnabled: false,
379
379
  });
380
+ // userId => 92ae5ac6-b47c-4444-923f-87d98b7e1fac-1743927514247
381
+ // sample => 92ae5ac6
380
382
  const createABTest = ({ userId }) => {
381
383
  const [sample] = userId.split('-');
382
384
  const segment = parseInt(sample, 16) % 2;
@@ -412,6 +414,7 @@ var ProvidersShopGptSdk = (function () {
412
414
  /** Action length should not exceed 42 */
413
415
  const uiActions = new Set([
414
416
  'shopGPTInitialized',
417
+ 'shopGPTLoaded',
415
418
  'chatbotOpened',
416
419
  'chatbotClosed',
417
420
  'singleThreadDelete',
@@ -626,16 +629,16 @@ var ProvidersShopGptSdk = (function () {
626
629
  const updatedLocal = { [sessionId]: local[sessionId] };
627
630
  saveLocalStorageData(destination, updatedLocal);
628
631
  };
629
- const getShopGPTLoaded = (destination, sessionId) => {
632
+ const getWasUserExposed = (destination, sessionId) => {
630
633
  var _a, _b;
631
634
  const local = getLocalStorageData(destination);
632
635
  if (!local || !sessionId) {
633
636
  logger.error('No local storage data or session id');
634
637
  return false;
635
638
  }
636
- return (_b = (_a = local[sessionId]) === null || _a === void 0 ? void 0 : _a.isShopGPTLoaded) !== null && _b !== void 0 ? _b : false;
639
+ return (_b = (_a = local[sessionId]) === null || _a === void 0 ? void 0 : _a.exposed) !== null && _b !== void 0 ? _b : false;
637
640
  };
638
- const setShopGPTLoaded = (destination, sessionId, value) => {
641
+ const setWasUserExposed = (destination, sessionId, value) => {
639
642
  const local = getLocalStorageData(destination);
640
643
  if (!local || !sessionId) {
641
644
  logger.error('No local storage data or session id');
@@ -643,14 +646,60 @@ var ProvidersShopGptSdk = (function () {
643
646
  }
644
647
  local[sessionId] = {
645
648
  ...local[sessionId],
646
- isShopGPTLoaded: value,
649
+ exposed: value,
647
650
  };
648
651
  // Clear other sessions
649
652
  const updatedLocal = { [sessionId]: local[sessionId] };
650
653
  saveLocalStorageData(destination, updatedLocal);
651
654
  };
655
+ const setUserType = (destination, sessionId, value) => {
656
+ const local = getLocalStorageData(destination);
657
+ if (!local || !sessionId) {
658
+ logger.error('No session id');
659
+ return;
660
+ }
661
+ local[sessionId] = {
662
+ ...local[sessionId],
663
+ userType: value,
664
+ };
665
+ // Clear other sessions
666
+ const updatedLocal = { [sessionId]: local[sessionId] };
667
+ saveLocalStorageData(destination, updatedLocal);
668
+ };
669
+ const getUserType = (destination, sessionId) => {
670
+ var _a;
671
+ const local = getLocalStorageData(destination);
672
+ if (!sessionId) {
673
+ logger.error('No session id');
674
+ return;
675
+ }
676
+ return (_a = local === null || local === void 0 ? void 0 : local[sessionId]) === null || _a === void 0 ? void 0 : _a.userType;
677
+ };
678
+ const setIsBotOpened = (destination, sessionId, value) => {
679
+ const local = getLocalStorageData(destination);
680
+ if (!local || !sessionId) {
681
+ logger.error('No session id');
682
+ return;
683
+ }
684
+ local[sessionId] = {
685
+ ...local[sessionId],
686
+ opened: value,
687
+ };
688
+ // Clear other sessions
689
+ const updatedLocal = { [sessionId]: local[sessionId] };
690
+ saveLocalStorageData(destination, updatedLocal);
691
+ };
692
+ const getIsBotOpened = (destination, sessionId) => {
693
+ var _a;
694
+ const local = getLocalStorageData(destination);
695
+ if (!sessionId) {
696
+ logger.error('No session id');
697
+ return;
698
+ }
699
+ return (_a = local === null || local === void 0 ? void 0 : local[sessionId]) === null || _a === void 0 ? void 0 : _a.opened;
700
+ };
652
701
 
653
- const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, storeAPI, sessionId, }) => {
702
+ const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, storeAPI, sessionId, sendTag, }) => {
654
703
  if (!baseURL) {
655
704
  throw new Error(`baseURL missing`);
656
705
  }
@@ -780,9 +829,12 @@ var ProvidersShopGptSdk = (function () {
780
829
  const data = (await response.json());
781
830
  return data.customPrompts;
782
831
  };
783
- const sendEvent = (action, currency, actionData) => {
832
+ const sendEvent = (action, currency, actionData, clickData) => {
784
833
  var _a;
785
834
  const storageData = (_a = getProductActions(baseURL, sessionId)) !== null && _a !== void 0 ? _a : {};
835
+ const userType = getUserType(baseURL, sessionId);
836
+ const exposed = getWasUserExposed(baseURL, sessionId);
837
+ const opened = getIsBotOpened(baseURL, sessionId);
786
838
  // This endpoint sends user events to the server, we don't need to wait for the response
787
839
  fetchImpl(getURL('/user/event'), {
788
840
  method: 'POST',
@@ -794,7 +846,9 @@ var ProvidersShopGptSdk = (function () {
794
846
  storageData: {
795
847
  session: storageData,
796
848
  preview: hasPreviewKey(),
797
- isShopGPTLoaded: true, // The fact that sendEvent was called means that the ShopGPT is loaded
849
+ userType: userType,
850
+ exposed,
851
+ opened: !!opened,
798
852
  },
799
853
  }),
800
854
  credentials: 'include',
@@ -805,6 +859,21 @@ var ProvidersShopGptSdk = (function () {
805
859
  }
806
860
  })
807
861
  .catch(logger.error);
862
+ sendTag({
863
+ eventId: crypto.randomUUID(),
864
+ eventName: action,
865
+ data: {
866
+ ...actionData,
867
+ ...clickData,
868
+ userType,
869
+ exposed,
870
+ storageData,
871
+ opened: !!opened,
872
+ },
873
+ providers: {
874
+ shopGPT: true,
875
+ },
876
+ });
808
877
  };
809
878
  return {
810
879
  processQuery,
@@ -822,7 +891,7 @@ var ProvidersShopGptSdk = (function () {
822
891
  // eslint-disable-next-line @nx/enforce-module-boundaries
823
892
  const error = (message) => console.error(message);
824
893
  const init = (params) => {
825
- var _a, _b, _c, _d, _e, _f;
894
+ var _a, _b, _c;
826
895
  if (typeof window == 'undefined' || typeof document == 'undefined') {
827
896
  // if loaded in non-browser SDKs, return early
828
897
  return;
@@ -841,7 +910,6 @@ var ProvidersShopGptSdk = (function () {
841
910
  return;
842
911
  }
843
912
  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 : {};
844
- setShopGPTLoaded(params.baseUrl, (_d = params.session) === null || _d === void 0 ? void 0 : _d.sessionId, !loadUIManually);
845
913
  const experiment = createExperiment({
846
914
  name: getExperimentName(mode),
847
915
  userId: params.userId,
@@ -851,42 +919,65 @@ var ProvidersShopGptSdk = (function () {
851
919
  if (experiment.name === 'preview' && shouldShowUI) {
852
920
  logger.log('Enabling UI in preview mode');
853
921
  }
854
- if (shouldShowUI) {
855
- const uiImplementation = window[registryKey].ui;
856
- if (!uiImplementation) {
857
- error('UI implementation is missing');
858
- return;
922
+ // once we implement a general version with togglable option to discriminate
923
+ // between anon/known, we'll be able to skip creating this promise before
924
+ // init and possibly loading the UI
925
+ new Promise((resolve) => {
926
+ var _a;
927
+ const userType = getUserType(params.baseUrl, (_a = params.session) === null || _a === void 0 ? void 0 : _a.sessionId);
928
+ if (userType) {
929
+ return resolve();
859
930
  }
931
+ params.getEdgeData(['email'], (data) => {
932
+ var _a;
933
+ setUserType(params.baseUrl, (_a = params.session) === null || _a === void 0 ? void 0 : _a.sessionId, data['emailExists'] ? 'known' : 'anon');
934
+ resolve();
935
+ });
936
+ }).then(() => {
937
+ var _a, _b;
860
938
  const shopGPTAPI = createShopGPTAPI({
861
939
  baseURL: params.baseUrl,
862
940
  storeAPI,
863
941
  userId: params.userId,
864
- sessionId: (_e = params.session) === null || _e === void 0 ? void 0 : _e.sessionId,
942
+ sessionId: (_a = params.session) === null || _a === void 0 ? void 0 : _a.sessionId,
943
+ sendTag: params.sendTag,
865
944
  });
866
- uiImplementation.init({
867
- destination: params.baseUrl,
868
- storeAPI,
869
- shopGPTAPI,
870
- devMode,
871
- view,
872
- merchantUrl,
873
- profiles,
874
- productHandles,
875
- path: targetPath,
876
- brandName,
877
- quickPrompts,
878
- merchantImage,
879
- latestThreadLoad: latestThreadLoad !== null && latestThreadLoad !== void 0 ? latestThreadLoad : DEFAULT_MAX_THREAD_AGE,
880
- botIconUrl,
881
- css,
882
- nudge,
883
- sessionId: (_f = params.session) === null || _f === void 0 ? void 0 : _f.sessionId,
884
- loadUIManually,
945
+ shopGPTAPI.sendEvent('shopGPTInitialized', undefined, undefined, {
946
+ groupName: experiment.groupName,
885
947
  });
886
- if (!loadUIManually) {
887
- uiImplementation.loadUI();
948
+ if (shouldShowUI) {
949
+ const uiImplementation = window[registryKey].ui;
950
+ if (!uiImplementation) {
951
+ error('UI implementation is missing');
952
+ return;
953
+ }
954
+ uiImplementation.init({
955
+ destination: params.baseUrl,
956
+ storeAPI,
957
+ shopGPTAPI,
958
+ devMode,
959
+ view,
960
+ merchantUrl,
961
+ profiles,
962
+ productHandles,
963
+ path: targetPath,
964
+ brandName,
965
+ quickPrompts,
966
+ merchantImage,
967
+ latestThreadLoad: latestThreadLoad !== null && latestThreadLoad !== void 0 ? latestThreadLoad : DEFAULT_MAX_THREAD_AGE,
968
+ botIconUrl,
969
+ css,
970
+ nudge,
971
+ sessionId: (_b = params.session) === null || _b === void 0 ? void 0 : _b.sessionId,
972
+ loadUIManually,
973
+ });
974
+ const searchParams = new URLSearchParams(window.location.search);
975
+ const hasSource = searchParams.get('utm_source') === 'shopgpt';
976
+ if (!loadUIManually || hasSource) {
977
+ uiImplementation.loadUI();
978
+ }
888
979
  }
889
- }
980
+ });
890
981
  };
891
982
 
892
983
  const getClickedProductsInContents = (destination, sessionId, data) => {
@@ -898,7 +989,7 @@ var ProvidersShopGptSdk = (function () {
898
989
  return contents.flatMap((content) => { var _a; return ((_a = storedData[content.id]) === null || _a === void 0 ? void 0 : _a.clicked) ? [content.id] : []; });
899
990
  };
900
991
  const tag = ({ eventName, destination, data, sessionId, }) => {
901
- var _a;
992
+ var _a, _b;
902
993
  const clickedProducts = getClickedProductsInContents(destination, sessionId, data);
903
994
  if (eventName === 'AddToCart') {
904
995
  clickedProducts === null || clickedProducts === void 0 ? void 0 : clickedProducts.forEach((id) => {
@@ -913,7 +1004,9 @@ var ProvidersShopGptSdk = (function () {
913
1004
  return {
914
1005
  session: getProductActions(destination, sessionId),
915
1006
  preview: hasPreviewKey(),
916
- isShopGPTLoaded: (_a = getShopGPTLoaded(destination, sessionId)) !== null && _a !== void 0 ? _a : false,
1007
+ exposed: (_a = getWasUserExposed(destination, sessionId)) !== null && _a !== void 0 ? _a : false,
1008
+ userType: getUserType(destination, sessionId),
1009
+ opened: (_b = getIsBotOpened(destination, sessionId)) !== null && _b !== void 0 ? _b : false,
917
1010
  };
918
1011
  };
919
1012
 
@@ -1783,13 +1876,13 @@ var ProvidersShopGptSdk = (function () {
1783
1876
  .product {
1784
1877
  display: flex;
1785
1878
  gap: 16px;
1879
+ cursor: pointer;
1786
1880
 
1787
1881
  img {
1788
1882
  width: 150px;
1789
1883
  height: 186px;
1790
1884
  object-position: center;
1791
1885
  object-fit: contain;
1792
- cursor: pointer;
1793
1886
  }
1794
1887
  }
1795
1888
 
@@ -1814,7 +1907,6 @@ var ProvidersShopGptSdk = (function () {
1814
1907
  text-overflow: ellipsis;
1815
1908
  word-break: break-word;
1816
1909
  white-space: normal;
1817
- cursor: pointer;
1818
1910
  }
1819
1911
 
1820
1912
  .product-variation-details {
@@ -1925,11 +2017,14 @@ var ProvidersShopGptSdk = (function () {
1925
2017
  ${this.getLocalPrice(comparedAtPrice)}
1926
2018
  </p>`;
1927
2019
  }
1928
- redirect(url) {
2020
+ openProduct(url) {
1929
2021
  if (!url) {
1930
2022
  return;
1931
2023
  }
1932
- open(url, '_self');
2024
+ const link = new URL(url);
2025
+ link.searchParams.set('utm_source', 'shopgpt');
2026
+ link.searchParams.set('utm_medium', 'chat');
2027
+ open(link, '_self');
1933
2028
  }
1934
2029
  renderVariantTitles() {
1935
2030
  if (this.product.hasOnlyDefaultVariant) {
@@ -1939,39 +2034,32 @@ var ProvidersShopGptSdk = (function () {
1939
2034
  <p class="product-variation-details">${option.name}: ${option.value}</p>
1940
2035
  `);
1941
2036
  }
1942
- productClicked(productId, price, url) {
1943
- if (productId) {
2037
+ productClicked(product) {
2038
+ if (product.id) {
2039
+ const price = product.variants[0].price;
1944
2040
  this.dispatchEvent(new CustomEvent('product-clicked', {
1945
2041
  detail: {
1946
- productId,
2042
+ id: product.id,
1947
2043
  value: price ? parseFloat(price) : undefined,
2044
+ variantId: product.variants[0].id,
2045
+ title: product.title,
2046
+ url: product.url,
2047
+ query: this.query,
2048
+ response: this.response,
2049
+ rank: this.rank,
1948
2050
  },
1949
2051
  composed: true,
1950
2052
  bubbles: true,
1951
2053
  }));
1952
2054
  }
1953
- this.redirect(url);
2055
+ this.openProduct(product.url);
1954
2056
  }
1955
2057
  render() {
1956
2058
  return x `
1957
- <div class="product">
1958
- <img
1959
- src=${this.product.image.url}
1960
- alt=${this.product.image.alt}
1961
- @click=${() => {
1962
- var _a;
1963
- return this.productClicked(this.product.id, this.product.variants[0].price, (_a = this.product) === null || _a === void 0 ? void 0 : _a.url);
1964
- }}
1965
- />
2059
+ <div class="product" @click=${() => this.productClicked(this.product)}>
2060
+ <img src=${this.product.image.url} alt=${this.product.image.alt} />
1966
2061
  <div class="content">
1967
- <p
1968
- class="product-name"
1969
- title=${this.product.title}
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
- }}
1974
- >
2062
+ <p class="product-name" title=${this.product.title}>
1975
2063
  ${this.product.title}
1976
2064
  </p>
1977
2065
  ${this.renderVariantTitles()}
@@ -1979,15 +2067,7 @@ var ProvidersShopGptSdk = (function () {
1979
2067
  ${this.getComparedAtPrice(this.product.variants[0].comparedAtPrice, this.product.variants[0].price)}
1980
2068
  <p>${this.getLocalPrice(this.product.variants[0].price)}</p>
1981
2069
  </div>
1982
- <button
1983
- class="btn-view-product"
1984
- @click=${() => {
1985
- var _a;
1986
- return this.productClicked(this.product.id, this.product.variants[0].price, (_a = this.product) === null || _a === void 0 ? void 0 : _a.url);
1987
- }}
1988
- >
1989
- View Product
1990
- </button>
2070
+ <button class="btn-view-product">View Product</button>
1991
2071
  </div>
1992
2072
  </div>
1993
2073
  `;
@@ -2002,6 +2082,18 @@ var ProvidersShopGptSdk = (function () {
2002
2082
  n({ type: Object }),
2003
2083
  __metadata("design:type", Object)
2004
2084
  ], ProductItem.prototype, "siteCurrency", void 0);
2085
+ __decorate([
2086
+ n({ type: String }),
2087
+ __metadata("design:type", Object)
2088
+ ], ProductItem.prototype, "query", void 0);
2089
+ __decorate([
2090
+ n({ type: String }),
2091
+ __metadata("design:type", String)
2092
+ ], ProductItem.prototype, "response", void 0);
2093
+ __decorate([
2094
+ n({ type: Number }),
2095
+ __metadata("design:type", Number)
2096
+ ], ProductItem.prototype, "rank", void 0);
2005
2097
  if (!customElements.get('product-item')) {
2006
2098
  customElements.define('product-item', ProductItem);
2007
2099
  }
@@ -2118,7 +2210,7 @@ var ProvidersShopGptSdk = (function () {
2118
2210
  return x `
2119
2211
  <div class="products-wrapper">
2120
2212
  <div class="products" @scroll=${this.updateButtonsState}>
2121
- ${o$1(this.products, (product) => x `
2213
+ ${o$1(this.products, (product, index) => x `
2122
2214
  <div
2123
2215
  class=${e$1({
2124
2216
  'product-container': true,
@@ -2126,8 +2218,11 @@ var ProvidersShopGptSdk = (function () {
2126
2218
  })}
2127
2219
  >
2128
2220
  <product-item
2221
+ .query=${this.query}
2222
+ .response=${this.response}
2129
2223
  .product=${product}
2130
2224
  .siteCurrency=${this.siteCurrency}
2225
+ .rank=${index + 1}
2131
2226
  ></product-item>
2132
2227
  </div>
2133
2228
  `)}
@@ -2155,6 +2250,14 @@ var ProvidersShopGptSdk = (function () {
2155
2250
  n({ type: Object }),
2156
2251
  __metadata("design:type", Object)
2157
2252
  ], ProductsList.prototype, "siteCurrency", void 0);
2253
+ __decorate([
2254
+ n({ type: String }),
2255
+ __metadata("design:type", Object)
2256
+ ], ProductsList.prototype, "query", void 0);
2257
+ __decorate([
2258
+ n({ type: String }),
2259
+ __metadata("design:type", String)
2260
+ ], ProductsList.prototype, "response", void 0);
2158
2261
  __decorate([
2159
2262
  r(),
2160
2263
  __metadata("design:type", Object)
@@ -2201,6 +2304,7 @@ var ProvidersShopGptSdk = (function () {
2201
2304
  `;
2202
2305
  }
2203
2306
  render() {
2307
+ var _a;
2204
2308
  if (this.isLoadingHistory || this.isLoadingThreads) {
2205
2309
  return x ` <load-spinner></load-spinner> `;
2206
2310
  }
@@ -2211,18 +2315,25 @@ var ProvidersShopGptSdk = (function () {
2211
2315
  }
2212
2316
  const topResult = this.products[0];
2213
2317
  const others = this.products.slice(1);
2318
+ const query = (_a = this.messages) === null || _a === void 0 ? void 0 : _a[1];
2319
+ const response = this.messages[0];
2214
2320
  return x `
2215
2321
  <div class="top-result">
2216
2322
  <h2>Top Result</h2>
2217
2323
  <product-item
2324
+ .query=${query === null || query === void 0 ? void 0 : query.message}
2325
+ .response=${response === null || response === void 0 ? void 0 : response.message}
2218
2326
  .product=${topResult}
2219
2327
  .siteCurrency=${this.siteCurrency}
2328
+ .rank=${1}
2220
2329
  ></product-item>
2221
2330
  </div>
2222
2331
  <span class="line"></span>
2223
2332
  <div class="others">
2224
2333
  <h2>Other Recommendations</h2>
2225
2334
  <products-list
2335
+ .query=${query === null || query === void 0 ? void 0 : query.message}
2336
+ .response=${response === null || response === void 0 ? void 0 : response.message}
2226
2337
  .products=${others}
2227
2338
  .siteCurrency=${this.siteCurrency}
2228
2339
  .viewType=${'overlay'}
@@ -2268,6 +2379,10 @@ var ProvidersShopGptSdk = (function () {
2268
2379
  n({ type: String }),
2269
2380
  __metadata("design:type", String)
2270
2381
  ], ProductsSection.prototype, "css", void 0);
2382
+ __decorate([
2383
+ n({ type: Array }),
2384
+ __metadata("design:type", Array)
2385
+ ], ProductsSection.prototype, "messages", void 0);
2271
2386
  if (!customElements.get('products-section')) {
2272
2387
  customElements.define('products-section', ProductsSection);
2273
2388
  }
@@ -3994,9 +4109,9 @@ ${this.comment ? this.comment : E}</textarea
3994
4109
  }
3995
4110
  await this.sendMessageToServer(e, message, isPrompt);
3996
4111
  }
3997
- sendEvent(action, actionData) {
4112
+ sendEvent(action, actionData, clickData) {
3998
4113
  this.dispatchEvent(new CustomEvent('send-event', {
3999
- detail: { action, actionData },
4114
+ detail: { action, actionData, clickData },
4000
4115
  composed: true,
4001
4116
  bubbles: true,
4002
4117
  }));
@@ -4027,24 +4142,38 @@ ${this.comment ? this.comment : E}</textarea
4027
4142
  }));
4028
4143
  this.deleteThreadId = '';
4029
4144
  }
4030
- handleFeedback(rating, messageId, queryMessageId, comment) {
4031
- var _a, _b;
4145
+ handleFeedback(rating, messageId, queryMessageId, comment, query, response) {
4146
+ var _a, _b, _c, _d;
4032
4147
  if (rating === 'bad') {
4033
- this.sendEvent('thumbsDown');
4148
+ this.sendEvent('thumbsDown', undefined, {
4149
+ messageId,
4150
+ threadId: ((_a = this.thread) === null || _a === void 0 ? void 0 : _a.threadId) || '',
4151
+ rating,
4152
+ comment: comment !== null && comment !== void 0 ? comment : '',
4153
+ query: query !== null && query !== void 0 ? query : '',
4154
+ response: response !== null && response !== void 0 ? response : '',
4155
+ });
4034
4156
  this.feedbackDetails = {
4035
4157
  messageId,
4036
4158
  queryMessageId,
4037
- threadId: ((_a = this.thread) === null || _a === void 0 ? void 0 : _a.threadId) || '',
4159
+ threadId: ((_b = this.thread) === null || _b === void 0 ? void 0 : _b.threadId) || '',
4038
4160
  comment,
4039
4161
  };
4040
4162
  return;
4041
4163
  }
4042
- this.sendEvent('thumbsUp');
4164
+ this.sendEvent('thumbsUp', undefined, {
4165
+ messageId,
4166
+ threadId: ((_c = this.thread) === null || _c === void 0 ? void 0 : _c.threadId) || '',
4167
+ rating,
4168
+ comment: comment !== null && comment !== void 0 ? comment : '',
4169
+ query: query !== null && query !== void 0 ? query : '',
4170
+ response: response !== null && response !== void 0 ? response : '',
4171
+ });
4043
4172
  this.dispatchEvent(new CustomEvent('submit-feedback', {
4044
4173
  detail: {
4045
4174
  messageId: messageId,
4046
4175
  queryMessageId: queryMessageId,
4047
- threadId: (_b = this.thread) === null || _b === void 0 ? void 0 : _b.threadId,
4176
+ threadId: (_d = this.thread) === null || _d === void 0 ? void 0 : _d.threadId,
4048
4177
  feedback: {
4049
4178
  rating,
4050
4179
  comment: null,
@@ -4079,8 +4208,11 @@ ${this.comment ? this.comment : E}</textarea
4079
4208
  <span class="line"></span>
4080
4209
  <div class="product-container">
4081
4210
  <product-item
4211
+ .query=${queryMessage.message}
4212
+ .response=${message.message}
4082
4213
  .product=${message.products[0]}
4083
4214
  .siteCurrency=${this.siteCurrency}
4215
+ .rank=${1}
4084
4216
  ></product-item>
4085
4217
  </div>
4086
4218
  `
@@ -4089,16 +4221,18 @@ ${this.comment ? this.comment : E}</textarea
4089
4221
  </div>
4090
4222
  ${this.viewType === 'modal' && message.products
4091
4223
  ? x ` <products-list
4224
+ .query=${queryMessage.message}
4225
+ .response=${message.message}
4092
4226
  .products=${message.products}
4093
4227
  .siteCurrency=${this.siteCurrency}
4094
4228
  .viewType=${this.viewType}
4095
4229
  ></products-list>`
4096
4230
  : E}
4097
4231
  ${message.messageId && (queryMessage === null || queryMessage === void 0 ? void 0 : queryMessage.messageId)
4098
- ? x `<div class="bot-response-actions">
4232
+ ? x ` <div class="bot-response-actions">
4099
4233
  <button
4100
4234
  type="button"
4101
- @click=${this.handleFeedback.bind(this, 'good', message.messageId, queryMessage === null || queryMessage === void 0 ? void 0 : queryMessage.messageId, (_b = message.feedback) === null || _b === void 0 ? void 0 : _b.comment)}
4235
+ @click=${this.handleFeedback.bind(this, 'good', message.messageId, queryMessage === null || queryMessage === void 0 ? void 0 : queryMessage.messageId, (_b = message.feedback) === null || _b === void 0 ? void 0 : _b.comment, queryMessage.message, message.message)}
4102
4236
  >
4103
4237
  ${((_c = message.feedback) === null || _c === void 0 ? void 0 : _c.rating) === 'good'
4104
4238
  ? thumbsUpFilledBtn
@@ -4106,7 +4240,7 @@ ${this.comment ? this.comment : E}</textarea
4106
4240
  </button>
4107
4241
  <button
4108
4242
  type="button"
4109
- @click=${this.handleFeedback.bind(this, 'bad', message.messageId, queryMessage === null || queryMessage === void 0 ? void 0 : queryMessage.messageId, (_d = message.feedback) === null || _d === void 0 ? void 0 : _d.comment)}
4243
+ @click=${this.handleFeedback.bind(this, 'bad', message.messageId, queryMessage === null || queryMessage === void 0 ? void 0 : queryMessage.messageId, (_d = message.feedback) === null || _d === void 0 ? void 0 : _d.comment, queryMessage.message, message.message)}
4110
4244
  >
4111
4245
  ${((_e = message.feedback) === null || _e === void 0 ? void 0 : _e.rating) === 'bad'
4112
4246
  ? thumbsDownFilledBtn
@@ -4119,7 +4253,7 @@ ${this.comment ? this.comment : E}</textarea
4119
4253
  }
4120
4254
  renderBotIcon() {
4121
4255
  if (this.botIconUrl) {
4122
- return x `<div class="bot-icon">
4256
+ return x ` <div class="bot-icon">
4123
4257
  <img src=${this.botIconUrl} width="30" height="30" />
4124
4258
  </div>`;
4125
4259
  }
@@ -4127,7 +4261,7 @@ ${this.comment ? this.comment : E}</textarea
4127
4261
  }
4128
4262
  chatWindow() {
4129
4263
  if (this.isLoadingHistory || this.isLoadingThreads) {
4130
- return x `<div class="messages loading">
4264
+ return x ` <div class="messages loading">
4131
4265
  <load-spinner></load-spinner>
4132
4266
  </div>`;
4133
4267
  }
@@ -4140,7 +4274,7 @@ ${this.comment ? this.comment : E}</textarea
4140
4274
  </div>`
4141
4275
  : ''}
4142
4276
  ${this.isFailed
4143
- ? x `<div class="message bot">
4277
+ ? x ` <div class="message bot">
4144
4278
  <div>${this.renderBotIcon()}</div>
4145
4279
  <div>
4146
4280
  <p>
@@ -4160,18 +4294,20 @@ ${this.comment ? this.comment : E}</textarea
4160
4294
  })}
4161
4295
  ${!this.fromAd || !this.thread
4162
4296
  ? x `
4163
- <div class="message bot">
4164
- <div>${this.renderBotIcon()}</div>
4165
- <div>
4166
- <p>
4167
- Hi,
4168
- ${this.brandName ? x `Welcome to ${this.brandName}.` : E}
4169
- I'm here to help you find the perfect product. Pick a suggested
4170
- prompt from below, or enter your own query.
4171
- </p>
4172
- </div>
4173
- </div>
4174
- </div>`
4297
+ <div class="message bot">
4298
+ <div>${this.renderBotIcon()}</div>
4299
+ <div>
4300
+ <p>
4301
+ Hi,
4302
+ ${this.brandName
4303
+ ? x `Welcome to ${this.brandName}.`
4304
+ : E}
4305
+ I'm here to help you find the perfect product. Pick a suggested
4306
+ prompt from below, or enter your own query.
4307
+ </p>
4308
+ </div>
4309
+ </div>
4310
+ </div>`
4175
4311
  : E}
4176
4312
  </div>
4177
4313
  `;
@@ -4198,7 +4334,9 @@ ${this.comment ? this.comment : E}</textarea
4198
4334
  class="prompt"
4199
4335
  @click=${(e) => {
4200
4336
  this.processMessage(e, prompt, true);
4201
- this.sendEvent('promptClicked');
4337
+ this.sendEvent('promptClicked', undefined, {
4338
+ promptName: prompt,
4339
+ });
4202
4340
  }}
4203
4341
  >
4204
4342
  ${prompt}
@@ -4212,7 +4350,9 @@ ${this.comment ? this.comment : E}</textarea
4212
4350
  href=${link}
4213
4351
  target="_blank"
4214
4352
  rel="noopener"
4215
- @click=${() => this.sendEvent('promptClicked')}
4353
+ @click=${() => this.sendEvent('promptClicked', undefined, {
4354
+ promptName: prompt,
4355
+ })}
4216
4356
  >
4217
4357
  ${prompt}
4218
4358
  </a>
@@ -4403,7 +4543,7 @@ ${this.comment ? this.comment : E}</textarea
4403
4543
  <div class="title-wrapper">
4404
4544
  <h2>Search History</h2>
4405
4545
  ${this.chatThreads.size
4406
- ? x `<div
4546
+ ? x ` <div
4407
4547
  class="trash-icon"
4408
4548
  @click=${() => {
4409
4549
  if (this.isStreaming) {
@@ -4809,9 +4949,6 @@ ${this.comment ? this.comment : E}</textarea
4809
4949
  this.startNudgeTimer();
4810
4950
  }
4811
4951
  disconnectedCallback() {
4812
- if (!this.loadUIManually) {
4813
- window.removeEventListener('edgetag-initialized', this.loadData);
4814
- }
4815
4952
  window.removeEventListener('popstate', this.onPopState);
4816
4953
  if (this.nudgeTimer) {
4817
4954
  window.clearTimeout(this.nudgeTimer);
@@ -4819,16 +4956,9 @@ ${this.comment ? this.comment : E}</textarea
4819
4956
  super.disconnectedCallback();
4820
4957
  }
4821
4958
  init() {
4822
- if (this.loadUIManually) {
4823
- // this is because edgetag-initialized will already be
4824
- // triggered before the loadUI function is called to load the UI
4825
- this.loadData();
4826
- }
4827
- else {
4828
- window.addEventListener('edgetag-initialized', this.loadData);
4829
- }
4959
+ this.loadData();
4830
4960
  window.addEventListener('popstate', this.onPopState);
4831
- this.shopGPTAPI.sendEvent('shopGPTInitialized', this.getSiteCurrency().currency);
4961
+ this.shopGPTAPI.sendEvent('shopGPTLoaded');
4832
4962
  if (!this.view || this.view === 'overlay') {
4833
4963
  delay(DIALOG_DELAY)
4834
4964
  .then(() => {
@@ -4972,10 +5102,17 @@ ${this.comment ? this.comment : E}</textarea
4972
5102
  }
4973
5103
  }
4974
5104
  async setSelectedThreadId(threadId, silent) {
5105
+ var _a, _b, _c, _d;
4975
5106
  this.isFailed = false;
5107
+ const currentThreadId = this.selectedThreadId;
4976
5108
  this.selectedThreadId = threadId;
4977
5109
  if (threadId && !silent) {
4978
- this.shopGPTAPI.sendEvent('switchThread');
5110
+ this.shopGPTAPI.sendEvent('switchThread', undefined, undefined, {
5111
+ previousThread: currentThreadId,
5112
+ activeThread: threadId,
5113
+ previousThreadTitle: (_b = (_a = this.chatThreads.get(currentThreadId)) === null || _a === void 0 ? void 0 : _a.title) !== null && _b !== void 0 ? _b : '',
5114
+ activeThreadTitle: (_d = (_c = this.chatThreads.get(this.selectedThreadId)) === null || _c === void 0 ? void 0 : _c.title) !== null && _d !== void 0 ? _d : '',
5115
+ });
4979
5116
  }
4980
5117
  await Promise.all([
4981
5118
  this.loadHistory(threadId),
@@ -5001,6 +5138,7 @@ ${this.comment ? this.comment : E}</textarea
5001
5138
  }
5002
5139
  }
5003
5140
  handleThreadDelete(e) {
5141
+ var _a, _b;
5004
5142
  e.stopPropagation();
5005
5143
  this.isLoadingThreads = true;
5006
5144
  const threadId = e.detail.threadId;
@@ -5008,7 +5146,10 @@ ${this.comment ? this.comment : E}</textarea
5008
5146
  logger.error('ThreadId is missing to delete the thread!');
5009
5147
  return;
5010
5148
  }
5011
- this.shopGPTAPI.sendEvent('singleThreadDelete');
5149
+ this.shopGPTAPI.sendEvent('singleThreadDelete', undefined, undefined, {
5150
+ thread: threadId,
5151
+ threadTitle: (_b = (_a = this.chatThreads.get(threadId)) === null || _a === void 0 ? void 0 : _a.title) !== null && _b !== void 0 ? _b : '',
5152
+ });
5012
5153
  this.shopGPTAPI
5013
5154
  .deleteSingleThread(threadId)
5014
5155
  .then(this.loadChatThreads.bind(this))
@@ -5136,7 +5277,10 @@ ${this.comment ? this.comment : E}</textarea
5136
5277
  try {
5137
5278
  this.isPreviousMessagePrompt = isPrompt;
5138
5279
  if (!isPrompt) {
5139
- this.shopGPTAPI.sendEvent('queryInteractions', this.getSiteCurrency().currency);
5280
+ this.shopGPTAPI.sendEvent('queryInteractions', this.getSiteCurrency().currency, undefined, {
5281
+ query: message,
5282
+ threadId: this.selectedThreadId,
5283
+ });
5140
5284
  }
5141
5285
  this.messages = [{ sender: 'user', message }, ...this.messages];
5142
5286
  this.isTyping = true;
@@ -5168,15 +5312,25 @@ ${this.comment ? this.comment : E}</textarea
5168
5312
  }
5169
5313
  sendEvent(e) {
5170
5314
  e.stopPropagation();
5171
- this.shopGPTAPI.sendEvent(e.detail.action, this.getSiteCurrency().currency, e.detail.actionData);
5315
+ this.shopGPTAPI.sendEvent(e.detail.action, this.getSiteCurrency().currency, e.detail.actionData, e.detail.clickData);
5172
5316
  }
5173
5317
  productClicked(e) {
5318
+ var _a, _b;
5174
5319
  e.stopPropagation();
5175
- setProductAction(this.destination, this.sessionId, e.detail.productId, 'clicked', true);
5320
+ setProductAction(this.destination, this.sessionId, e.detail.id, 'clicked', true);
5176
5321
  this.shopGPTAPI.sendEvent('productRecommendationClicked', this.getSiteCurrency().currency, {
5177
- productId: e.detail.productId,
5322
+ productId: e.detail.id,
5178
5323
  value: e.detail.value,
5179
5324
  isPrompt: this.isPreviousMessagePrompt,
5325
+ }, {
5326
+ threadId: this.selectedThreadId,
5327
+ query: (_a = e.detail.query) !== null && _a !== void 0 ? _a : '',
5328
+ response: (_b = e.detail.response) !== null && _b !== void 0 ? _b : '',
5329
+ currency: this.getSiteCurrency().currency,
5330
+ variantId: e.detail.variantId,
5331
+ url: e.detail.url,
5332
+ title: e.detail.title,
5333
+ rank: e.detail.rank,
5180
5334
  });
5181
5335
  }
5182
5336
  getSiteCurrency() {
@@ -5207,6 +5361,7 @@ ${this.comment ? this.comment : E}</textarea
5207
5361
  .css=${this.css}
5208
5362
  ></chat-threads>
5209
5363
  <products-section
5364
+ .messages=${this.messages}
5210
5365
  .merchantImage=${this.merchantImage}
5211
5366
  .products=${this.products}
5212
5367
  .isLoadingHistory=${this.isLoadingHistory}
@@ -5252,26 +5407,23 @@ ${this.comment ? this.comment : E}</textarea
5252
5407
  <button
5253
5408
  @click=${(e) => {
5254
5409
  e.preventDefault();
5255
- this.shopGPTAPI.sendEvent('chatbotOpened', this.getSiteCurrency().currency);
5256
- this.modalState = 'open';
5257
- this.handleUserInteraction();
5410
+ this.openModal();
5258
5411
  }}
5259
5412
  >
5260
5413
  ${chatIcon}
5261
5414
  </button>
5262
5415
  ${((_a = this.nudge) === null || _a === void 0 ? void 0 : _a.show) && this.showNudge
5263
- ? x `<div
5416
+ ? x ` <div
5264
5417
  class="nudge"
5265
5418
  @click=${(e) => {
5266
5419
  e.preventDefault();
5267
- this.modalState = 'open';
5268
- this.handleUserInteraction();
5420
+ this.openModal();
5269
5421
  }}
5270
5422
  >
5271
5423
  Hi there! I'm an AI Agent to help you find the perfect product.
5272
5424
  What are you looking for today?
5273
5425
  </div>`
5274
- : x `<div class="chatbot-hover-text">
5426
+ : x ` <div class="chatbot-hover-text">
5275
5427
  What are you looking for today?
5276
5428
  </div>`}
5277
5429
  </div>`;
@@ -5315,6 +5467,12 @@ ${this.comment ? this.comment : E}</textarea
5315
5467
  </div>
5316
5468
  `;
5317
5469
  }
5470
+ openModal() {
5471
+ setIsBotOpened(this.destination, this.sessionId, true);
5472
+ this.shopGPTAPI.sendEvent('chatbotOpened');
5473
+ this.modalState = 'open';
5474
+ this.handleUserInteraction();
5475
+ }
5318
5476
  startNudgeTimer() {
5319
5477
  var _a, _b;
5320
5478
  if (this.view !== 'modal' || !((_a = this.nudge) === null || _a === void 0 ? void 0 : _a.show)) {
@@ -5353,6 +5511,11 @@ ${this.comment ? this.comment : E}</textarea
5353
5511
  }
5354
5512
  render() {
5355
5513
  if (this.view === 'modal') {
5514
+ const searchParams = new URLSearchParams(window.location.search);
5515
+ const hasSource = searchParams.get('utm_source') === 'shopgpt';
5516
+ if (hasSource) {
5517
+ this.modalState = 'open';
5518
+ }
5356
5519
  return this.modalMode();
5357
5520
  }
5358
5521
  return this.overlayMode();
@@ -5462,14 +5625,13 @@ ${this.comment ? this.comment : E}</textarea
5462
5625
  logger.log('ShopGPT component added already!');
5463
5626
  return;
5464
5627
  }
5628
+ setWasUserExposed(shopGPT.destination, shopGPT.sessionId, true);
5465
5629
  document.body.append(shopGPT);
5466
- setShopGPTLoaded(shopGPT.destination, shopGPT.sessionId, true);
5467
5630
  },
5468
5631
  destroy() {
5469
5632
  if (!shopGPT) {
5470
5633
  return;
5471
5634
  }
5472
- setShopGPTLoaded(shopGPT.destination, shopGPT.sessionId, false);
5473
5635
  shopGPT.remove();
5474
5636
  shopGPT = undefined;
5475
5637
  delete window[registryKey];