@blotoutio/providers-shop-gpt-sdk 1.11.2 → 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 -131
  2. package/index.js +292 -131
  3. package/index.mjs +292 -131
  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,12 +2017,14 @@ var ProvidersShopGptSdk = (function () {
1925
2017
  ${this.getLocalPrice(comparedAtPrice)}
1926
2018
  </p>`;
1927
2019
  }
1928
- redirect(url) {
1929
- var _a;
2020
+ openProduct(url) {
1930
2021
  if (!url) {
1931
2022
  return;
1932
2023
  }
1933
- (_a = open(url, '_blank')) === null || _a === void 0 ? void 0 : _a.focus();
2024
+ const link = new URL(url);
2025
+ link.searchParams.set('utm_source', 'shopgpt');
2026
+ link.searchParams.set('utm_medium', 'chat');
2027
+ open(link, '_self');
1934
2028
  }
1935
2029
  renderVariantTitles() {
1936
2030
  if (this.product.hasOnlyDefaultVariant) {
@@ -1940,39 +2034,32 @@ var ProvidersShopGptSdk = (function () {
1940
2034
  <p class="product-variation-details">${option.name}: ${option.value}</p>
1941
2035
  `);
1942
2036
  }
1943
- productClicked(productId, price, url) {
1944
- if (productId) {
2037
+ productClicked(product) {
2038
+ if (product.id) {
2039
+ const price = product.variants[0].price;
1945
2040
  this.dispatchEvent(new CustomEvent('product-clicked', {
1946
2041
  detail: {
1947
- productId,
2042
+ id: product.id,
1948
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,
1949
2050
  },
1950
2051
  composed: true,
1951
2052
  bubbles: true,
1952
2053
  }));
1953
2054
  }
1954
- this.redirect(url);
2055
+ this.openProduct(product.url);
1955
2056
  }
1956
2057
  render() {
1957
2058
  return x `
1958
- <div class="product">
1959
- <img
1960
- src=${this.product.image.url}
1961
- alt=${this.product.image.alt}
1962
- @click=${() => {
1963
- var _a;
1964
- return this.productClicked(this.product.id, this.product.variants[0].price, (_a = this.product) === null || _a === void 0 ? void 0 : _a.url);
1965
- }}
1966
- />
2059
+ <div class="product" @click=${() => this.productClicked(this.product)}>
2060
+ <img src=${this.product.image.url} alt=${this.product.image.alt} />
1967
2061
  <div class="content">
1968
- <p
1969
- class="product-name"
1970
- title=${this.product.title}
1971
- @click=${() => {
1972
- var _a;
1973
- return this.productClicked(this.product.id, this.product.variants[0].price, (_a = this.product) === null || _a === void 0 ? void 0 : _a.url);
1974
- }}
1975
- >
2062
+ <p class="product-name" title=${this.product.title}>
1976
2063
  ${this.product.title}
1977
2064
  </p>
1978
2065
  ${this.renderVariantTitles()}
@@ -1980,15 +2067,7 @@ var ProvidersShopGptSdk = (function () {
1980
2067
  ${this.getComparedAtPrice(this.product.variants[0].comparedAtPrice, this.product.variants[0].price)}
1981
2068
  <p>${this.getLocalPrice(this.product.variants[0].price)}</p>
1982
2069
  </div>
1983
- <button
1984
- class="btn-view-product"
1985
- @click=${() => {
1986
- var _a;
1987
- return this.productClicked(this.product.id, this.product.variants[0].price, (_a = this.product) === null || _a === void 0 ? void 0 : _a.url);
1988
- }}
1989
- >
1990
- View Product
1991
- </button>
2070
+ <button class="btn-view-product">View Product</button>
1992
2071
  </div>
1993
2072
  </div>
1994
2073
  `;
@@ -2003,6 +2082,18 @@ var ProvidersShopGptSdk = (function () {
2003
2082
  n({ type: Object }),
2004
2083
  __metadata("design:type", Object)
2005
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);
2006
2097
  if (!customElements.get('product-item')) {
2007
2098
  customElements.define('product-item', ProductItem);
2008
2099
  }
@@ -2119,7 +2210,7 @@ var ProvidersShopGptSdk = (function () {
2119
2210
  return x `
2120
2211
  <div class="products-wrapper">
2121
2212
  <div class="products" @scroll=${this.updateButtonsState}>
2122
- ${o$1(this.products, (product) => x `
2213
+ ${o$1(this.products, (product, index) => x `
2123
2214
  <div
2124
2215
  class=${e$1({
2125
2216
  'product-container': true,
@@ -2127,8 +2218,11 @@ var ProvidersShopGptSdk = (function () {
2127
2218
  })}
2128
2219
  >
2129
2220
  <product-item
2221
+ .query=${this.query}
2222
+ .response=${this.response}
2130
2223
  .product=${product}
2131
2224
  .siteCurrency=${this.siteCurrency}
2225
+ .rank=${index + 1}
2132
2226
  ></product-item>
2133
2227
  </div>
2134
2228
  `)}
@@ -2156,6 +2250,14 @@ var ProvidersShopGptSdk = (function () {
2156
2250
  n({ type: Object }),
2157
2251
  __metadata("design:type", Object)
2158
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);
2159
2261
  __decorate([
2160
2262
  r(),
2161
2263
  __metadata("design:type", Object)
@@ -2202,6 +2304,7 @@ var ProvidersShopGptSdk = (function () {
2202
2304
  `;
2203
2305
  }
2204
2306
  render() {
2307
+ var _a;
2205
2308
  if (this.isLoadingHistory || this.isLoadingThreads) {
2206
2309
  return x ` <load-spinner></load-spinner> `;
2207
2310
  }
@@ -2212,18 +2315,25 @@ var ProvidersShopGptSdk = (function () {
2212
2315
  }
2213
2316
  const topResult = this.products[0];
2214
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];
2215
2320
  return x `
2216
2321
  <div class="top-result">
2217
2322
  <h2>Top Result</h2>
2218
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}
2219
2326
  .product=${topResult}
2220
2327
  .siteCurrency=${this.siteCurrency}
2328
+ .rank=${1}
2221
2329
  ></product-item>
2222
2330
  </div>
2223
2331
  <span class="line"></span>
2224
2332
  <div class="others">
2225
2333
  <h2>Other Recommendations</h2>
2226
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}
2227
2337
  .products=${others}
2228
2338
  .siteCurrency=${this.siteCurrency}
2229
2339
  .viewType=${'overlay'}
@@ -2269,6 +2379,10 @@ var ProvidersShopGptSdk = (function () {
2269
2379
  n({ type: String }),
2270
2380
  __metadata("design:type", String)
2271
2381
  ], ProductsSection.prototype, "css", void 0);
2382
+ __decorate([
2383
+ n({ type: Array }),
2384
+ __metadata("design:type", Array)
2385
+ ], ProductsSection.prototype, "messages", void 0);
2272
2386
  if (!customElements.get('products-section')) {
2273
2387
  customElements.define('products-section', ProductsSection);
2274
2388
  }
@@ -3995,9 +4109,9 @@ ${this.comment ? this.comment : E}</textarea
3995
4109
  }
3996
4110
  await this.sendMessageToServer(e, message, isPrompt);
3997
4111
  }
3998
- sendEvent(action, actionData) {
4112
+ sendEvent(action, actionData, clickData) {
3999
4113
  this.dispatchEvent(new CustomEvent('send-event', {
4000
- detail: { action, actionData },
4114
+ detail: { action, actionData, clickData },
4001
4115
  composed: true,
4002
4116
  bubbles: true,
4003
4117
  }));
@@ -4028,24 +4142,38 @@ ${this.comment ? this.comment : E}</textarea
4028
4142
  }));
4029
4143
  this.deleteThreadId = '';
4030
4144
  }
4031
- handleFeedback(rating, messageId, queryMessageId, comment) {
4032
- var _a, _b;
4145
+ handleFeedback(rating, messageId, queryMessageId, comment, query, response) {
4146
+ var _a, _b, _c, _d;
4033
4147
  if (rating === 'bad') {
4034
- 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
+ });
4035
4156
  this.feedbackDetails = {
4036
4157
  messageId,
4037
4158
  queryMessageId,
4038
- 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) || '',
4039
4160
  comment,
4040
4161
  };
4041
4162
  return;
4042
4163
  }
4043
- 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
+ });
4044
4172
  this.dispatchEvent(new CustomEvent('submit-feedback', {
4045
4173
  detail: {
4046
4174
  messageId: messageId,
4047
4175
  queryMessageId: queryMessageId,
4048
- 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,
4049
4177
  feedback: {
4050
4178
  rating,
4051
4179
  comment: null,
@@ -4080,8 +4208,11 @@ ${this.comment ? this.comment : E}</textarea
4080
4208
  <span class="line"></span>
4081
4209
  <div class="product-container">
4082
4210
  <product-item
4211
+ .query=${queryMessage.message}
4212
+ .response=${message.message}
4083
4213
  .product=${message.products[0]}
4084
4214
  .siteCurrency=${this.siteCurrency}
4215
+ .rank=${1}
4085
4216
  ></product-item>
4086
4217
  </div>
4087
4218
  `
@@ -4090,16 +4221,18 @@ ${this.comment ? this.comment : E}</textarea
4090
4221
  </div>
4091
4222
  ${this.viewType === 'modal' && message.products
4092
4223
  ? x ` <products-list
4224
+ .query=${queryMessage.message}
4225
+ .response=${message.message}
4093
4226
  .products=${message.products}
4094
4227
  .siteCurrency=${this.siteCurrency}
4095
4228
  .viewType=${this.viewType}
4096
4229
  ></products-list>`
4097
4230
  : E}
4098
4231
  ${message.messageId && (queryMessage === null || queryMessage === void 0 ? void 0 : queryMessage.messageId)
4099
- ? x `<div class="bot-response-actions">
4232
+ ? x ` <div class="bot-response-actions">
4100
4233
  <button
4101
4234
  type="button"
4102
- @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)}
4103
4236
  >
4104
4237
  ${((_c = message.feedback) === null || _c === void 0 ? void 0 : _c.rating) === 'good'
4105
4238
  ? thumbsUpFilledBtn
@@ -4107,7 +4240,7 @@ ${this.comment ? this.comment : E}</textarea
4107
4240
  </button>
4108
4241
  <button
4109
4242
  type="button"
4110
- @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)}
4111
4244
  >
4112
4245
  ${((_e = message.feedback) === null || _e === void 0 ? void 0 : _e.rating) === 'bad'
4113
4246
  ? thumbsDownFilledBtn
@@ -4120,7 +4253,7 @@ ${this.comment ? this.comment : E}</textarea
4120
4253
  }
4121
4254
  renderBotIcon() {
4122
4255
  if (this.botIconUrl) {
4123
- return x `<div class="bot-icon">
4256
+ return x ` <div class="bot-icon">
4124
4257
  <img src=${this.botIconUrl} width="30" height="30" />
4125
4258
  </div>`;
4126
4259
  }
@@ -4128,7 +4261,7 @@ ${this.comment ? this.comment : E}</textarea
4128
4261
  }
4129
4262
  chatWindow() {
4130
4263
  if (this.isLoadingHistory || this.isLoadingThreads) {
4131
- return x `<div class="messages loading">
4264
+ return x ` <div class="messages loading">
4132
4265
  <load-spinner></load-spinner>
4133
4266
  </div>`;
4134
4267
  }
@@ -4141,7 +4274,7 @@ ${this.comment ? this.comment : E}</textarea
4141
4274
  </div>`
4142
4275
  : ''}
4143
4276
  ${this.isFailed
4144
- ? x `<div class="message bot">
4277
+ ? x ` <div class="message bot">
4145
4278
  <div>${this.renderBotIcon()}</div>
4146
4279
  <div>
4147
4280
  <p>
@@ -4161,18 +4294,20 @@ ${this.comment ? this.comment : E}</textarea
4161
4294
  })}
4162
4295
  ${!this.fromAd || !this.thread
4163
4296
  ? x `
4164
- <div class="message bot">
4165
- <div>${this.renderBotIcon()}</div>
4166
- <div>
4167
- <p>
4168
- Hi,
4169
- ${this.brandName ? x `Welcome to ${this.brandName}.` : E}
4170
- I'm here to help you find the perfect product. Pick a suggested
4171
- prompt from below, or enter your own query.
4172
- </p>
4173
- </div>
4174
- </div>
4175
- </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>`
4176
4311
  : E}
4177
4312
  </div>
4178
4313
  `;
@@ -4199,7 +4334,9 @@ ${this.comment ? this.comment : E}</textarea
4199
4334
  class="prompt"
4200
4335
  @click=${(e) => {
4201
4336
  this.processMessage(e, prompt, true);
4202
- this.sendEvent('promptClicked');
4337
+ this.sendEvent('promptClicked', undefined, {
4338
+ promptName: prompt,
4339
+ });
4203
4340
  }}
4204
4341
  >
4205
4342
  ${prompt}
@@ -4213,7 +4350,9 @@ ${this.comment ? this.comment : E}</textarea
4213
4350
  href=${link}
4214
4351
  target="_blank"
4215
4352
  rel="noopener"
4216
- @click=${() => this.sendEvent('promptClicked')}
4353
+ @click=${() => this.sendEvent('promptClicked', undefined, {
4354
+ promptName: prompt,
4355
+ })}
4217
4356
  >
4218
4357
  ${prompt}
4219
4358
  </a>
@@ -4404,7 +4543,7 @@ ${this.comment ? this.comment : E}</textarea
4404
4543
  <div class="title-wrapper">
4405
4544
  <h2>Search History</h2>
4406
4545
  ${this.chatThreads.size
4407
- ? x `<div
4546
+ ? x ` <div
4408
4547
  class="trash-icon"
4409
4548
  @click=${() => {
4410
4549
  if (this.isStreaming) {
@@ -4810,9 +4949,6 @@ ${this.comment ? this.comment : E}</textarea
4810
4949
  this.startNudgeTimer();
4811
4950
  }
4812
4951
  disconnectedCallback() {
4813
- if (!this.loadUIManually) {
4814
- window.removeEventListener('edgetag-initialized', this.loadData);
4815
- }
4816
4952
  window.removeEventListener('popstate', this.onPopState);
4817
4953
  if (this.nudgeTimer) {
4818
4954
  window.clearTimeout(this.nudgeTimer);
@@ -4820,16 +4956,9 @@ ${this.comment ? this.comment : E}</textarea
4820
4956
  super.disconnectedCallback();
4821
4957
  }
4822
4958
  init() {
4823
- if (this.loadUIManually) {
4824
- // this is because edgetag-initialized will already be
4825
- // triggered before the loadUI function is called to load the UI
4826
- this.loadData();
4827
- }
4828
- else {
4829
- window.addEventListener('edgetag-initialized', this.loadData);
4830
- }
4959
+ this.loadData();
4831
4960
  window.addEventListener('popstate', this.onPopState);
4832
- this.shopGPTAPI.sendEvent('shopGPTInitialized', this.getSiteCurrency().currency);
4961
+ this.shopGPTAPI.sendEvent('shopGPTLoaded');
4833
4962
  if (!this.view || this.view === 'overlay') {
4834
4963
  delay(DIALOG_DELAY)
4835
4964
  .then(() => {
@@ -4973,10 +5102,17 @@ ${this.comment ? this.comment : E}</textarea
4973
5102
  }
4974
5103
  }
4975
5104
  async setSelectedThreadId(threadId, silent) {
5105
+ var _a, _b, _c, _d;
4976
5106
  this.isFailed = false;
5107
+ const currentThreadId = this.selectedThreadId;
4977
5108
  this.selectedThreadId = threadId;
4978
5109
  if (threadId && !silent) {
4979
- 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
+ });
4980
5116
  }
4981
5117
  await Promise.all([
4982
5118
  this.loadHistory(threadId),
@@ -5002,6 +5138,7 @@ ${this.comment ? this.comment : E}</textarea
5002
5138
  }
5003
5139
  }
5004
5140
  handleThreadDelete(e) {
5141
+ var _a, _b;
5005
5142
  e.stopPropagation();
5006
5143
  this.isLoadingThreads = true;
5007
5144
  const threadId = e.detail.threadId;
@@ -5009,7 +5146,10 @@ ${this.comment ? this.comment : E}</textarea
5009
5146
  logger.error('ThreadId is missing to delete the thread!');
5010
5147
  return;
5011
5148
  }
5012
- 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
+ });
5013
5153
  this.shopGPTAPI
5014
5154
  .deleteSingleThread(threadId)
5015
5155
  .then(this.loadChatThreads.bind(this))
@@ -5137,7 +5277,10 @@ ${this.comment ? this.comment : E}</textarea
5137
5277
  try {
5138
5278
  this.isPreviousMessagePrompt = isPrompt;
5139
5279
  if (!isPrompt) {
5140
- this.shopGPTAPI.sendEvent('queryInteractions', this.getSiteCurrency().currency);
5280
+ this.shopGPTAPI.sendEvent('queryInteractions', this.getSiteCurrency().currency, undefined, {
5281
+ query: message,
5282
+ threadId: this.selectedThreadId,
5283
+ });
5141
5284
  }
5142
5285
  this.messages = [{ sender: 'user', message }, ...this.messages];
5143
5286
  this.isTyping = true;
@@ -5169,15 +5312,25 @@ ${this.comment ? this.comment : E}</textarea
5169
5312
  }
5170
5313
  sendEvent(e) {
5171
5314
  e.stopPropagation();
5172
- 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);
5173
5316
  }
5174
5317
  productClicked(e) {
5318
+ var _a, _b;
5175
5319
  e.stopPropagation();
5176
- setProductAction(this.destination, this.sessionId, e.detail.productId, 'clicked', true);
5320
+ setProductAction(this.destination, this.sessionId, e.detail.id, 'clicked', true);
5177
5321
  this.shopGPTAPI.sendEvent('productRecommendationClicked', this.getSiteCurrency().currency, {
5178
- productId: e.detail.productId,
5322
+ productId: e.detail.id,
5179
5323
  value: e.detail.value,
5180
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,
5181
5334
  });
5182
5335
  }
5183
5336
  getSiteCurrency() {
@@ -5208,6 +5361,7 @@ ${this.comment ? this.comment : E}</textarea
5208
5361
  .css=${this.css}
5209
5362
  ></chat-threads>
5210
5363
  <products-section
5364
+ .messages=${this.messages}
5211
5365
  .merchantImage=${this.merchantImage}
5212
5366
  .products=${this.products}
5213
5367
  .isLoadingHistory=${this.isLoadingHistory}
@@ -5253,26 +5407,23 @@ ${this.comment ? this.comment : E}</textarea
5253
5407
  <button
5254
5408
  @click=${(e) => {
5255
5409
  e.preventDefault();
5256
- this.shopGPTAPI.sendEvent('chatbotOpened', this.getSiteCurrency().currency);
5257
- this.modalState = 'open';
5258
- this.handleUserInteraction();
5410
+ this.openModal();
5259
5411
  }}
5260
5412
  >
5261
5413
  ${chatIcon}
5262
5414
  </button>
5263
5415
  ${((_a = this.nudge) === null || _a === void 0 ? void 0 : _a.show) && this.showNudge
5264
- ? x `<div
5416
+ ? x ` <div
5265
5417
  class="nudge"
5266
5418
  @click=${(e) => {
5267
5419
  e.preventDefault();
5268
- this.modalState = 'open';
5269
- this.handleUserInteraction();
5420
+ this.openModal();
5270
5421
  }}
5271
5422
  >
5272
5423
  Hi there! I'm an AI Agent to help you find the perfect product.
5273
5424
  What are you looking for today?
5274
5425
  </div>`
5275
- : x `<div class="chatbot-hover-text">
5426
+ : x ` <div class="chatbot-hover-text">
5276
5427
  What are you looking for today?
5277
5428
  </div>`}
5278
5429
  </div>`;
@@ -5316,6 +5467,12 @@ ${this.comment ? this.comment : E}</textarea
5316
5467
  </div>
5317
5468
  `;
5318
5469
  }
5470
+ openModal() {
5471
+ setIsBotOpened(this.destination, this.sessionId, true);
5472
+ this.shopGPTAPI.sendEvent('chatbotOpened');
5473
+ this.modalState = 'open';
5474
+ this.handleUserInteraction();
5475
+ }
5319
5476
  startNudgeTimer() {
5320
5477
  var _a, _b;
5321
5478
  if (this.view !== 'modal' || !((_a = this.nudge) === null || _a === void 0 ? void 0 : _a.show)) {
@@ -5354,6 +5511,11 @@ ${this.comment ? this.comment : E}</textarea
5354
5511
  }
5355
5512
  render() {
5356
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
+ }
5357
5519
  return this.modalMode();
5358
5520
  }
5359
5521
  return this.overlayMode();
@@ -5463,14 +5625,13 @@ ${this.comment ? this.comment : E}</textarea
5463
5625
  logger.log('ShopGPT component added already!');
5464
5626
  return;
5465
5627
  }
5628
+ setWasUserExposed(shopGPT.destination, shopGPT.sessionId, true);
5466
5629
  document.body.append(shopGPT);
5467
- setShopGPTLoaded(shopGPT.destination, shopGPT.sessionId, true);
5468
5630
  },
5469
5631
  destroy() {
5470
5632
  if (!shopGPT) {
5471
5633
  return;
5472
5634
  }
5473
- setShopGPTLoaded(shopGPT.destination, shopGPT.sessionId, false);
5474
5635
  shopGPT.remove();
5475
5636
  shopGPT = undefined;
5476
5637
  delete window[registryKey];