@blotoutio/providers-shop-gpt-sdk 1.11.3 → 1.11.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs.js +295 -130
- package/index.js +295 -130
- package/index.mjs +295 -130
- package/package.json +1 -1
package/index.mjs
CHANGED
@@ -374,6 +374,8 @@ const createDisabled = () => ({
|
|
374
374
|
groupName: '',
|
375
375
|
isEnabled: false,
|
376
376
|
});
|
377
|
+
// userId => 92ae5ac6-b47c-4444-923f-87d98b7e1fac-1743927514247
|
378
|
+
// sample => 92ae5ac6
|
377
379
|
const createABTest = ({ userId }) => {
|
378
380
|
const [sample] = userId.split('-');
|
379
381
|
const segment = parseInt(sample, 16) % 2;
|
@@ -409,6 +411,7 @@ const createExperiment = (props) => {
|
|
409
411
|
/** Action length should not exceed 42 */
|
410
412
|
const uiActions = new Set([
|
411
413
|
'shopGPTInitialized',
|
414
|
+
'shopGPTLoaded',
|
412
415
|
'chatbotOpened',
|
413
416
|
'chatbotClosed',
|
414
417
|
'singleThreadDelete',
|
@@ -623,16 +626,16 @@ const setProductAction = (destination, sessionId, productId, action, value) => {
|
|
623
626
|
const updatedLocal = { [sessionId]: local[sessionId] };
|
624
627
|
saveLocalStorageData(destination, updatedLocal);
|
625
628
|
};
|
626
|
-
const
|
629
|
+
const getWasUserExposed = (destination, sessionId) => {
|
627
630
|
var _a, _b;
|
628
631
|
const local = getLocalStorageData(destination);
|
629
632
|
if (!local || !sessionId) {
|
630
633
|
logger.error('No local storage data or session id');
|
631
634
|
return false;
|
632
635
|
}
|
633
|
-
return (_b = (_a = local[sessionId]) === null || _a === void 0 ? void 0 : _a.
|
636
|
+
return (_b = (_a = local[sessionId]) === null || _a === void 0 ? void 0 : _a.exposed) !== null && _b !== void 0 ? _b : false;
|
634
637
|
};
|
635
|
-
const
|
638
|
+
const setWasUserExposed = (destination, sessionId, value) => {
|
636
639
|
const local = getLocalStorageData(destination);
|
637
640
|
if (!local || !sessionId) {
|
638
641
|
logger.error('No local storage data or session id');
|
@@ -640,14 +643,60 @@ const setShopGPTLoaded = (destination, sessionId, value) => {
|
|
640
643
|
}
|
641
644
|
local[sessionId] = {
|
642
645
|
...local[sessionId],
|
643
|
-
|
646
|
+
exposed: value,
|
644
647
|
};
|
645
648
|
// Clear other sessions
|
646
649
|
const updatedLocal = { [sessionId]: local[sessionId] };
|
647
650
|
saveLocalStorageData(destination, updatedLocal);
|
648
651
|
};
|
652
|
+
const setUserType = (destination, sessionId, value) => {
|
653
|
+
const local = getLocalStorageData(destination);
|
654
|
+
if (!local || !sessionId) {
|
655
|
+
logger.error('No session id');
|
656
|
+
return;
|
657
|
+
}
|
658
|
+
local[sessionId] = {
|
659
|
+
...local[sessionId],
|
660
|
+
userType: value,
|
661
|
+
};
|
662
|
+
// Clear other sessions
|
663
|
+
const updatedLocal = { [sessionId]: local[sessionId] };
|
664
|
+
saveLocalStorageData(destination, updatedLocal);
|
665
|
+
};
|
666
|
+
const getUserType = (destination, sessionId) => {
|
667
|
+
var _a;
|
668
|
+
const local = getLocalStorageData(destination);
|
669
|
+
if (!sessionId) {
|
670
|
+
logger.error('No session id');
|
671
|
+
return;
|
672
|
+
}
|
673
|
+
return (_a = local === null || local === void 0 ? void 0 : local[sessionId]) === null || _a === void 0 ? void 0 : _a.userType;
|
674
|
+
};
|
675
|
+
const setIsBotOpened = (destination, sessionId, value) => {
|
676
|
+
const local = getLocalStorageData(destination);
|
677
|
+
if (!local || !sessionId) {
|
678
|
+
logger.error('No session id');
|
679
|
+
return;
|
680
|
+
}
|
681
|
+
local[sessionId] = {
|
682
|
+
...local[sessionId],
|
683
|
+
opened: value,
|
684
|
+
};
|
685
|
+
// Clear other sessions
|
686
|
+
const updatedLocal = { [sessionId]: local[sessionId] };
|
687
|
+
saveLocalStorageData(destination, updatedLocal);
|
688
|
+
};
|
689
|
+
const getIsBotOpened = (destination, sessionId) => {
|
690
|
+
var _a;
|
691
|
+
const local = getLocalStorageData(destination);
|
692
|
+
if (!sessionId) {
|
693
|
+
logger.error('No session id');
|
694
|
+
return;
|
695
|
+
}
|
696
|
+
return (_a = local === null || local === void 0 ? void 0 : local[sessionId]) === null || _a === void 0 ? void 0 : _a.opened;
|
697
|
+
};
|
649
698
|
|
650
|
-
const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, storeAPI, sessionId, }) => {
|
699
|
+
const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, storeAPI, sessionId, sendTag, }) => {
|
651
700
|
if (!baseURL) {
|
652
701
|
throw new Error(`baseURL missing`);
|
653
702
|
}
|
@@ -777,9 +826,12 @@ const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, st
|
|
777
826
|
const data = (await response.json());
|
778
827
|
return data.customPrompts;
|
779
828
|
};
|
780
|
-
const sendEvent = (action, currency, actionData) => {
|
829
|
+
const sendEvent = (action, currency, actionData, clickData) => {
|
781
830
|
var _a;
|
782
831
|
const storageData = (_a = getProductActions(baseURL, sessionId)) !== null && _a !== void 0 ? _a : {};
|
832
|
+
const userType = getUserType(baseURL, sessionId);
|
833
|
+
const exposed = getWasUserExposed(baseURL, sessionId);
|
834
|
+
const opened = getIsBotOpened(baseURL, sessionId);
|
783
835
|
// This endpoint sends user events to the server, we don't need to wait for the response
|
784
836
|
fetchImpl(getURL('/user/event'), {
|
785
837
|
method: 'POST',
|
@@ -791,7 +843,9 @@ const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, st
|
|
791
843
|
storageData: {
|
792
844
|
session: storageData,
|
793
845
|
preview: hasPreviewKey(),
|
794
|
-
|
846
|
+
userType: userType,
|
847
|
+
exposed,
|
848
|
+
opened: !!opened,
|
795
849
|
},
|
796
850
|
}),
|
797
851
|
credentials: 'include',
|
@@ -802,6 +856,21 @@ const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, st
|
|
802
856
|
}
|
803
857
|
})
|
804
858
|
.catch(logger.error);
|
859
|
+
sendTag({
|
860
|
+
eventId: crypto.randomUUID(),
|
861
|
+
eventName: action,
|
862
|
+
data: {
|
863
|
+
...actionData,
|
864
|
+
...clickData,
|
865
|
+
userType,
|
866
|
+
exposed,
|
867
|
+
storageData,
|
868
|
+
opened: !!opened,
|
869
|
+
},
|
870
|
+
providers: {
|
871
|
+
shopGPT: true,
|
872
|
+
},
|
873
|
+
});
|
805
874
|
};
|
806
875
|
return {
|
807
876
|
processQuery,
|
@@ -819,7 +888,7 @@ const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, st
|
|
819
888
|
// eslint-disable-next-line @nx/enforce-module-boundaries
|
820
889
|
const error = (message) => console.error(message);
|
821
890
|
const init = (params) => {
|
822
|
-
var _a, _b, _c
|
891
|
+
var _a, _b, _c;
|
823
892
|
if (typeof window == 'undefined' || typeof document == 'undefined') {
|
824
893
|
// if loaded in non-browser SDKs, return early
|
825
894
|
return;
|
@@ -838,7 +907,6 @@ const init = (params) => {
|
|
838
907
|
return;
|
839
908
|
}
|
840
909
|
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 : {};
|
841
|
-
setShopGPTLoaded(params.baseUrl, (_d = params.session) === null || _d === void 0 ? void 0 : _d.sessionId, !loadUIManually);
|
842
910
|
const experiment = createExperiment({
|
843
911
|
name: getExperimentName(mode),
|
844
912
|
userId: params.userId,
|
@@ -848,42 +916,65 @@ const init = (params) => {
|
|
848
916
|
if (experiment.name === 'preview' && shouldShowUI) {
|
849
917
|
logger.log('Enabling UI in preview mode');
|
850
918
|
}
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
919
|
+
// once we implement a general version with togglable option to discriminate
|
920
|
+
// between anon/known, we'll be able to skip creating this promise before
|
921
|
+
// init and possibly loading the UI
|
922
|
+
new Promise((resolve) => {
|
923
|
+
var _a;
|
924
|
+
const userType = getUserType(params.baseUrl, (_a = params.session) === null || _a === void 0 ? void 0 : _a.sessionId);
|
925
|
+
if (userType) {
|
926
|
+
return resolve();
|
856
927
|
}
|
928
|
+
params.getEdgeData(['email'], (data) => {
|
929
|
+
var _a;
|
930
|
+
setUserType(params.baseUrl, (_a = params.session) === null || _a === void 0 ? void 0 : _a.sessionId, data['emailExists'] ? 'known' : 'anon');
|
931
|
+
resolve();
|
932
|
+
});
|
933
|
+
}).then(() => {
|
934
|
+
var _a, _b;
|
857
935
|
const shopGPTAPI = createShopGPTAPI({
|
858
936
|
baseURL: params.baseUrl,
|
859
937
|
storeAPI,
|
860
938
|
userId: params.userId,
|
861
|
-
sessionId: (
|
939
|
+
sessionId: (_a = params.session) === null || _a === void 0 ? void 0 : _a.sessionId,
|
940
|
+
sendTag: params.sendTag,
|
862
941
|
});
|
863
|
-
|
864
|
-
|
865
|
-
storeAPI,
|
866
|
-
shopGPTAPI,
|
867
|
-
devMode,
|
868
|
-
view,
|
869
|
-
merchantUrl,
|
870
|
-
profiles,
|
871
|
-
productHandles,
|
872
|
-
path: targetPath,
|
873
|
-
brandName,
|
874
|
-
quickPrompts,
|
875
|
-
merchantImage,
|
876
|
-
latestThreadLoad: latestThreadLoad !== null && latestThreadLoad !== void 0 ? latestThreadLoad : DEFAULT_MAX_THREAD_AGE,
|
877
|
-
botIconUrl,
|
878
|
-
css,
|
879
|
-
nudge,
|
880
|
-
sessionId: (_f = params.session) === null || _f === void 0 ? void 0 : _f.sessionId,
|
881
|
-
loadUIManually,
|
942
|
+
shopGPTAPI.sendEvent('shopGPTInitialized', undefined, undefined, {
|
943
|
+
groupName: experiment.groupName,
|
882
944
|
});
|
883
|
-
if (
|
884
|
-
uiImplementation.
|
945
|
+
if (shouldShowUI) {
|
946
|
+
const uiImplementation = window[registryKey].ui;
|
947
|
+
if (!uiImplementation) {
|
948
|
+
error('UI implementation is missing');
|
949
|
+
return;
|
950
|
+
}
|
951
|
+
uiImplementation.init({
|
952
|
+
destination: params.baseUrl,
|
953
|
+
storeAPI,
|
954
|
+
shopGPTAPI,
|
955
|
+
devMode,
|
956
|
+
view,
|
957
|
+
merchantUrl,
|
958
|
+
profiles,
|
959
|
+
productHandles,
|
960
|
+
path: targetPath,
|
961
|
+
brandName,
|
962
|
+
quickPrompts,
|
963
|
+
merchantImage,
|
964
|
+
latestThreadLoad: latestThreadLoad !== null && latestThreadLoad !== void 0 ? latestThreadLoad : DEFAULT_MAX_THREAD_AGE,
|
965
|
+
botIconUrl,
|
966
|
+
css,
|
967
|
+
nudge,
|
968
|
+
sessionId: (_b = params.session) === null || _b === void 0 ? void 0 : _b.sessionId,
|
969
|
+
loadUIManually,
|
970
|
+
});
|
971
|
+
const searchParams = new URLSearchParams(window.location.search);
|
972
|
+
const hasSource = searchParams.get('utm_source') === 'shopgpt';
|
973
|
+
if (!loadUIManually || hasSource) {
|
974
|
+
uiImplementation.loadUI();
|
975
|
+
}
|
885
976
|
}
|
886
|
-
}
|
977
|
+
});
|
887
978
|
};
|
888
979
|
|
889
980
|
const getClickedProductsInContents = (destination, sessionId, data) => {
|
@@ -895,7 +986,7 @@ const getClickedProductsInContents = (destination, sessionId, data) => {
|
|
895
986
|
return contents.flatMap((content) => { var _a; return ((_a = storedData[content.id]) === null || _a === void 0 ? void 0 : _a.clicked) ? [content.id] : []; });
|
896
987
|
};
|
897
988
|
const tag = ({ eventName, destination, data, sessionId, }) => {
|
898
|
-
var _a;
|
989
|
+
var _a, _b;
|
899
990
|
const clickedProducts = getClickedProductsInContents(destination, sessionId, data);
|
900
991
|
if (eventName === 'AddToCart') {
|
901
992
|
clickedProducts === null || clickedProducts === void 0 ? void 0 : clickedProducts.forEach((id) => {
|
@@ -910,7 +1001,9 @@ const tag = ({ eventName, destination, data, sessionId, }) => {
|
|
910
1001
|
return {
|
911
1002
|
session: getProductActions(destination, sessionId),
|
912
1003
|
preview: hasPreviewKey(),
|
913
|
-
|
1004
|
+
exposed: (_a = getWasUserExposed(destination, sessionId)) !== null && _a !== void 0 ? _a : false,
|
1005
|
+
userType: getUserType(destination, sessionId),
|
1006
|
+
opened: (_b = getIsBotOpened(destination, sessionId)) !== null && _b !== void 0 ? _b : false,
|
914
1007
|
};
|
915
1008
|
};
|
916
1009
|
|
@@ -1780,13 +1873,13 @@ const productItemStyles = i$4 `
|
|
1780
1873
|
.product {
|
1781
1874
|
display: flex;
|
1782
1875
|
gap: 16px;
|
1876
|
+
cursor: pointer;
|
1783
1877
|
|
1784
1878
|
img {
|
1785
1879
|
width: 150px;
|
1786
1880
|
height: 186px;
|
1787
1881
|
object-position: center;
|
1788
1882
|
object-fit: contain;
|
1789
|
-
cursor: pointer;
|
1790
1883
|
}
|
1791
1884
|
}
|
1792
1885
|
|
@@ -1811,7 +1904,6 @@ const productItemStyles = i$4 `
|
|
1811
1904
|
text-overflow: ellipsis;
|
1812
1905
|
word-break: break-word;
|
1813
1906
|
white-space: normal;
|
1814
|
-
cursor: pointer;
|
1815
1907
|
}
|
1816
1908
|
|
1817
1909
|
.product-variation-details {
|
@@ -1922,11 +2014,14 @@ class ProductItem extends r$2 {
|
|
1922
2014
|
${this.getLocalPrice(comparedAtPrice)}
|
1923
2015
|
</p>`;
|
1924
2016
|
}
|
1925
|
-
|
2017
|
+
openProduct(url) {
|
1926
2018
|
if (!url) {
|
1927
2019
|
return;
|
1928
2020
|
}
|
1929
|
-
|
2021
|
+
const link = new URL(url);
|
2022
|
+
link.searchParams.set('utm_source', 'shopgpt');
|
2023
|
+
link.searchParams.set('utm_medium', 'chat');
|
2024
|
+
open(link, '_self');
|
1930
2025
|
}
|
1931
2026
|
renderVariantTitles() {
|
1932
2027
|
if (this.product.hasOnlyDefaultVariant) {
|
@@ -1936,39 +2031,32 @@ class ProductItem extends r$2 {
|
|
1936
2031
|
<p class="product-variation-details">${option.name}: ${option.value}</p>
|
1937
2032
|
`);
|
1938
2033
|
}
|
1939
|
-
productClicked(
|
1940
|
-
if (
|
2034
|
+
productClicked(product) {
|
2035
|
+
if (product.id) {
|
2036
|
+
const price = product.variants[0].price;
|
1941
2037
|
this.dispatchEvent(new CustomEvent('product-clicked', {
|
1942
2038
|
detail: {
|
1943
|
-
|
2039
|
+
id: product.id,
|
1944
2040
|
value: price ? parseFloat(price) : undefined,
|
2041
|
+
variantId: product.variants[0].id,
|
2042
|
+
title: product.title,
|
2043
|
+
url: product.url,
|
2044
|
+
query: this.query,
|
2045
|
+
response: this.response,
|
2046
|
+
rank: this.rank,
|
1945
2047
|
},
|
1946
2048
|
composed: true,
|
1947
2049
|
bubbles: true,
|
1948
2050
|
}));
|
1949
2051
|
}
|
1950
|
-
this.
|
2052
|
+
this.openProduct(product.url);
|
1951
2053
|
}
|
1952
2054
|
render() {
|
1953
2055
|
return x `
|
1954
|
-
<div class="product">
|
1955
|
-
<img
|
1956
|
-
src=${this.product.image.url}
|
1957
|
-
alt=${this.product.image.alt}
|
1958
|
-
@click=${() => {
|
1959
|
-
var _a;
|
1960
|
-
return this.productClicked(this.product.id, this.product.variants[0].price, (_a = this.product) === null || _a === void 0 ? void 0 : _a.url);
|
1961
|
-
}}
|
1962
|
-
/>
|
2056
|
+
<div class="product" @click=${() => this.productClicked(this.product)}>
|
2057
|
+
<img src=${this.product.image.url} alt=${this.product.image.alt} />
|
1963
2058
|
<div class="content">
|
1964
|
-
<p
|
1965
|
-
class="product-name"
|
1966
|
-
title=${this.product.title}
|
1967
|
-
@click=${() => {
|
1968
|
-
var _a;
|
1969
|
-
return this.productClicked(this.product.id, this.product.variants[0].price, (_a = this.product) === null || _a === void 0 ? void 0 : _a.url);
|
1970
|
-
}}
|
1971
|
-
>
|
2059
|
+
<p class="product-name" title=${this.product.title}>
|
1972
2060
|
${this.product.title}
|
1973
2061
|
</p>
|
1974
2062
|
${this.renderVariantTitles()}
|
@@ -1976,15 +2064,7 @@ class ProductItem extends r$2 {
|
|
1976
2064
|
${this.getComparedAtPrice(this.product.variants[0].comparedAtPrice, this.product.variants[0].price)}
|
1977
2065
|
<p>${this.getLocalPrice(this.product.variants[0].price)}</p>
|
1978
2066
|
</div>
|
1979
|
-
<button
|
1980
|
-
class="btn-view-product"
|
1981
|
-
@click=${() => {
|
1982
|
-
var _a;
|
1983
|
-
return this.productClicked(this.product.id, this.product.variants[0].price, (_a = this.product) === null || _a === void 0 ? void 0 : _a.url);
|
1984
|
-
}}
|
1985
|
-
>
|
1986
|
-
View Product
|
1987
|
-
</button>
|
2067
|
+
<button class="btn-view-product">View Product</button>
|
1988
2068
|
</div>
|
1989
2069
|
</div>
|
1990
2070
|
`;
|
@@ -1999,6 +2079,18 @@ __decorate([
|
|
1999
2079
|
n({ type: Object }),
|
2000
2080
|
__metadata("design:type", Object)
|
2001
2081
|
], ProductItem.prototype, "siteCurrency", void 0);
|
2082
|
+
__decorate([
|
2083
|
+
n({ type: String }),
|
2084
|
+
__metadata("design:type", Object)
|
2085
|
+
], ProductItem.prototype, "query", void 0);
|
2086
|
+
__decorate([
|
2087
|
+
n({ type: String }),
|
2088
|
+
__metadata("design:type", String)
|
2089
|
+
], ProductItem.prototype, "response", void 0);
|
2090
|
+
__decorate([
|
2091
|
+
n({ type: Number }),
|
2092
|
+
__metadata("design:type", Number)
|
2093
|
+
], ProductItem.prototype, "rank", void 0);
|
2002
2094
|
if (!customElements.get('product-item')) {
|
2003
2095
|
customElements.define('product-item', ProductItem);
|
2004
2096
|
}
|
@@ -2115,7 +2207,7 @@ class ProductsList extends r$2 {
|
|
2115
2207
|
return x `
|
2116
2208
|
<div class="products-wrapper">
|
2117
2209
|
<div class="products" @scroll=${this.updateButtonsState}>
|
2118
|
-
${o$1(this.products, (product) => x `
|
2210
|
+
${o$1(this.products, (product, index) => x `
|
2119
2211
|
<div
|
2120
2212
|
class=${e$1({
|
2121
2213
|
'product-container': true,
|
@@ -2123,8 +2215,11 @@ class ProductsList extends r$2 {
|
|
2123
2215
|
})}
|
2124
2216
|
>
|
2125
2217
|
<product-item
|
2218
|
+
.query=${this.query}
|
2219
|
+
.response=${this.response}
|
2126
2220
|
.product=${product}
|
2127
2221
|
.siteCurrency=${this.siteCurrency}
|
2222
|
+
.rank=${index + 1}
|
2128
2223
|
></product-item>
|
2129
2224
|
</div>
|
2130
2225
|
`)}
|
@@ -2152,6 +2247,14 @@ __decorate([
|
|
2152
2247
|
n({ type: Object }),
|
2153
2248
|
__metadata("design:type", Object)
|
2154
2249
|
], ProductsList.prototype, "siteCurrency", void 0);
|
2250
|
+
__decorate([
|
2251
|
+
n({ type: String }),
|
2252
|
+
__metadata("design:type", Object)
|
2253
|
+
], ProductsList.prototype, "query", void 0);
|
2254
|
+
__decorate([
|
2255
|
+
n({ type: String }),
|
2256
|
+
__metadata("design:type", String)
|
2257
|
+
], ProductsList.prototype, "response", void 0);
|
2155
2258
|
__decorate([
|
2156
2259
|
r(),
|
2157
2260
|
__metadata("design:type", Object)
|
@@ -2198,6 +2301,7 @@ class ProductsSection extends r$2 {
|
|
2198
2301
|
`;
|
2199
2302
|
}
|
2200
2303
|
render() {
|
2304
|
+
var _a;
|
2201
2305
|
if (this.isLoadingHistory || this.isLoadingThreads) {
|
2202
2306
|
return x ` <load-spinner></load-spinner> `;
|
2203
2307
|
}
|
@@ -2208,18 +2312,25 @@ class ProductsSection extends r$2 {
|
|
2208
2312
|
}
|
2209
2313
|
const topResult = this.products[0];
|
2210
2314
|
const others = this.products.slice(1);
|
2315
|
+
const query = (_a = this.messages) === null || _a === void 0 ? void 0 : _a[1];
|
2316
|
+
const response = this.messages[0];
|
2211
2317
|
return x `
|
2212
2318
|
<div class="top-result">
|
2213
2319
|
<h2>Top Result</h2>
|
2214
2320
|
<product-item
|
2321
|
+
.query=${query === null || query === void 0 ? void 0 : query.message}
|
2322
|
+
.response=${response === null || response === void 0 ? void 0 : response.message}
|
2215
2323
|
.product=${topResult}
|
2216
2324
|
.siteCurrency=${this.siteCurrency}
|
2325
|
+
.rank=${1}
|
2217
2326
|
></product-item>
|
2218
2327
|
</div>
|
2219
2328
|
<span class="line"></span>
|
2220
2329
|
<div class="others">
|
2221
2330
|
<h2>Other Recommendations</h2>
|
2222
2331
|
<products-list
|
2332
|
+
.query=${query === null || query === void 0 ? void 0 : query.message}
|
2333
|
+
.response=${response === null || response === void 0 ? void 0 : response.message}
|
2223
2334
|
.products=${others}
|
2224
2335
|
.siteCurrency=${this.siteCurrency}
|
2225
2336
|
.viewType=${'overlay'}
|
@@ -2265,6 +2376,10 @@ __decorate([
|
|
2265
2376
|
n({ type: String }),
|
2266
2377
|
__metadata("design:type", String)
|
2267
2378
|
], ProductsSection.prototype, "css", void 0);
|
2379
|
+
__decorate([
|
2380
|
+
n({ type: Array }),
|
2381
|
+
__metadata("design:type", Array)
|
2382
|
+
], ProductsSection.prototype, "messages", void 0);
|
2268
2383
|
if (!customElements.get('products-section')) {
|
2269
2384
|
customElements.define('products-section', ProductsSection);
|
2270
2385
|
}
|
@@ -3991,9 +4106,9 @@ class ChatSection extends r$2 {
|
|
3991
4106
|
}
|
3992
4107
|
await this.sendMessageToServer(e, message, isPrompt);
|
3993
4108
|
}
|
3994
|
-
sendEvent(action, actionData) {
|
4109
|
+
sendEvent(action, actionData, clickData) {
|
3995
4110
|
this.dispatchEvent(new CustomEvent('send-event', {
|
3996
|
-
detail: { action, actionData },
|
4111
|
+
detail: { action, actionData, clickData },
|
3997
4112
|
composed: true,
|
3998
4113
|
bubbles: true,
|
3999
4114
|
}));
|
@@ -4024,24 +4139,38 @@ class ChatSection extends r$2 {
|
|
4024
4139
|
}));
|
4025
4140
|
this.deleteThreadId = '';
|
4026
4141
|
}
|
4027
|
-
handleFeedback(rating, messageId, queryMessageId, comment) {
|
4028
|
-
var _a, _b;
|
4142
|
+
handleFeedback(rating, messageId, queryMessageId, comment, query, response) {
|
4143
|
+
var _a, _b, _c, _d;
|
4029
4144
|
if (rating === 'bad') {
|
4030
|
-
this.sendEvent('thumbsDown'
|
4145
|
+
this.sendEvent('thumbsDown', undefined, {
|
4146
|
+
messageId,
|
4147
|
+
threadId: ((_a = this.thread) === null || _a === void 0 ? void 0 : _a.threadId) || '',
|
4148
|
+
rating,
|
4149
|
+
comment: comment !== null && comment !== void 0 ? comment : '',
|
4150
|
+
query: query !== null && query !== void 0 ? query : '',
|
4151
|
+
response: response !== null && response !== void 0 ? response : '',
|
4152
|
+
});
|
4031
4153
|
this.feedbackDetails = {
|
4032
4154
|
messageId,
|
4033
4155
|
queryMessageId,
|
4034
|
-
threadId: ((
|
4156
|
+
threadId: ((_b = this.thread) === null || _b === void 0 ? void 0 : _b.threadId) || '',
|
4035
4157
|
comment,
|
4036
4158
|
};
|
4037
4159
|
return;
|
4038
4160
|
}
|
4039
|
-
this.sendEvent('thumbsUp'
|
4161
|
+
this.sendEvent('thumbsUp', undefined, {
|
4162
|
+
messageId,
|
4163
|
+
threadId: ((_c = this.thread) === null || _c === void 0 ? void 0 : _c.threadId) || '',
|
4164
|
+
rating,
|
4165
|
+
comment: comment !== null && comment !== void 0 ? comment : '',
|
4166
|
+
query: query !== null && query !== void 0 ? query : '',
|
4167
|
+
response: response !== null && response !== void 0 ? response : '',
|
4168
|
+
});
|
4040
4169
|
this.dispatchEvent(new CustomEvent('submit-feedback', {
|
4041
4170
|
detail: {
|
4042
4171
|
messageId: messageId,
|
4043
4172
|
queryMessageId: queryMessageId,
|
4044
|
-
threadId: (
|
4173
|
+
threadId: (_d = this.thread) === null || _d === void 0 ? void 0 : _d.threadId,
|
4045
4174
|
feedback: {
|
4046
4175
|
rating,
|
4047
4176
|
comment: null,
|
@@ -4076,8 +4205,11 @@ class ChatSection extends r$2 {
|
|
4076
4205
|
<span class="line"></span>
|
4077
4206
|
<div class="product-container">
|
4078
4207
|
<product-item
|
4208
|
+
.query=${queryMessage === null || queryMessage === void 0 ? void 0 : queryMessage.message}
|
4209
|
+
.response=${message.message}
|
4079
4210
|
.product=${message.products[0]}
|
4080
4211
|
.siteCurrency=${this.siteCurrency}
|
4212
|
+
.rank=${1}
|
4081
4213
|
></product-item>
|
4082
4214
|
</div>
|
4083
4215
|
`
|
@@ -4086,16 +4218,18 @@ class ChatSection extends r$2 {
|
|
4086
4218
|
</div>
|
4087
4219
|
${this.viewType === 'modal' && message.products
|
4088
4220
|
? x ` <products-list
|
4221
|
+
.query=${queryMessage === null || queryMessage === void 0 ? void 0 : queryMessage.message}
|
4222
|
+
.response=${message.message}
|
4089
4223
|
.products=${message.products}
|
4090
4224
|
.siteCurrency=${this.siteCurrency}
|
4091
4225
|
.viewType=${this.viewType}
|
4092
4226
|
></products-list>`
|
4093
4227
|
: E}
|
4094
4228
|
${message.messageId && (queryMessage === null || queryMessage === void 0 ? void 0 : queryMessage.messageId)
|
4095
|
-
? x
|
4229
|
+
? x ` <div class="bot-response-actions">
|
4096
4230
|
<button
|
4097
4231
|
type="button"
|
4098
|
-
@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)}
|
4232
|
+
@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 === null || queryMessage === void 0 ? void 0 : queryMessage.message, message === null || message === void 0 ? void 0 : message.message)}
|
4099
4233
|
>
|
4100
4234
|
${((_c = message.feedback) === null || _c === void 0 ? void 0 : _c.rating) === 'good'
|
4101
4235
|
? thumbsUpFilledBtn
|
@@ -4103,7 +4237,7 @@ class ChatSection extends r$2 {
|
|
4103
4237
|
</button>
|
4104
4238
|
<button
|
4105
4239
|
type="button"
|
4106
|
-
@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)}
|
4240
|
+
@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 === null || queryMessage === void 0 ? void 0 : queryMessage.message, message === null || message === void 0 ? void 0 : message.message)}
|
4107
4241
|
>
|
4108
4242
|
${((_e = message.feedback) === null || _e === void 0 ? void 0 : _e.rating) === 'bad'
|
4109
4243
|
? thumbsDownFilledBtn
|
@@ -4116,7 +4250,7 @@ class ChatSection extends r$2 {
|
|
4116
4250
|
}
|
4117
4251
|
renderBotIcon() {
|
4118
4252
|
if (this.botIconUrl) {
|
4119
|
-
return x
|
4253
|
+
return x ` <div class="bot-icon">
|
4120
4254
|
<img src=${this.botIconUrl} width="30" height="30" />
|
4121
4255
|
</div>`;
|
4122
4256
|
}
|
@@ -4124,7 +4258,7 @@ class ChatSection extends r$2 {
|
|
4124
4258
|
}
|
4125
4259
|
chatWindow() {
|
4126
4260
|
if (this.isLoadingHistory || this.isLoadingThreads) {
|
4127
|
-
return x
|
4261
|
+
return x ` <div class="messages loading">
|
4128
4262
|
<load-spinner></load-spinner>
|
4129
4263
|
</div>`;
|
4130
4264
|
}
|
@@ -4137,7 +4271,7 @@ class ChatSection extends r$2 {
|
|
4137
4271
|
</div>`
|
4138
4272
|
: ''}
|
4139
4273
|
${this.isFailed
|
4140
|
-
? x
|
4274
|
+
? x ` <div class="message bot">
|
4141
4275
|
<div>${this.renderBotIcon()}</div>
|
4142
4276
|
<div>
|
4143
4277
|
<p>
|
@@ -4157,18 +4291,20 @@ class ChatSection extends r$2 {
|
|
4157
4291
|
})}
|
4158
4292
|
${!this.fromAd || !this.thread
|
4159
4293
|
? x `
|
4160
|
-
|
4161
|
-
|
4162
|
-
|
4163
|
-
|
4164
|
-
|
4165
|
-
|
4166
|
-
|
4167
|
-
|
4168
|
-
|
4169
|
-
|
4170
|
-
|
4171
|
-
|
4294
|
+
<div class="message bot">
|
4295
|
+
<div>${this.renderBotIcon()}</div>
|
4296
|
+
<div>
|
4297
|
+
<p>
|
4298
|
+
Hi,
|
4299
|
+
${this.brandName
|
4300
|
+
? x `Welcome to ${this.brandName}.`
|
4301
|
+
: E}
|
4302
|
+
I'm here to help you find the perfect product. Pick a suggested
|
4303
|
+
prompt from below, or enter your own query.
|
4304
|
+
</p>
|
4305
|
+
</div>
|
4306
|
+
</div>
|
4307
|
+
</div>`
|
4172
4308
|
: E}
|
4173
4309
|
</div>
|
4174
4310
|
`;
|
@@ -4195,7 +4331,9 @@ class ChatSection extends r$2 {
|
|
4195
4331
|
class="prompt"
|
4196
4332
|
@click=${(e) => {
|
4197
4333
|
this.processMessage(e, prompt, true);
|
4198
|
-
this.sendEvent('promptClicked'
|
4334
|
+
this.sendEvent('promptClicked', undefined, {
|
4335
|
+
promptName: prompt,
|
4336
|
+
});
|
4199
4337
|
}}
|
4200
4338
|
>
|
4201
4339
|
${prompt}
|
@@ -4209,7 +4347,9 @@ class ChatSection extends r$2 {
|
|
4209
4347
|
href=${link}
|
4210
4348
|
target="_blank"
|
4211
4349
|
rel="noopener"
|
4212
|
-
@click=${() => this.sendEvent('promptClicked'
|
4350
|
+
@click=${() => this.sendEvent('promptClicked', undefined, {
|
4351
|
+
promptName: prompt,
|
4352
|
+
})}
|
4213
4353
|
>
|
4214
4354
|
${prompt}
|
4215
4355
|
</a>
|
@@ -4400,7 +4540,7 @@ class ChatSection extends r$2 {
|
|
4400
4540
|
<div class="title-wrapper">
|
4401
4541
|
<h2>Search History</h2>
|
4402
4542
|
${this.chatThreads.size
|
4403
|
-
? x
|
4543
|
+
? x ` <div
|
4404
4544
|
class="trash-icon"
|
4405
4545
|
@click=${() => {
|
4406
4546
|
if (this.isStreaming) {
|
@@ -4806,9 +4946,6 @@ class ShopGPT extends r$2 {
|
|
4806
4946
|
this.startNudgeTimer();
|
4807
4947
|
}
|
4808
4948
|
disconnectedCallback() {
|
4809
|
-
if (!this.loadUIManually) {
|
4810
|
-
window.removeEventListener('edgetag-initialized', this.loadData);
|
4811
|
-
}
|
4812
4949
|
window.removeEventListener('popstate', this.onPopState);
|
4813
4950
|
if (this.nudgeTimer) {
|
4814
4951
|
window.clearTimeout(this.nudgeTimer);
|
@@ -4816,16 +4953,9 @@ class ShopGPT extends r$2 {
|
|
4816
4953
|
super.disconnectedCallback();
|
4817
4954
|
}
|
4818
4955
|
init() {
|
4819
|
-
|
4820
|
-
// this is because edgetag-initialized will already be
|
4821
|
-
// triggered before the loadUI function is called to load the UI
|
4822
|
-
this.loadData();
|
4823
|
-
}
|
4824
|
-
else {
|
4825
|
-
window.addEventListener('edgetag-initialized', this.loadData);
|
4826
|
-
}
|
4956
|
+
this.loadData();
|
4827
4957
|
window.addEventListener('popstate', this.onPopState);
|
4828
|
-
this.shopGPTAPI.sendEvent('
|
4958
|
+
this.shopGPTAPI.sendEvent('shopGPTLoaded');
|
4829
4959
|
if (!this.view || this.view === 'overlay') {
|
4830
4960
|
delay(DIALOG_DELAY)
|
4831
4961
|
.then(() => {
|
@@ -4841,6 +4971,14 @@ class ShopGPT extends r$2 {
|
|
4841
4971
|
})
|
4842
4972
|
.catch(logger.error);
|
4843
4973
|
}
|
4974
|
+
else if (this.view === 'modal') {
|
4975
|
+
const searchParams = new URLSearchParams(window.location.search);
|
4976
|
+
const hasSource = searchParams.get('utm_source') === 'shopgpt';
|
4977
|
+
// If the url has `utm_source` open the popup when reloaded
|
4978
|
+
if (hasSource) {
|
4979
|
+
this.modalState = 'open';
|
4980
|
+
}
|
4981
|
+
}
|
4844
4982
|
}
|
4845
4983
|
setChatTitle(threadId, title) {
|
4846
4984
|
if (!title || !threadId) {
|
@@ -4969,10 +5107,17 @@ class ShopGPT extends r$2 {
|
|
4969
5107
|
}
|
4970
5108
|
}
|
4971
5109
|
async setSelectedThreadId(threadId, silent) {
|
5110
|
+
var _a, _b, _c, _d;
|
4972
5111
|
this.isFailed = false;
|
5112
|
+
const currentThreadId = this.selectedThreadId;
|
4973
5113
|
this.selectedThreadId = threadId;
|
4974
5114
|
if (threadId && !silent) {
|
4975
|
-
this.shopGPTAPI.sendEvent('switchThread'
|
5115
|
+
this.shopGPTAPI.sendEvent('switchThread', undefined, undefined, {
|
5116
|
+
previousThread: currentThreadId,
|
5117
|
+
activeThread: threadId,
|
5118
|
+
previousThreadTitle: (_b = (_a = this.chatThreads.get(currentThreadId)) === null || _a === void 0 ? void 0 : _a.title) !== null && _b !== void 0 ? _b : '',
|
5119
|
+
activeThreadTitle: (_d = (_c = this.chatThreads.get(this.selectedThreadId)) === null || _c === void 0 ? void 0 : _c.title) !== null && _d !== void 0 ? _d : '',
|
5120
|
+
});
|
4976
5121
|
}
|
4977
5122
|
await Promise.all([
|
4978
5123
|
this.loadHistory(threadId),
|
@@ -4998,6 +5143,7 @@ class ShopGPT extends r$2 {
|
|
4998
5143
|
}
|
4999
5144
|
}
|
5000
5145
|
handleThreadDelete(e) {
|
5146
|
+
var _a, _b;
|
5001
5147
|
e.stopPropagation();
|
5002
5148
|
this.isLoadingThreads = true;
|
5003
5149
|
const threadId = e.detail.threadId;
|
@@ -5005,7 +5151,10 @@ class ShopGPT extends r$2 {
|
|
5005
5151
|
logger.error('ThreadId is missing to delete the thread!');
|
5006
5152
|
return;
|
5007
5153
|
}
|
5008
|
-
this.shopGPTAPI.sendEvent('singleThreadDelete'
|
5154
|
+
this.shopGPTAPI.sendEvent('singleThreadDelete', undefined, undefined, {
|
5155
|
+
thread: threadId,
|
5156
|
+
threadTitle: (_b = (_a = this.chatThreads.get(threadId)) === null || _a === void 0 ? void 0 : _a.title) !== null && _b !== void 0 ? _b : '',
|
5157
|
+
});
|
5009
5158
|
this.shopGPTAPI
|
5010
5159
|
.deleteSingleThread(threadId)
|
5011
5160
|
.then(this.loadChatThreads.bind(this))
|
@@ -5133,7 +5282,10 @@ class ShopGPT extends r$2 {
|
|
5133
5282
|
try {
|
5134
5283
|
this.isPreviousMessagePrompt = isPrompt;
|
5135
5284
|
if (!isPrompt) {
|
5136
|
-
this.shopGPTAPI.sendEvent('queryInteractions', this.getSiteCurrency().currency
|
5285
|
+
this.shopGPTAPI.sendEvent('queryInteractions', this.getSiteCurrency().currency, undefined, {
|
5286
|
+
query: message,
|
5287
|
+
threadId: this.selectedThreadId,
|
5288
|
+
});
|
5137
5289
|
}
|
5138
5290
|
this.messages = [{ sender: 'user', message }, ...this.messages];
|
5139
5291
|
this.isTyping = true;
|
@@ -5165,15 +5317,25 @@ class ShopGPT extends r$2 {
|
|
5165
5317
|
}
|
5166
5318
|
sendEvent(e) {
|
5167
5319
|
e.stopPropagation();
|
5168
|
-
this.shopGPTAPI.sendEvent(e.detail.action, this.getSiteCurrency().currency, e.detail.actionData);
|
5320
|
+
this.shopGPTAPI.sendEvent(e.detail.action, this.getSiteCurrency().currency, e.detail.actionData, e.detail.clickData);
|
5169
5321
|
}
|
5170
5322
|
productClicked(e) {
|
5323
|
+
var _a, _b;
|
5171
5324
|
e.stopPropagation();
|
5172
|
-
setProductAction(this.destination, this.sessionId, e.detail.
|
5325
|
+
setProductAction(this.destination, this.sessionId, e.detail.id, 'clicked', true);
|
5173
5326
|
this.shopGPTAPI.sendEvent('productRecommendationClicked', this.getSiteCurrency().currency, {
|
5174
|
-
productId: e.detail.
|
5327
|
+
productId: e.detail.id,
|
5175
5328
|
value: e.detail.value,
|
5176
5329
|
isPrompt: this.isPreviousMessagePrompt,
|
5330
|
+
}, {
|
5331
|
+
threadId: this.selectedThreadId,
|
5332
|
+
query: (_a = e.detail.query) !== null && _a !== void 0 ? _a : '',
|
5333
|
+
response: (_b = e.detail.response) !== null && _b !== void 0 ? _b : '',
|
5334
|
+
currency: this.getSiteCurrency().currency,
|
5335
|
+
variantId: e.detail.variantId,
|
5336
|
+
url: e.detail.url,
|
5337
|
+
title: e.detail.title,
|
5338
|
+
rank: e.detail.rank,
|
5177
5339
|
});
|
5178
5340
|
}
|
5179
5341
|
getSiteCurrency() {
|
@@ -5204,6 +5366,7 @@ class ShopGPT extends r$2 {
|
|
5204
5366
|
.css=${this.css}
|
5205
5367
|
></chat-threads>
|
5206
5368
|
<products-section
|
5369
|
+
.messages=${this.messages}
|
5207
5370
|
.merchantImage=${this.merchantImage}
|
5208
5371
|
.products=${this.products}
|
5209
5372
|
.isLoadingHistory=${this.isLoadingHistory}
|
@@ -5249,26 +5412,23 @@ class ShopGPT extends r$2 {
|
|
5249
5412
|
<button
|
5250
5413
|
@click=${(e) => {
|
5251
5414
|
e.preventDefault();
|
5252
|
-
this.
|
5253
|
-
this.modalState = 'open';
|
5254
|
-
this.handleUserInteraction();
|
5415
|
+
this.openModal();
|
5255
5416
|
}}
|
5256
5417
|
>
|
5257
5418
|
${chatIcon}
|
5258
5419
|
</button>
|
5259
5420
|
${((_a = this.nudge) === null || _a === void 0 ? void 0 : _a.show) && this.showNudge
|
5260
|
-
? x
|
5421
|
+
? x ` <div
|
5261
5422
|
class="nudge"
|
5262
5423
|
@click=${(e) => {
|
5263
5424
|
e.preventDefault();
|
5264
|
-
this.
|
5265
|
-
this.handleUserInteraction();
|
5425
|
+
this.openModal();
|
5266
5426
|
}}
|
5267
5427
|
>
|
5268
5428
|
Hi there! I'm an AI Agent to help you find the perfect product.
|
5269
5429
|
What are you looking for today?
|
5270
5430
|
</div>`
|
5271
|
-
: x
|
5431
|
+
: x ` <div class="chatbot-hover-text">
|
5272
5432
|
What are you looking for today?
|
5273
5433
|
</div>`}
|
5274
5434
|
</div>`;
|
@@ -5312,6 +5472,12 @@ class ShopGPT extends r$2 {
|
|
5312
5472
|
</div>
|
5313
5473
|
`;
|
5314
5474
|
}
|
5475
|
+
openModal() {
|
5476
|
+
setIsBotOpened(this.destination, this.sessionId, true);
|
5477
|
+
this.shopGPTAPI.sendEvent('chatbotOpened');
|
5478
|
+
this.modalState = 'open';
|
5479
|
+
this.handleUserInteraction();
|
5480
|
+
}
|
5315
5481
|
startNudgeTimer() {
|
5316
5482
|
var _a, _b;
|
5317
5483
|
if (this.view !== 'modal' || !((_a = this.nudge) === null || _a === void 0 ? void 0 : _a.show)) {
|
@@ -5459,14 +5625,13 @@ if (typeof window != 'undefined' && typeof document != 'undefined') {
|
|
5459
5625
|
logger.log('ShopGPT component added already!');
|
5460
5626
|
return;
|
5461
5627
|
}
|
5628
|
+
setWasUserExposed(shopGPT.destination, shopGPT.sessionId, true);
|
5462
5629
|
document.body.append(shopGPT);
|
5463
|
-
setShopGPTLoaded(shopGPT.destination, shopGPT.sessionId, true);
|
5464
5630
|
},
|
5465
5631
|
destroy() {
|
5466
5632
|
if (!shopGPT) {
|
5467
5633
|
return;
|
5468
5634
|
}
|
5469
|
-
setShopGPTLoaded(shopGPT.destination, shopGPT.sessionId, false);
|
5470
5635
|
shopGPT.remove();
|
5471
5636
|
shopGPT = undefined;
|
5472
5637
|
delete window[registryKey];
|