@envive-ai/react-hooks 0.3.9 → 0.3.11
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/dist/application/commerce-api.cjs +14 -14
- package/dist/application/commerce-api.d.cts +58 -0
- package/dist/application/commerce-api.d.ts +59 -0
- package/dist/application/commerce-api.js +3 -3
- package/dist/application/models/api/widgetText.d.cts +14 -0
- package/dist/application/models/api/widgetText.d.ts +14 -0
- package/dist/application/models/api/widgetTextRequest.d.cts +15 -0
- package/dist/application/models/api/widgetTextRequest.d.ts +15 -0
- package/dist/application/models/chatElementDisplayLocationV3.cjs +2 -1
- package/dist/application/models/chatElementDisplayLocationV3.d.cts +2 -1
- package/dist/application/models/chatElementDisplayLocationV3.d.ts +2 -1
- package/dist/application/models/chatElementDisplayLocationV3.js +2 -1
- package/dist/application/models/guards/api/index.cjs +4 -4
- package/dist/application/models/guards/api/index.js +4 -4
- package/dist/application/models/guards/api/isApiFormResponse.cjs +1 -1
- package/dist/application/models/guards/api/isApiFormResponse.js +1 -1
- package/dist/application/models/guards/api/isApiFormSubmittedResponseAttributes.cjs +1 -1
- package/dist/application/models/guards/api/isApiFormSubmittedResponseAttributes.js +1 -1
- package/dist/application/models/guards/api/isApiOrderResponseAttributes.cjs +1 -1
- package/dist/application/models/guards/api/isApiOrderResponseAttributes.js +1 -1
- package/dist/application/models/guards/api/isApiProductResponseAttributes.cjs +1 -1
- package/dist/application/models/guards/api/isApiProductResponseAttributes.js +1 -1
- package/dist/application/models/guards/api/isApiResponse.cjs +1 -1
- package/dist/application/models/guards/api/isApiResponse.js +1 -1
- package/dist/application/models/index.cjs +12 -12
- package/dist/application/models/index.d.cts +25 -25
- package/dist/application/models/index.d.ts +25 -25
- package/dist/application/models/index.js +12 -12
- package/dist/application/models/validators/validateGraphQLFrontendConfig.cjs +1 -1
- package/dist/application/models/validators/validateGraphQLFrontendConfig.js +1 -1
- package/dist/application/models/validators/validateUserEvent.cjs +2 -2
- package/dist/application/models/validators/validateUserEvent.js +2 -2
- package/dist/application/models/variantInfo/variantInfo.cjs +2 -1
- package/dist/application/models/variantInfo/variantInfo.d.cts +6 -1
- package/dist/application/models/variantInfo/variantInfo.d.ts +6 -1
- package/dist/application/models/variantInfo/variantInfo.js +2 -1
- package/dist/application/utils/analyticsUtils.cjs +1 -1
- package/dist/application/utils/analyticsUtils.js +1 -1
- package/dist/application/utils/widgetTextFromApiWidgetTextResponse.cjs +3 -1
- package/dist/application/utils/widgetTextFromApiWidgetTextResponse.js +3 -1
- package/dist/application/utils/widgetTextRequestToApiRequest.cjs +3 -1
- package/dist/application/utils/widgetTextRequestToApiRequest.js +3 -1
- package/dist/atoms/app/index.cjs +7 -7
- package/dist/atoms/app/index.d.cts +8 -8
- package/dist/atoms/app/index.d.ts +8 -8
- package/dist/atoms/app/index.js +1 -1
- package/dist/atoms/app/variant.cjs +44 -4
- package/dist/atoms/app/variant.d.cts +8 -8
- package/dist/atoms/app/variant.d.ts +8 -8
- package/dist/atoms/app/variant.js +44 -5
- package/dist/atoms/chat/chatState.d.cts +17 -17
- package/dist/atoms/chat/chatState.d.ts +18 -18
- package/dist/atoms/chat/form.cjs +1 -1
- package/dist/atoms/chat/form.d.cts +2 -2
- package/dist/atoms/chat/form.d.ts +2 -2
- package/dist/atoms/chat/form.js +1 -1
- package/dist/atoms/chat/index.cjs +1 -1
- package/dist/atoms/chat/index.d.cts +2 -2
- package/dist/atoms/chat/index.d.ts +2 -2
- package/dist/atoms/chat/index.js +1 -1
- package/dist/atoms/chat/lastMessage.d.cts +2 -2
- package/dist/atoms/chat/lastMessage.d.ts +2 -2
- package/dist/atoms/chat/messageQueue.d.cts +6 -6
- package/dist/atoms/chat/messageQueue.d.ts +6 -6
- package/dist/atoms/chat/performanceMetrics.d.cts +6 -6
- package/dist/atoms/chat/performanceMetrics.d.ts +6 -6
- package/dist/atoms/chat/renderedWidgetRefs.d.cts +2 -2
- package/dist/atoms/chat/renderedWidgetRefs.d.ts +2 -2
- package/dist/atoms/chat/replies.d.cts +3 -3
- package/dist/atoms/chat/replies.d.ts +3 -3
- package/dist/atoms/chat/suggestions.d.cts +2 -2
- package/dist/atoms/chat/suggestions.d.ts +2 -2
- package/dist/atoms/envive/enviveConfig.d.cts +19 -0
- package/dist/atoms/envive/enviveConfig.d.ts +19 -0
- package/dist/atoms/globalSearch/globalSearch.d.cts +5 -5
- package/dist/atoms/globalSearch/globalSearch.d.ts +5 -5
- package/dist/atoms/org/customerService.d.cts +6 -6
- package/dist/atoms/org/customerService.d.ts +6 -6
- package/dist/atoms/org/graphqlConfig.d.cts +4 -4
- package/dist/atoms/org/graphqlConfig.d.ts +4 -4
- package/dist/atoms/org/index.cjs +1 -1
- package/dist/atoms/org/index.js +1 -1
- package/dist/atoms/org/newOrgConfigAtom.d.cts +2 -2
- package/dist/atoms/org/newOrgConfigAtom.d.ts +2 -2
- package/dist/atoms/org/orgAnalyticsConfig.d.cts +5 -5
- package/dist/atoms/org/orgAnalyticsConfig.d.ts +5 -5
- package/dist/atoms/search/chatSearch.cjs +2 -2
- package/dist/atoms/search/chatSearch.d.cts +17 -17
- package/dist/atoms/search/chatSearch.d.ts +17 -17
- package/dist/atoms/search/chatSearch.js +2 -2
- package/dist/atoms/search/searchAPI.cjs +1 -1
- package/dist/atoms/search/searchAPI.d.cts +13 -13
- package/dist/atoms/search/searchAPI.d.ts +13 -13
- package/dist/atoms/search/searchAPI.js +1 -1
- package/dist/atoms/widget/chatPreviewLoading.d.cts +2 -2
- package/dist/atoms/widget/chatPreviewLoading.d.ts +2 -2
- package/dist/contexts/amplitudeContext/amplitudeContext.cjs +10 -7
- package/dist/contexts/amplitudeContext/amplitudeContext.d.cts +2 -2
- package/dist/contexts/amplitudeContext/amplitudeContext.d.ts +2 -2
- package/dist/contexts/amplitudeContext/amplitudeContext.js +6 -3
- package/dist/contexts/amplitudeContext/index.cjs +1 -0
- package/dist/contexts/amplitudeContext/index.d.cts +2 -2
- package/dist/contexts/amplitudeContext/index.d.ts +2 -2
- package/dist/contexts/amplitudeContext/index.js +2 -2
- package/dist/contexts/cdnContext/cdnContext.cjs +3 -3
- package/dist/contexts/enviveConfigContext/enviveConfigContext.cjs +6 -5
- package/dist/contexts/enviveConfigContext/enviveConfigContext.d.cts +2 -1
- package/dist/contexts/enviveConfigContext/enviveConfigContext.d.ts +2 -1
- package/dist/contexts/enviveConfigContext/enviveConfigContext.js +3 -2
- package/dist/contexts/enviveContext/WindowChatToggleBinder.cjs +4 -3
- package/dist/contexts/enviveContext/WindowChatToggleBinder.js +4 -3
- package/dist/contexts/enviveContext/enviveContext.cjs +15 -11
- package/dist/contexts/enviveContext/enviveContext.d.cts +2 -1
- package/dist/contexts/enviveContext/enviveContext.d.ts +2 -1
- package/dist/contexts/enviveContext/enviveContext.js +15 -11
- package/dist/contexts/enviveContext/types.d.cts +1 -1
- package/dist/contexts/enviveContext/types.d.ts +1 -1
- package/dist/contexts/featureFlagServiceContext/featureFlagServiceContext.cjs +23 -2
- package/dist/contexts/featureFlagServiceContext/featureFlagServiceContext.d.cts +11 -2
- package/dist/contexts/featureFlagServiceContext/featureFlagServiceContext.d.ts +11 -2
- package/dist/contexts/featureFlagServiceContext/featureFlagServiceContext.js +23 -2
- package/dist/contexts/featureFlagServiceContext/index.d.cts +2 -2
- package/dist/contexts/featureFlagServiceContext/index.d.ts +2 -2
- package/dist/contexts/graphqlContext/graphqlContext.cjs +7 -7
- package/dist/contexts/graphqlContext/graphqlContext.d.cts +1 -1
- package/dist/contexts/graphqlContext/graphqlContext.d.ts +1 -1
- package/dist/contexts/graphqlContext/graphqlContext.js +3 -3
- package/dist/contexts/graphqlContext/mockV3Config.cjs +10 -4
- package/dist/contexts/graphqlContext/mockV3Config.js +10 -4
- package/dist/contexts/hardcopyContext/hardcopyContext.cjs +50 -5
- package/dist/contexts/hardcopyContext/hardcopyContext.d.cts +4 -1
- package/dist/contexts/hardcopyContext/hardcopyContext.d.ts +4 -1
- package/dist/contexts/hardcopyContext/hardcopyContext.js +48 -3
- package/dist/contexts/newOrgConfigContext/newOrgConfigContext.cjs +4 -4
- package/dist/contexts/newOrgConfigContext/newOrgConfigContext.js +1 -1
- package/dist/contexts/pageContext/mapping.cjs +6 -2
- package/dist/contexts/pageContext/mapping.js +6 -2
- package/dist/contexts/pageContext/pageContext.cjs +4 -3
- package/dist/contexts/pageContext/pageContext.js +2 -1
- package/dist/contexts/pageContext/types.d.cts +7 -3
- package/dist/contexts/pageContext/types.d.ts +7 -3
- package/dist/contexts/salesAgentContext/chatAPI.cjs +103 -13
- package/dist/contexts/salesAgentContext/chatAPI.d.cts +8 -4
- package/dist/contexts/salesAgentContext/chatAPI.d.ts +8 -4
- package/dist/contexts/salesAgentContext/chatAPI.js +105 -15
- package/dist/contexts/salesAgentContext/salesAgentContext.cjs +1 -1
- package/dist/contexts/salesAgentContext/salesAgentContext.js +1 -1
- package/dist/contexts/salesAgentContext/salesAgentService.cjs +53 -11
- package/dist/contexts/salesAgentContext/salesAgentService.js +51 -9
- package/dist/contexts/searchContext/searchContext.cjs +4 -4
- package/dist/contexts/searchContext/searchContext.js +1 -1
- package/dist/contexts/systemSettingsContext/systemSettingsContext.cjs +3 -3
- package/dist/contexts/systemSettingsContext/systemSettingsContext.d.cts +2 -2
- package/dist/contexts/systemSettingsContext/systemSettingsContext.d.ts +2 -2
- package/dist/contexts/types.cjs +1 -1
- package/dist/contexts/types.d.cts +7 -2
- package/dist/contexts/types.d.ts +7 -2
- package/dist/contexts/types.js +1 -1
- package/dist/contexts/typesV3.cjs +2 -1
- package/dist/contexts/typesV3.d.cts +12 -7
- package/dist/contexts/typesV3.d.ts +10 -5
- package/dist/contexts/typesV3.js +2 -1
- package/dist/contexts/userIdentityContext/userIdentityContext.cjs +3 -3
- package/dist/contexts/widgetConfigContext/widgetConfigContext.cjs +1 -1
- package/dist/contexts/widgetConfigContext/widgetConfigContext.js +1 -1
- package/dist/hooks/AppDetails/useAppDetails.cjs +6 -6
- package/dist/hooks/GrabAndScroll/useGrabAndScroll.d.cts +2 -2
- package/dist/hooks/GrabAndScroll/useGrabAndScroll.d.ts +2 -2
- package/dist/hooks/ImageResolver/useImageResolver.cjs +3 -3
- package/dist/hooks/Search/useSearch.cjs +6 -6
- package/dist/hooks/Search/useSearch.d.cts +1 -1
- package/dist/hooks/Search/useSearch.d.ts +1 -1
- package/dist/hooks/Search/useSearch.js +3 -3
- package/dist/hooks/Search/useSearchInput.cjs +2 -2
- package/dist/hooks/Search/useSearchInput.js +2 -2
- package/dist/services/amplitudeService/amplitudeService.cjs +49 -11
- package/dist/services/amplitudeService/amplitudeService.d.cts +18 -3
- package/dist/services/amplitudeService/amplitudeService.d.ts +18 -3
- package/dist/services/amplitudeService/amplitudeService.js +49 -12
- package/dist/services/amplitudeService/index.cjs +1 -0
- package/dist/services/amplitudeService/index.d.cts +2 -2
- package/dist/services/amplitudeService/index.d.ts +2 -2
- package/dist/services/amplitudeService/index.js +2 -2
- package/dist/types/customerService.d.cts +3 -1
- package/dist/types/customerService.d.ts +1 -1
- package/package.json +10 -2
- package/src/application/models/api/widgetText.ts +2 -0
- package/src/application/models/api/widgetTextRequest.ts +1 -0
- package/src/application/models/chatElementDisplayLocationV3.ts +1 -0
- package/src/application/models/variantInfo/variantInfo.ts +5 -0
- package/src/application/utils/widgetTextFromApiWidgetTextResponse.ts +2 -0
- package/src/application/utils/widgetTextRequestToApiRequest.ts +4 -0
- package/src/atoms/app/variant.ts +56 -2
- package/src/contexts/amplitudeContext/__tests__/amplitudeContext.test.tsx +2 -0
- package/src/contexts/amplitudeContext/amplitudeContext.tsx +6 -1
- package/src/contexts/enviveConfigContext/enviveConfigContext.tsx +3 -0
- package/src/contexts/enviveContext/WindowChatToggleBinder.tsx +5 -1
- package/src/contexts/enviveContext/enviveContext.tsx +5 -1
- package/src/contexts/featureFlagServiceContext/featureFlagServiceContext.tsx +36 -0
- package/src/contexts/graphqlContext/mockV3Config.ts +13 -7
- package/src/contexts/hardcopyContext/hardcopyContext.tsx +48 -3
- package/src/contexts/pageContext/mapping.ts +13 -1
- package/src/contexts/pageContext/pageContext.tsx +1 -0
- package/src/contexts/pageContext/types.ts +7 -1
- package/src/contexts/salesAgentContext/chatAPI.ts +106 -13
- package/src/contexts/salesAgentContext/salesAgentService.ts +66 -4
- package/src/contexts/types.ts +8 -1
- package/src/contexts/typesV3.ts +24 -16
- package/src/services/amplitudeService/__tests__/amplitudeService.test.ts +80 -0
- package/src/services/amplitudeService/amplitudeService.ts +55 -11
|
@@ -25,6 +25,8 @@ import { useMessageInterceptor } from 'src/interceptors/useMessageInterceptor';
|
|
|
25
25
|
import { SpiffyMetricsEventName, useAmplitude } from 'src/contexts/amplitudeContext';
|
|
26
26
|
import { useFeatureFlagService } from 'src/contexts/featureFlagServiceContext';
|
|
27
27
|
import { UserEventCategory } from '@spiffy-ai/commerce-api-client';
|
|
28
|
+
import { EnviveMetricsEventName } from 'src/services/amplitudeService/amplitudeService';
|
|
29
|
+
import { analyticsContextAtom } from 'src/atoms/app/variant';
|
|
28
30
|
|
|
29
31
|
import { StatusCodeError } from './statusCodeError';
|
|
30
32
|
|
|
@@ -59,6 +61,41 @@ const inputPropsToTrackingProps = (
|
|
|
59
61
|
return {};
|
|
60
62
|
};
|
|
61
63
|
|
|
64
|
+
const inputPropsToEnviveTrackingProps = (
|
|
65
|
+
payload: NextMessageRequest,
|
|
66
|
+
): Record<string, unknown> | undefined => {
|
|
67
|
+
const [userEvent] = payload.userEvents || [];
|
|
68
|
+
if (userEvent.category === UserEventCategory.SuggestionClicked) {
|
|
69
|
+
return {
|
|
70
|
+
'chat.request_type': 'suggestion',
|
|
71
|
+
'chat.request_id': userEvent.eventId,
|
|
72
|
+
'chat.request_text': userEvent.attributes.content,
|
|
73
|
+
'chat.suggestion_id': userEvent.attributes.suggestionId,
|
|
74
|
+
'chat.user_typed': false,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
if (userEvent.category === UserEventCategory.QueryTyped) {
|
|
78
|
+
return {
|
|
79
|
+
'chat.request_type': 'text',
|
|
80
|
+
'chat.request_id': userEvent.eventId,
|
|
81
|
+
'chat.request_text': userEvent.attributes.query,
|
|
82
|
+
'chat.user_typed': userEvent.attributes.userTyped,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (
|
|
86
|
+
userEvent.category === UserEventCategory.PageVisit ||
|
|
87
|
+
userEvent.category === UserEventCategory.PdpVisit ||
|
|
88
|
+
userEvent.category === UserEventCategory.PlpVisit
|
|
89
|
+
) {
|
|
90
|
+
return {
|
|
91
|
+
'chat.request_id': userEvent.eventId,
|
|
92
|
+
'chat.request_type': 'page_visit',
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return {};
|
|
97
|
+
};
|
|
98
|
+
|
|
62
99
|
export const getQueryParam = (key: string): string | null => {
|
|
63
100
|
const urlObj = new URL(window.location.href);
|
|
64
101
|
return urlObj.searchParams.get(key);
|
|
@@ -137,14 +174,15 @@ const processStreamingResponse = async (
|
|
|
137
174
|
messageInterceptor: { intercept: (response?: Response) => boolean | undefined },
|
|
138
175
|
setMessages: (updater: (prev: Message[][]) => Message[][]) => void,
|
|
139
176
|
setResponseStreaming: (responseStreaming: boolean) => void,
|
|
140
|
-
): Promise<
|
|
177
|
+
): Promise<Record<string, number>> => {
|
|
141
178
|
let lastMessage: Message | undefined;
|
|
142
179
|
setResponseStreaming(true);
|
|
180
|
+
const responseAnalytics: Record<string, number> = {};
|
|
143
181
|
|
|
144
182
|
for await (const response of stream) {
|
|
145
183
|
try {
|
|
146
184
|
if (messageInterceptor.intercept(response)) {
|
|
147
|
-
return;
|
|
185
|
+
return {};
|
|
148
186
|
}
|
|
149
187
|
|
|
150
188
|
if (!response) {
|
|
@@ -155,6 +193,14 @@ const processStreamingResponse = async (
|
|
|
155
193
|
if (!message) {
|
|
156
194
|
throw new Error('Failed to transform API response to client message');
|
|
157
195
|
}
|
|
196
|
+
if (message.type === MessageType.Product) {
|
|
197
|
+
responseAnalytics['chat.product_cards_returned'] =
|
|
198
|
+
(responseAnalytics['chat.product_cards_returned'] || 0) + 1;
|
|
199
|
+
}
|
|
200
|
+
if (message.type === MessageType.Review) {
|
|
201
|
+
responseAnalytics['chat.review_cards_returned'] =
|
|
202
|
+
(responseAnalytics['chat.review_cards_returned'] || 0) + 1;
|
|
203
|
+
}
|
|
158
204
|
|
|
159
205
|
// No support for ChatSearch messages at the current time.
|
|
160
206
|
// Perhaps we add support back in the future
|
|
@@ -173,6 +219,7 @@ const processStreamingResponse = async (
|
|
|
173
219
|
}
|
|
174
220
|
setResponseStreaming(false);
|
|
175
221
|
}
|
|
222
|
+
return responseAnalytics;
|
|
176
223
|
};
|
|
177
224
|
|
|
178
225
|
export const useSalesAgentService: () => SalesAgentService = () => {
|
|
@@ -181,6 +228,7 @@ export const useSalesAgentService: () => SalesAgentService = () => {
|
|
|
181
228
|
const setSuggestions = useSetAtom(suggestionsAtom);
|
|
182
229
|
const setPendingResponse = useSetAtom(pendingResponseAtom);
|
|
183
230
|
const setResponseStreaming = useSetAtom(responseStreamingAtom);
|
|
231
|
+
const analyticsContext = useAtomValue(analyticsContextAtom);
|
|
184
232
|
const messageInterceptor = useMessageInterceptor();
|
|
185
233
|
const { trackEvent } = useAmplitude();
|
|
186
234
|
|
|
@@ -220,12 +268,13 @@ export const useSalesAgentService: () => SalesAgentService = () => {
|
|
|
220
268
|
const startTime = Date.now();
|
|
221
269
|
let successfulResponse: boolean | undefined;
|
|
222
270
|
setPendingResponse(true);
|
|
271
|
+
setSuggestions([]);
|
|
223
272
|
const stream = CommerceApiClient.getNextResponseStreaming(payload);
|
|
224
|
-
|
|
273
|
+
let responseAnalytics: Record<string, unknown> | undefined;
|
|
225
274
|
try {
|
|
226
275
|
setRequestFailure(false);
|
|
227
276
|
|
|
228
|
-
await processStreamingResponse(
|
|
277
|
+
responseAnalytics = await processStreamingResponse(
|
|
229
278
|
stream,
|
|
230
279
|
messageInterceptor,
|
|
231
280
|
setMessages,
|
|
@@ -274,14 +323,27 @@ export const useSalesAgentService: () => SalesAgentService = () => {
|
|
|
274
323
|
...inputPropsToTrackingProps(payload),
|
|
275
324
|
},
|
|
276
325
|
});
|
|
326
|
+
trackEvent({
|
|
327
|
+
eventName: EnviveMetricsEventName.ChatResponse,
|
|
328
|
+
eventProps: {
|
|
329
|
+
...analyticsContext,
|
|
330
|
+
'chat.response_time_ms': responseTime.toString(),
|
|
331
|
+
...inputPropsToEnviveTrackingProps(payload),
|
|
332
|
+
...responseAnalytics,
|
|
333
|
+
},
|
|
334
|
+
});
|
|
277
335
|
setPendingResponse(false);
|
|
278
336
|
setResponseStreaming(false);
|
|
279
337
|
// logPerfMetric(PerfMetricsEvents.FirstResponseCompleted);
|
|
280
338
|
}
|
|
281
339
|
},
|
|
282
340
|
[
|
|
341
|
+
analyticsContext,
|
|
342
|
+
trackEvent,
|
|
343
|
+
setResponseStreaming,
|
|
283
344
|
// logPerfMetric,
|
|
284
345
|
setRequestFailure,
|
|
346
|
+
setSuggestions,
|
|
285
347
|
messageInterceptor,
|
|
286
348
|
setMessages,
|
|
287
349
|
setPendingResponse,
|
package/src/contexts/types.ts
CHANGED
|
@@ -863,6 +863,7 @@ type PageVariantBase = {
|
|
|
863
863
|
variantId: string;
|
|
864
864
|
widgetMounting: WidgetMounting[];
|
|
865
865
|
variantTests: PageVariantTest[];
|
|
866
|
+
floatingButtonOverride?: ShowFloatingButtonOptions;
|
|
866
867
|
};
|
|
867
868
|
|
|
868
869
|
type PLPPageVariant = PageVariantBase & {
|
|
@@ -892,13 +893,18 @@ type SearchPageVariant = PageVariantBase & {
|
|
|
892
893
|
variantType: 'search';
|
|
893
894
|
};
|
|
894
895
|
|
|
896
|
+
type FullPageSalesAgentVariant = PageVariantBase & {
|
|
897
|
+
variantType: 'full_page';
|
|
898
|
+
};
|
|
899
|
+
|
|
895
900
|
export type PageVariantConfig =
|
|
896
901
|
| PLPPageVariant
|
|
897
902
|
| PDPPageVariant
|
|
898
903
|
| VisitPageVariant
|
|
899
904
|
| OtherPageVariant
|
|
900
905
|
| HomePageVariant
|
|
901
|
-
| SearchPageVariant
|
|
906
|
+
| SearchPageVariant
|
|
907
|
+
| FullPageSalesAgentVariant;
|
|
902
908
|
|
|
903
909
|
export type OrgPageConfig = {
|
|
904
910
|
// pageVariants is a list of page variants that we support.
|
|
@@ -928,6 +934,7 @@ export interface EnviveConfig {
|
|
|
928
934
|
variantUrlOverride?: string;
|
|
929
935
|
variantInfoOverride?: any;
|
|
930
936
|
show?: boolean;
|
|
937
|
+
enviveOn?: boolean;
|
|
931
938
|
publicKey?: string;
|
|
932
939
|
featureGates?: OrgConfigFeatureGate[];
|
|
933
940
|
}
|
package/src/contexts/typesV3.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FloatingButtonLocation } from '@envive-ai/react-toolkit-v3/FloatingButton';
|
|
2
2
|
import { ImageGalleryImage, ImageGalleryLayout } from '@envive-ai/react-toolkit-v3/ImageGallery';
|
|
3
3
|
import { PromptButtonVariant } from '@envive-ai/react-toolkit-v3/PromptButton';
|
|
4
|
-
import {
|
|
5
|
-
import { Theme } from '@envive-ai/react-toolkit-v3/Tokens';
|
|
4
|
+
import { AnimationSpeed, PromptCarouselRows } from '@envive-ai/react-toolkit-v3/PromptCarousel';
|
|
6
5
|
import { DynamicLayout, WidgetKind } from '@envive-ai/react-toolkit-v3/SocialProof';
|
|
6
|
+
import { Theme } from '@envive-ai/react-toolkit-v3/Tokens';
|
|
7
7
|
import { SparkleIconColor } from '@envive-ai/react-toolkit-v3/WelcomeMessage';
|
|
8
|
-
import {
|
|
8
|
+
import { WidgetWrapperVariant } from '@envive-ai/react-toolkit-v3/WidgetWrapper';
|
|
9
9
|
import { ColorNames } from '../application/models/colorsConfigV3';
|
|
10
10
|
import { CustomerServiceType } from '../types/customerService';
|
|
11
11
|
import type { SearchConfig } from './types';
|
|
@@ -246,6 +246,7 @@ export enum WidgetTypeV3 {
|
|
|
246
246
|
FloatingChatV3 = 'FloatingChatV3',
|
|
247
247
|
FloatingButtonV3 = 'FloatingButtonV3',
|
|
248
248
|
ProductCardV3 = 'ProductCardV3',
|
|
249
|
+
FullPageSalesAgentV3 = 'FullPageSalesAgentV3',
|
|
249
250
|
}
|
|
250
251
|
|
|
251
252
|
interface BaseWidgetConfig<T extends WidgetTypeV3> {
|
|
@@ -324,6 +325,11 @@ interface ProductCardWidgetV3Config extends BaseWidgetConfig<WidgetTypeV3.Produc
|
|
|
324
325
|
imageSrc?: string;
|
|
325
326
|
}
|
|
326
327
|
|
|
328
|
+
interface FullPageSalesAgentWidgetV3Config extends BaseWidgetConfig<WidgetTypeV3.FullPageSalesAgentV3> {
|
|
329
|
+
headerContainer?: string;
|
|
330
|
+
autoHeight?: boolean;
|
|
331
|
+
}
|
|
332
|
+
|
|
327
333
|
type WidgetConfigV3 =
|
|
328
334
|
| PromptCarouselWidgetV3Config
|
|
329
335
|
| SocialProofWidgetV3Config
|
|
@@ -334,24 +340,26 @@ type WidgetConfigV3 =
|
|
|
334
340
|
| ChatPreviewWidgetV3Config
|
|
335
341
|
| PromptButtonCarouselWithImageWidgetV3Config
|
|
336
342
|
| FloatingChatWidgetV3Config
|
|
337
|
-
| ProductCardWidgetV3Config
|
|
343
|
+
| ProductCardWidgetV3Config
|
|
344
|
+
| FullPageSalesAgentWidgetV3Config;
|
|
338
345
|
|
|
339
346
|
export type {
|
|
340
|
-
OrgUIConfigV3,
|
|
341
|
-
WidgetConfigV3,
|
|
342
|
-
LookAndFeelConfig,
|
|
343
|
-
SocialProofWidgetV3Config,
|
|
344
|
-
PromptCarouselWidgetV3Config,
|
|
345
347
|
ChatPreviewComparisonWidgetV3Config,
|
|
346
348
|
ChatPreviewLoadingWidgetV3Config,
|
|
347
349
|
ChatPreviewWidgetV3Config,
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
350
|
+
CustomerServiceIntegration,
|
|
351
|
+
FloatingButtonConfig,
|
|
352
|
+
FloatingChatConfig,
|
|
351
353
|
FloatingChatWidgetV3Config,
|
|
354
|
+
FullPageSalesAgentWidgetV3Config,
|
|
355
|
+
LookAndFeelConfig,
|
|
356
|
+
OrgUIConfigV3,
|
|
352
357
|
ProductCardWidgetV3Config,
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
358
|
+
PromptButtonCarouselWithImageWidgetV3Config,
|
|
359
|
+
PromptCarouselWidgetV3Config,
|
|
360
|
+
SocialProofWidgetV3Config,
|
|
356
361
|
SPASettings,
|
|
362
|
+
TitledPromptCarouselWidgetV3Config,
|
|
363
|
+
TypingAnimationWidgetV3Config,
|
|
364
|
+
WidgetConfigV3,
|
|
357
365
|
};
|
|
@@ -66,6 +66,23 @@ describe('AmplitudeService', () => {
|
|
|
66
66
|
mockAdd.mockClear();
|
|
67
67
|
mockDigest.mockResolvedValue(new Uint8Array(32).fill(0));
|
|
68
68
|
mockDispatch.mockClear();
|
|
69
|
+
|
|
70
|
+
// Mock window.location for tests that need it
|
|
71
|
+
Object.defineProperty(global, 'window', {
|
|
72
|
+
value: {
|
|
73
|
+
location: {
|
|
74
|
+
href: 'https://test.example.com',
|
|
75
|
+
},
|
|
76
|
+
localStorage: {
|
|
77
|
+
getItem: vi.fn(),
|
|
78
|
+
},
|
|
79
|
+
performance: {
|
|
80
|
+
now: vi.fn(() => Date.now()),
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
writable: true,
|
|
84
|
+
configurable: true,
|
|
85
|
+
});
|
|
69
86
|
});
|
|
70
87
|
|
|
71
88
|
const createService = (overrides?: Partial<AmplitudeServiceConfig>) => {
|
|
@@ -76,6 +93,7 @@ describe('AmplitudeService', () => {
|
|
|
76
93
|
env: 'test',
|
|
77
94
|
orgId: 'test-org-id',
|
|
78
95
|
show: true,
|
|
96
|
+
enviveOn: true,
|
|
79
97
|
contextSource: 'app',
|
|
80
98
|
orgShortName: 'test-org',
|
|
81
99
|
featureFlagService,
|
|
@@ -108,6 +126,7 @@ describe('AmplitudeService', () => {
|
|
|
108
126
|
env: 'test',
|
|
109
127
|
orgId: 'test-org-id',
|
|
110
128
|
show: true,
|
|
129
|
+
enviveOn: true,
|
|
111
130
|
getLocalStorageItem: mockGetLocalStorageItem,
|
|
112
131
|
contextSource: 'app',
|
|
113
132
|
orgShortName: 'test-org',
|
|
@@ -125,6 +144,7 @@ describe('AmplitudeService', () => {
|
|
|
125
144
|
env: 'test',
|
|
126
145
|
orgId: 'test-org-id',
|
|
127
146
|
show: true,
|
|
147
|
+
enviveOn: true,
|
|
128
148
|
getLocalStorageItem: mockGetLocalStorageItem,
|
|
129
149
|
contextSource: 'app',
|
|
130
150
|
orgShortName: 'test-org',
|
|
@@ -142,6 +162,7 @@ describe('AmplitudeService', () => {
|
|
|
142
162
|
env: 'test',
|
|
143
163
|
orgId: 'test-org-id',
|
|
144
164
|
show: true,
|
|
165
|
+
enviveOn: true,
|
|
145
166
|
getLocalStorageItem: mockGetLocalStorageItem,
|
|
146
167
|
contextSource: 'app',
|
|
147
168
|
orgShortName: 'test-org',
|
|
@@ -209,6 +230,7 @@ describe('AmplitudeService', () => {
|
|
|
209
230
|
eventProps: { message: 'test', count: 5 },
|
|
210
231
|
});
|
|
211
232
|
|
|
233
|
+
expect(mockTrack).toHaveBeenCalled();
|
|
212
234
|
const callArgs = mockTrack.mock.calls[0];
|
|
213
235
|
const eventProps = callArgs[1];
|
|
214
236
|
|
|
@@ -238,6 +260,7 @@ describe('AmplitudeService', () => {
|
|
|
238
260
|
eventGroups: { group1: 'value1', group2: 'value2' },
|
|
239
261
|
});
|
|
240
262
|
|
|
263
|
+
expect(mockTrack).toHaveBeenCalled();
|
|
241
264
|
const callArgs = mockTrack.mock.calls[0];
|
|
242
265
|
expect(callArgs[2]).toHaveProperty('group1', 'value1');
|
|
243
266
|
expect(callArgs[2]).toHaveProperty('group2', 'value2');
|
|
@@ -251,6 +274,7 @@ describe('AmplitudeService', () => {
|
|
|
251
274
|
env: 'test',
|
|
252
275
|
orgId: 'test-org-id',
|
|
253
276
|
show: true,
|
|
277
|
+
enviveOn: true,
|
|
254
278
|
getLocalStorageItem: mockGetLocalStorageItem,
|
|
255
279
|
contextSource: 'app',
|
|
256
280
|
orgShortName: 'test-org',
|
|
@@ -304,6 +328,15 @@ describe('AmplitudeService', () => {
|
|
|
304
328
|
const dataLayer: any[] = [];
|
|
305
329
|
Object.defineProperty(global, 'window', {
|
|
306
330
|
value: {
|
|
331
|
+
location: {
|
|
332
|
+
href: 'https://test.example.com',
|
|
333
|
+
},
|
|
334
|
+
localStorage: {
|
|
335
|
+
getItem: vi.fn(),
|
|
336
|
+
},
|
|
337
|
+
performance: {
|
|
338
|
+
now: vi.fn(() => Date.now()),
|
|
339
|
+
},
|
|
307
340
|
dataLayer,
|
|
308
341
|
},
|
|
309
342
|
writable: true,
|
|
@@ -391,6 +424,7 @@ describe('AmplitudeService', () => {
|
|
|
391
424
|
env: 'test',
|
|
392
425
|
orgId: 'test-org-id',
|
|
393
426
|
show: true,
|
|
427
|
+
enviveOn: true,
|
|
394
428
|
getLocalStorageItem: null,
|
|
395
429
|
contextSource: 'app',
|
|
396
430
|
orgShortName: 'test-org',
|
|
@@ -408,7 +442,13 @@ describe('AmplitudeService', () => {
|
|
|
408
442
|
};
|
|
409
443
|
Object.defineProperty(global, 'window', {
|
|
410
444
|
value: {
|
|
445
|
+
location: {
|
|
446
|
+
href: 'https://test.example.com',
|
|
447
|
+
},
|
|
411
448
|
localStorage: mockLocalStorage,
|
|
449
|
+
performance: {
|
|
450
|
+
now: vi.fn(() => Date.now()),
|
|
451
|
+
},
|
|
412
452
|
},
|
|
413
453
|
writable: true,
|
|
414
454
|
configurable: true,
|
|
@@ -418,7 +458,9 @@ describe('AmplitudeService', () => {
|
|
|
418
458
|
eventName: SpiffyMetricsEventName.ChatUserMessageInput,
|
|
419
459
|
});
|
|
420
460
|
|
|
461
|
+
// Check that getItem was called with ChatId (may be called with other keys too)
|
|
421
462
|
expect(mockLocalStorage.getItem).toHaveBeenCalledWith(LocalStorageKeys.ChatId);
|
|
463
|
+
expect(mockTrack).toHaveBeenCalled();
|
|
422
464
|
const callArgs = mockTrack.mock.calls[0];
|
|
423
465
|
expect(callArgs[1]).toHaveProperty('chat_id', 'window-chat-id');
|
|
424
466
|
});
|
|
@@ -448,6 +490,7 @@ describe('AmplitudeService', () => {
|
|
|
448
490
|
eventName: SpiffyMetricsEventName.ChatUserMessageInput,
|
|
449
491
|
});
|
|
450
492
|
|
|
493
|
+
expect(mockTrack).toHaveBeenCalled();
|
|
451
494
|
const callArgs = mockTrack.mock.calls[0];
|
|
452
495
|
const eventProps = callArgs[1];
|
|
453
496
|
expect(eventProps).toHaveProperty('test', 'value');
|
|
@@ -456,6 +499,23 @@ describe('AmplitudeService', () => {
|
|
|
456
499
|
|
|
457
500
|
describe('Event enrichment', () => {
|
|
458
501
|
it('should enrich Page Viewed events', async () => {
|
|
502
|
+
// Ensure window.location is properly mocked
|
|
503
|
+
Object.defineProperty(global, 'window', {
|
|
504
|
+
value: {
|
|
505
|
+
location: {
|
|
506
|
+
href: 'https://test.example.com',
|
|
507
|
+
},
|
|
508
|
+
localStorage: {
|
|
509
|
+
getItem: vi.fn(),
|
|
510
|
+
},
|
|
511
|
+
performance: {
|
|
512
|
+
now: vi.fn(() => Date.now()),
|
|
513
|
+
},
|
|
514
|
+
},
|
|
515
|
+
writable: true,
|
|
516
|
+
configurable: true,
|
|
517
|
+
});
|
|
518
|
+
|
|
459
519
|
createService({
|
|
460
520
|
show: true,
|
|
461
521
|
});
|
|
@@ -487,6 +547,23 @@ describe('AmplitudeService', () => {
|
|
|
487
547
|
});
|
|
488
548
|
|
|
489
549
|
it('should enrich Bundle Loaded events', async () => {
|
|
550
|
+
// Ensure window.location is properly mocked
|
|
551
|
+
Object.defineProperty(global, 'window', {
|
|
552
|
+
value: {
|
|
553
|
+
location: {
|
|
554
|
+
href: 'https://test.example.com',
|
|
555
|
+
},
|
|
556
|
+
localStorage: {
|
|
557
|
+
getItem: vi.fn(),
|
|
558
|
+
},
|
|
559
|
+
performance: {
|
|
560
|
+
now: vi.fn(() => Date.now()),
|
|
561
|
+
},
|
|
562
|
+
},
|
|
563
|
+
writable: true,
|
|
564
|
+
configurable: true,
|
|
565
|
+
});
|
|
566
|
+
|
|
490
567
|
createService();
|
|
491
568
|
|
|
492
569
|
const enrichmentCall = mockAdd.mock.calls[0];
|
|
@@ -541,6 +618,9 @@ describe('AmplitudeService', () => {
|
|
|
541
618
|
it('should track multiple events with correct userId', async () => {
|
|
542
619
|
const service = createService();
|
|
543
620
|
|
|
621
|
+
// Ensure the service is ready
|
|
622
|
+
expect(service.isReady).toBe(true);
|
|
623
|
+
|
|
544
624
|
await service.trackEvent({
|
|
545
625
|
eventName: SpiffyMetricsEventName.ChatUserMessageInput,
|
|
546
626
|
eventProps: { event1: true },
|
|
@@ -46,8 +46,20 @@ export enum SpiffyMetricsEventName {
|
|
|
46
46
|
SearchSortClicked = 'Search Sort Clicked',
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
export enum EnviveMetricsEventName {
|
|
50
|
+
WidgetRendered = 'Widget Rendered',
|
|
51
|
+
WidgetInteraction = 'Widget Interaction',
|
|
52
|
+
ChatRequest = 'Chat Request',
|
|
53
|
+
ChatResponse = 'Chat Response',
|
|
54
|
+
EnviveInitialized = 'Envive Initialized',
|
|
55
|
+
PageViewed = 'Page Viewed', // Will this be useful?
|
|
56
|
+
WidgetTextRequest = 'Widget Text Request',
|
|
57
|
+
WidgetTextResponse = 'Widget Text Response',
|
|
58
|
+
WidgetTextClicked = 'Widget Text Clicked',
|
|
59
|
+
}
|
|
60
|
+
|
|
49
61
|
export interface TrackEventParams {
|
|
50
|
-
eventName: SpiffyMetricsEventName;
|
|
62
|
+
eventName: SpiffyMetricsEventName | EnviveMetricsEventName;
|
|
51
63
|
eventProps?: Record<string, unknown>;
|
|
52
64
|
eventGroups?: Record<string, unknown>;
|
|
53
65
|
alsoSendToGoogleAnalytics?: boolean;
|
|
@@ -64,6 +76,7 @@ export interface AmplitudeServiceConfig {
|
|
|
64
76
|
featureFlagService: FeatureFlagService;
|
|
65
77
|
orgGaConfig?: unknown;
|
|
66
78
|
show: boolean;
|
|
79
|
+
enviveOn: boolean;
|
|
67
80
|
enabledFeatures?: Record<string, boolean>;
|
|
68
81
|
getLocalStorageItem: null | ((key: string) => string | null);
|
|
69
82
|
}
|
|
@@ -101,7 +114,9 @@ export class AmplitudeService {
|
|
|
101
114
|
return null;
|
|
102
115
|
}
|
|
103
116
|
|
|
104
|
-
private getDefaultTrackingProps(
|
|
117
|
+
private getDefaultTrackingProps(
|
|
118
|
+
eventName: SpiffyMetricsEventName | EnviveMetricsEventName,
|
|
119
|
+
): Record<string, unknown> {
|
|
105
120
|
const featureGates = Object.entries(this.config.featureFlagService.getFeatureFlags());
|
|
106
121
|
const gatesProps =
|
|
107
122
|
featureGates.length > 0
|
|
@@ -114,16 +129,32 @@ export class AmplitudeService {
|
|
|
114
129
|
: {};
|
|
115
130
|
const experimentProps = {}; // No direct equivalent for experiments in EnviveConfig yet
|
|
116
131
|
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
132
|
+
const environmentProps = {
|
|
133
|
+
'environment.execution_context': 'bundle',
|
|
134
|
+
'environment.page_url': window.location.href,
|
|
135
|
+
'environment.envive_user_id': this.config.userId,
|
|
136
|
+
'environment.execution_environment': this.config.env || 'unknown',
|
|
137
|
+
'environment.context_source': this.config.contextSource,
|
|
138
|
+
'environment.sales_agent_enabled': this.config.enabledFeatures?.salesAgent ?? false,
|
|
139
|
+
'environment.search_enabled': this.config.enabledFeatures?.searchAgent ?? false,
|
|
140
|
+
'environment.envive_on_query_param': this.config.enviveOn,
|
|
141
|
+
'environment.window_show': this.config.show,
|
|
142
|
+
'environment.envive_enabled': this.config.enabledFeatures?.envive,
|
|
120
143
|
};
|
|
121
144
|
|
|
145
|
+
const orgLevelAmplitudeTrackingProps = AmplitudeService.isEnviveEvent(eventName)
|
|
146
|
+
? {
|
|
147
|
+
...this.config.featureFlagService.getFullFlagValues(),
|
|
148
|
+
...experimentProps,
|
|
149
|
+
...environmentProps,
|
|
150
|
+
}
|
|
151
|
+
: {
|
|
152
|
+
...gatesProps,
|
|
153
|
+
...experimentProps,
|
|
154
|
+
};
|
|
122
155
|
return {
|
|
123
156
|
...orgLevelAmplitudeTrackingProps,
|
|
124
157
|
...this.supplementalDefaultProps,
|
|
125
|
-
// TODO: org_id is not directly available in EnviveConfig. Need to find a new source or derive it.
|
|
126
|
-
// org_id: orgConfig?.org?.org?.id,
|
|
127
158
|
app_id: 'commerce-chat-react-component',
|
|
128
159
|
chat_id: this.getLocalStorageItem(LocalStorageKeys.ChatId),
|
|
129
160
|
env: this.config.env || 'unknown',
|
|
@@ -143,7 +174,7 @@ export class AmplitudeService {
|
|
|
143
174
|
|
|
144
175
|
// eslint-disable-next-line class-methods-use-this
|
|
145
176
|
private eventPropsToPrefixedEventProps(
|
|
146
|
-
eventName: SpiffyMetricsEventName,
|
|
177
|
+
eventName: SpiffyMetricsEventName | EnviveMetricsEventName,
|
|
147
178
|
eventProps: Record<string, unknown>,
|
|
148
179
|
): Record<string, unknown> {
|
|
149
180
|
const prefix = eventName.toLowerCase().replace(/\s+/g, '_');
|
|
@@ -200,7 +231,9 @@ export class AmplitudeService {
|
|
|
200
231
|
...event,
|
|
201
232
|
event_properties: {
|
|
202
233
|
...event.event_properties,
|
|
203
|
-
...this.getDefaultTrackingProps(
|
|
234
|
+
...this.getDefaultTrackingProps(
|
|
235
|
+
event.event_type as SpiffyMetricsEventName | EnviveMetricsEventName,
|
|
236
|
+
),
|
|
204
237
|
...globalProperties,
|
|
205
238
|
...enabledFeaturesProperties,
|
|
206
239
|
...timingProperties,
|
|
@@ -342,6 +375,17 @@ export class AmplitudeService {
|
|
|
342
375
|
return eventProps ?? {};
|
|
343
376
|
}
|
|
344
377
|
|
|
378
|
+
static isEnviveEvent(eventName: SpiffyMetricsEventName | EnviveMetricsEventName): boolean {
|
|
379
|
+
return Object.values(EnviveMetricsEventName).includes(eventName as EnviveMetricsEventName);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
static decorateEventName(eventName: SpiffyMetricsEventName | EnviveMetricsEventName): string {
|
|
383
|
+
if (AmplitudeService.isEnviveEvent(eventName)) {
|
|
384
|
+
return `[Envive] ${eventName}`;
|
|
385
|
+
}
|
|
386
|
+
return `[Spiffy] ${eventName}`;
|
|
387
|
+
}
|
|
388
|
+
|
|
345
389
|
async trackEvent({
|
|
346
390
|
eventName,
|
|
347
391
|
eventProps,
|
|
@@ -350,7 +394,7 @@ export class AmplitudeService {
|
|
|
350
394
|
}: TrackEventParams): Promise<void> {
|
|
351
395
|
Logger.logDebug('Submitting event', eventName);
|
|
352
396
|
try {
|
|
353
|
-
const decoratedEventName =
|
|
397
|
+
const decoratedEventName = AmplitudeService.decorateEventName(eventName);
|
|
354
398
|
|
|
355
399
|
if (!this.amplitudeClient) {
|
|
356
400
|
Logger.logWarn('amplitude client undefined', undefined, {
|
|
@@ -382,7 +426,7 @@ export class AmplitudeService {
|
|
|
382
426
|
this.amplitudeClient.track(
|
|
383
427
|
decoratedEventName,
|
|
384
428
|
{
|
|
385
|
-
...this.getDefaultTrackingProps(),
|
|
429
|
+
...this.getDefaultTrackingProps(eventName),
|
|
386
430
|
...mappedEventProps,
|
|
387
431
|
...(mappedEventProps
|
|
388
432
|
? this.eventPropsToPrefixedEventProps(eventName, mappedEventProps)
|