Skip to content

Commit

Permalink
feat(headless): added the analytics section in the search requests ma…
Browse files Browse the repository at this point in the history
…de in the insight use case (#3726)

## [SFINT-5431](https://coveord.atlassian.net/browse/SFINT-5431)

In this PR:

- Added the analytics section to the search request executed in the
insight use case with the `ExcuteSearch` action.
- Added the analytics section to the search request executed in the
insight use case with the `Legacy ExcuteSearch` action.
- Fixed the `fromLogToLegacyBuilder` utility function, previously it was
building only events that have the value `caseAssist` as the action
cause. Now, with the implementation proposed in this PR, any action
cause could be set properly.
- Added new unit tests that check that the search query for the insight
use case is properly built with the analytics section.

## Demo

### With the legacy analytics:


https://github.com/coveo/ui-kit/assets/86681870/f4589d02-7ab0-43b3-8017-47ccafeb511e

### With the next analytics:


https://github.com/coveo/ui-kit/assets/86681870/281c973c-3f0a-4266-9823-4c14c3461725

[SFINT-5431]:
https://coveord.atlassian.net/browse/SFINT-5431?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

---------

Co-authored-by: Sylvie Allain <[email protected]>
Co-authored-by: Frederic Beaudoin <[email protected]>
  • Loading branch information
3 people authored Mar 21, 2024
1 parent 54a62e7 commit 55fc157
Show file tree
Hide file tree
Showing 27 changed files with 710 additions and 344 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
NumberOfResultsParam,
} from '../../../platform-service-params';
import {
AnalyticsParam,
ConstantQueryParam,
EnableDidYouMeanParam,
FacetsParam,
Expand All @@ -22,6 +23,7 @@ import {
import {InsightQuerySuggestRequest} from '../query-suggest/query-suggest-request';

export type InsightQueryRequest = InsightParam &
AnalyticsParam &
CaseContextParam &
FacetsParam &
QueryParam &
Expand Down
46 changes: 28 additions & 18 deletions packages/headless/src/features/analytics/analytics-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -548,20 +548,23 @@ type LogFunction<Client, StateNeeded> = (
state: StateNeeded
) => Promise<void | SearchEventResponse> | void | null;

const fromLogToLegacyBuilder =
<Client extends CommonClient, StateNeeded>(
const fromLogToLegacyBuilderFactory = (actionCause: string) => {
const fromLogToLegacyBuilder = <Client extends CommonClient, StateNeeded>(
log: (
client: Client,
state: StateNeeded
) => Promise<void | SearchEventResponse> | void | null
): ((client: Client, state: StateNeeded) => Promise<EventBuilder>) =>
(client, state) =>
Promise.resolve({
description: {actionCause: 'caseAssist'},
log: async (_metadata: {searchUID: string}) => {
log(client, state);
},
});
): ((client: Client, state: StateNeeded) => Promise<EventBuilder>) => {
return (client, state) =>
Promise.resolve({
description: {actionCause: actionCause},
log: async (_metadata: {searchUID: string}) => {
log(client, state);
},
});
};
return fromLogToLegacyBuilder;
};

export const makeAnalyticsAction = makeAnalyticsActionFactory<
StateNeededBySearchAnalyticsProvider,
Expand All @@ -578,17 +581,24 @@ export const makeCaseAssistAnalyticsAction = makeAnalyticsActionFactory<
LogFunction<CaseAssistClient, StateNeededByCaseAssistAnalytics>
>(
configureCaseAssistAnalytics,
fromLogToLegacyBuilder,
fromLogToLegacyBuilderFactory('caseAssist'),
CaseAssistAnalyticsProvider
);

export const makeInsightAnalyticsAction = makeAnalyticsActionFactory<
StateNeededByInsightAnalyticsProvider,
StateNeededByInsightAnalyticsProvider,
CoveoInsightClient,
InsightAnalyticsProvider,
LogFunction<CoveoInsightClient, StateNeededByInsightAnalyticsProvider>
>(configureInsightAnalytics, fromLogToLegacyBuilder, InsightAnalyticsProvider);
export const makeInsightAnalyticsActionFactory = (actionCause: string) => {
const makeInsightAnalyticsAction = makeAnalyticsActionFactory<
StateNeededByInsightAnalyticsProvider,
StateNeededByInsightAnalyticsProvider,
CoveoInsightClient,
InsightAnalyticsProvider,
LogFunction<CoveoInsightClient, StateNeededByInsightAnalyticsProvider>
>(
configureInsightAnalytics,
fromLogToLegacyBuilderFactory(actionCause),
InsightAnalyticsProvider
);
return makeInsightAnalyticsAction;
};

export const makeCommerceAnalyticsAction = makeAnalyticsActionFactory<
StateNeededByCommerceAnalyticsProvider,
Expand Down
36 changes: 36 additions & 0 deletions packages/headless/src/features/analytics/search-action-cause.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,4 +316,40 @@ export enum SearchPageEvents {
historyForward = 'historyForward',

historyBackward = 'historyBackward',
/**
* Identifies the search event that gets logged when the query context is updated as a result of updating one of the case context fields.
*/
contextChanged = 'contextChanged',
/**
* Identifies the search event that gets logged when a user clicks a rephrase button in a generated answer.
*/
rephraseGeneratedAnswer = 'rephraseGeneratedAnswer',
/**
* Identifies the custom event that gets logged when a user hovers over a generated answer citation.
*/
generatedAnswerSourceHover = 'generatedAnswerSourceHover',
/**
* Identifies the custom event that gets logged when a user submits feedback on a generated answer.
*/
generatedAnswerFeedbackSubmit = 'generatedAnswerFeedbackSubmit',
/**
* Identifies the custom event that gets logged when a user deactivates the RGA feature.
*/
generatedAnswerHideAnswers = 'generatedAnswerHideAnswers',
/**
* Identifies the custom event that gets logged when a user activates the RGA feature.
*/
generatedAnswerShowAnswers = 'generatedAnswerShowAnswers',
/**
* Identifies the custom event that gets logged when a user clicks the copy to clipboard button of a generated answer.
*/
generatedAnswerCopyToClipboard = 'generatedAnswerCopyToClipboard',
/**
* Identifies the custom event that gets logged when the user opens the full search page from the insight panel.
*/
expandToFullUI = 'expandToFullUI',
/**
* Identifies the custom event that gets logged when the user clicks the create article button.
*/
createArticle = 'createArticle',
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ import {Result} from '../../api/search/search/result';
import {
analyticsEventItemMetadata,
documentIdentifier,
makeInsightAnalyticsAction,
makeInsightAnalyticsActionFactory,
partialDocumentInformation,
validateResultPayload,
} from '../analytics/analytics-utils';
import {analyticsEventCaseContext} from '../analytics/insight-analytics-utils';
import {SearchPageEvents} from '../analytics/search-action-cause';
import {getCaseContextAnalyticsMetadata} from '../case-context/case-context-state';

export const logCaseAttach = (result: Result) =>
makeInsightAnalyticsAction({
makeInsightAnalyticsActionFactory(SearchPageEvents.caseAttach)({
prefix: 'insight/caseAttach',
__legacy__getBuilder: (client, state) => {
validateResultPayload(result);
Expand All @@ -38,7 +39,7 @@ export const logCaseAttach = (result: Result) =>
});

export const logCaseDetach = (result: Result) =>
makeInsightAnalyticsAction({
makeInsightAnalyticsActionFactory(SearchPageEvents.caseDetach)({
prefix: 'insight/caseDetach',
__legacy__getBuilder: (client, state) => {
return client.logCaseDetach(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import {
InsightAction,
makeInsightAnalyticsAction,
makeInsightAnalyticsActionFactory,
} from '../analytics/analytics-utils';
import {SearchPageEvents} from '../analytics/search-action-cause';
import {getCaseContextAnalyticsMetadata} from '../case-context/case-context-state';

export const logDidYouMeanClick = (): InsightAction =>
makeInsightAnalyticsAction('analytics/didyoumean/click', (client, state) =>
client.logDidYouMeanClick(
getCaseContextAnalyticsMetadata(state.insightCaseContext)
)
makeInsightAnalyticsActionFactory(SearchPageEvents.didyoumeanClick)(
'analytics/didyoumean/click',
(client, state) =>
client.logDidYouMeanClick(
getCaseContextAnalyticsMetadata(state.insightCaseContext)
)
);

export const logDidYouMeanAutomatic = (): InsightAction =>
makeInsightAnalyticsAction(
makeInsightAnalyticsActionFactory(SearchPageEvents.didyoumeanAutomatic)(
'analytics/didyoumean/automatic',
(client, state) =>
client.logDidYouMeanAutomatic(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import {
} from '../../../utils/validate-payload';
import {
InsightAction,
makeInsightAnalyticsAction,
makeInsightAnalyticsActionFactory,
} from '../../analytics/analytics-utils';
import {SearchPageEvents} from '../../analytics/search-action-cause';
import {getCaseContextAnalyticsMetadata} from '../../case-context/case-context-state';
import {facetIdDefinition} from '../generic/facet-actions-validation';
import {LogCategoryFacetBreadcrumbActionCreatorPayload} from './category-facet-set-analytics-actions';
Expand Down Expand Up @@ -42,7 +43,7 @@ const getCategoryFacetMetadata = (
export const logCategoryFacetBreadcrumb = (
payload: LogCategoryFacetBreadcrumbActionCreatorPayload
): InsightAction =>
makeInsightAnalyticsAction(
makeInsightAnalyticsActionFactory(SearchPageEvents.breadcrumbFacet)(
'analytics/categoryFacet/breadcrumb',
(client, state) => {
validatePayload(payload, categoryFacetBreadcrumbPayloadDefinition);
Expand Down
Loading

0 comments on commit 55fc157

Please sign in to comment.