coveo.analytics 2.30.44 → 2.30.46
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/README.md +41 -41
- package/dist/browser.mjs +72 -18
- package/dist/coveoua.browser.js +1 -1
- package/dist/coveoua.browser.js.map +1 -1
- package/dist/coveoua.debug.js +103 -30
- package/dist/coveoua.debug.js.map +1 -1
- package/dist/coveoua.js +1 -1
- package/dist/coveoua.js.map +1 -1
- package/dist/definitions/caseAssist/caseAssistActions.d.ts +4 -1
- package/dist/definitions/caseAssist/caseAssistClient.d.ts +12 -1
- package/dist/definitions/client/analytics.d.ts +2 -2
- package/dist/definitions/insight/insightClient.d.ts +2 -0
- package/dist/definitions/version.d.ts +1 -1
- package/dist/library.cjs +200 -37
- package/dist/library.es.js +72 -18
- package/dist/library.js +200 -37
- package/dist/library.mjs +200 -37
- package/dist/react-native.es.js +72 -18
- package/package.json +7 -7
- package/src/caseAssist/caseAssistActions.ts +4 -1
- package/src/caseAssist/caseAssistClient.spec.ts +64 -40
- package/src/caseAssist/caseAssistClient.ts +67 -6
- package/src/client/analytics.spec.ts +1 -1
- package/src/client/analytics.ts +11 -11
- package/src/client/analyticsBeaconClient.spec.ts +10 -10
- package/src/client/analyticsBeaconClient.ts +4 -4
- package/src/client/analyticsFetchClient.ts +1 -1
- package/src/client/analyticsRequestClient.ts +1 -1
- package/src/client/measurementProtocolMapper.ts +2 -2
- package/src/client/measurementProtocolMapping/baseMeasurementProtocolMapper.ts +1 -1
- package/src/client/measurementProtocolMapping/commerceMeasurementProtocolMapper.ts +5 -5
- package/src/client/noopAnalytics.ts +1 -1
- package/src/client/utils.spec.ts +6 -6
- package/src/coveoua/browser.ts +2 -2
- package/src/coveoua/plugins.ts +1 -1
- package/src/coveoua/simpleanalytics.spec.ts +5 -5
- package/src/coveoua/simpleanalytics.ts +1 -1
- package/src/donottrack.spec.ts +1 -1
- package/src/history.spec.ts +1 -1
- package/src/insight/insightClient.spec.ts +42 -8
- package/src/insight/insightClient.ts +82 -63
- package/src/plugins/ec.spec.ts +6 -6
- package/src/plugins/ec.ts +5 -5
- package/src/plugins/link.spec.ts +5 -5
- package/src/plugins/link.ts +1 -1
- package/src/plugins/svc.ts +1 -1
- package/src/searchPage/searchPageClient.spec.ts +3 -3
- package/src/searchPage/searchPageClient.ts +27 -24
- package/src/searchPage/searchPageEvents.ts +2 -1
- package/src/version.ts +1 -1
|
@@ -9,7 +9,8 @@ export enum CaseAssistActions {
|
|
|
9
9
|
enterInterface = 'ticket_create_start',
|
|
10
10
|
fieldUpdate = 'ticket_field_update',
|
|
11
11
|
fieldSuggestionClick = 'ticket_classification_click',
|
|
12
|
-
|
|
12
|
+
documentSuggestionClick = 'documentSuggestionClick',
|
|
13
|
+
documentSuggestionQuickview = 'documentSuggestionQuickview',
|
|
13
14
|
suggestionRate = 'suggestion_rate',
|
|
14
15
|
nextCaseStep = 'ticket_next_stage',
|
|
15
16
|
caseCancelled = 'ticket_cancel',
|
|
@@ -78,12 +79,14 @@ export interface FieldSuggestion {
|
|
|
78
79
|
export interface DocumentSuggestion {
|
|
79
80
|
suggestionId: string;
|
|
80
81
|
responseId: string;
|
|
82
|
+
permanentId: string;
|
|
81
83
|
suggestion: {
|
|
82
84
|
documentUri: string;
|
|
83
85
|
documentUriHash: string;
|
|
84
86
|
documentTitle: string;
|
|
85
87
|
documentUrl: string;
|
|
86
88
|
documentPosition: number;
|
|
89
|
+
sourceName: string;
|
|
87
90
|
};
|
|
88
91
|
fromQuickview?: boolean;
|
|
89
92
|
openDocument?: boolean;
|
|
@@ -11,6 +11,7 @@ import {TicketProperties} from '../plugins/svc';
|
|
|
11
11
|
const {fetchMock, fetchMockBeforeEach} = mockFetch();
|
|
12
12
|
import doNotTrack from '../donottrack';
|
|
13
13
|
import {Cookie} from '../cookieutils';
|
|
14
|
+
import {PartialDocumentInformation} from '../searchPage/searchPageEvents';
|
|
14
15
|
jest.mock('../donottrack', () => {
|
|
15
16
|
return {
|
|
16
17
|
default: jest.fn(),
|
|
@@ -19,17 +20,31 @@ jest.mock('../donottrack', () => {
|
|
|
19
20
|
});
|
|
20
21
|
|
|
21
22
|
describe('CaseAssistClient', () => {
|
|
22
|
-
const
|
|
23
|
+
const exampleSearchHub = 'example origin-level-1';
|
|
24
|
+
const exampleOriginLevel2 = 'example origin-level-2';
|
|
25
|
+
const exampleOriginLevel3 = 'example origin-level-3';
|
|
26
|
+
const exampleOriginContext = 'example origin-context';
|
|
27
|
+
const exampleSearchUID = 'foo';
|
|
28
|
+
const exampleLanguage = 'en';
|
|
29
|
+
const exampleClientId = '123-456';
|
|
30
|
+
|
|
23
31
|
let client: CaseAssistClient;
|
|
24
32
|
|
|
25
33
|
const provider: CaseAssistClientProvider = {
|
|
26
|
-
getOriginLevel1: () =>
|
|
34
|
+
getOriginLevel1: () => exampleSearchHub,
|
|
35
|
+
getOriginLevel2: () => exampleOriginLevel2,
|
|
36
|
+
getOriginLevel3: () => exampleOriginLevel3,
|
|
37
|
+
getOriginContext: () => exampleOriginContext,
|
|
38
|
+
getIsAnonymous: () => false,
|
|
39
|
+
getSearchUID: () => exampleSearchUID,
|
|
40
|
+
getLanguage: () => exampleLanguage,
|
|
27
41
|
};
|
|
28
42
|
|
|
29
43
|
beforeEach(() => {
|
|
30
44
|
fetchMockBeforeEach();
|
|
31
45
|
|
|
32
46
|
client = initClient();
|
|
47
|
+
client.coveoAnalyticsClient.runtime.storage.setItem('visitorId', exampleClientId);
|
|
33
48
|
fetchMock.mock(/.*/, {
|
|
34
49
|
visitorId: 'visitor-id',
|
|
35
50
|
});
|
|
@@ -44,7 +59,7 @@ describe('CaseAssistClient', () => {
|
|
|
44
59
|
{
|
|
45
60
|
enableAnalytics: true,
|
|
46
61
|
},
|
|
47
|
-
provider
|
|
62
|
+
provider,
|
|
48
63
|
);
|
|
49
64
|
};
|
|
50
65
|
|
|
@@ -76,18 +91,18 @@ describe('CaseAssistClient', () => {
|
|
|
76
91
|
};
|
|
77
92
|
};
|
|
78
93
|
|
|
79
|
-
const fakeDocumentSuggestion
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
94
|
+
const fakeDocumentSuggestion: DocumentSuggestion = {
|
|
95
|
+
responseId: 'document-suggestion-response-id',
|
|
96
|
+
suggestionId: 'document-suggestion-id',
|
|
97
|
+
permanentId: 'example permanent-id',
|
|
98
|
+
suggestion: {
|
|
99
|
+
documentPosition: 0,
|
|
100
|
+
documentTitle: 'the document title',
|
|
101
|
+
documentUri: 'some-document-uri',
|
|
102
|
+
documentUriHash: 'documenturihash',
|
|
103
|
+
documentUrl: 'some-document-url',
|
|
104
|
+
sourceName: 'example source-name',
|
|
105
|
+
},
|
|
91
106
|
};
|
|
92
107
|
|
|
93
108
|
const expectMatchPayload = (actionName: CaseAssistActions, actionData: Object, ticket: TicketProperties) => {
|
|
@@ -96,13 +111,29 @@ describe('CaseAssistClient', () => {
|
|
|
96
111
|
|
|
97
112
|
expectMatchActionPayload(content, actionName, actionData);
|
|
98
113
|
expectMatchTicketPayload(content, ticket);
|
|
99
|
-
expectMatchProperty(content, 'searchHub',
|
|
114
|
+
expectMatchProperty(content, 'searchHub', exampleSearchHub);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const expectMatchDocumentPayload = (actionCause: CaseAssistActions, doc: PartialDocumentInformation, meta = {}) => {
|
|
118
|
+
const body: string = lastCallBody(fetchMock);
|
|
119
|
+
const customData = {...meta};
|
|
120
|
+
expect(JSON.parse(body.toString())).toMatchObject({
|
|
121
|
+
actionCause,
|
|
122
|
+
customData,
|
|
123
|
+
language: exampleLanguage,
|
|
124
|
+
clientId: exampleClientId,
|
|
125
|
+
originContext: exampleOriginContext,
|
|
126
|
+
originLevel1: exampleSearchHub,
|
|
127
|
+
originLevel2: exampleOriginLevel2,
|
|
128
|
+
originLevel3: exampleOriginLevel3,
|
|
129
|
+
...doc,
|
|
130
|
+
});
|
|
100
131
|
};
|
|
101
132
|
|
|
102
133
|
const expectMatchActionPayload = (
|
|
103
134
|
content: Record<string, unknown>,
|
|
104
135
|
actionName: CaseAssistActions,
|
|
105
|
-
actionData: Object
|
|
136
|
+
actionData: Object,
|
|
106
137
|
) => {
|
|
107
138
|
expectMatchProperty(content, 'ec', 'svc');
|
|
108
139
|
expectMatchProperty(content, 'svc_action', actionName);
|
|
@@ -241,33 +272,26 @@ describe('CaseAssistClient', () => {
|
|
|
241
272
|
|
|
242
273
|
it('should send proper payload for #logSelectDocumentSuggestion', async () => {
|
|
243
274
|
await client.logSelectDocumentSuggestion({
|
|
244
|
-
suggestion: fakeDocumentSuggestion
|
|
275
|
+
suggestion: fakeDocumentSuggestion,
|
|
245
276
|
ticket: fakeTicket,
|
|
246
277
|
});
|
|
247
278
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
it('should send proper payload for #logSelectDocumentSuggestion when the fromQuickview property is set to true', async () => {
|
|
252
|
-
const myFakeDocumentSuggestion = fakeDocumentSuggestion();
|
|
253
|
-
myFakeDocumentSuggestion.fromQuickview = true;
|
|
254
|
-
await client.logSelectDocumentSuggestion({
|
|
255
|
-
suggestion: myFakeDocumentSuggestion,
|
|
256
|
-
ticket: fakeTicket,
|
|
279
|
+
expectMatchDocumentPayload(CaseAssistActions.documentSuggestionClick, fakeDocumentSuggestion.suggestion, {
|
|
280
|
+
contentIDKey: 'permanentId',
|
|
281
|
+
contentIDValue: fakeDocumentSuggestion.permanentId,
|
|
257
282
|
});
|
|
258
|
-
|
|
259
|
-
expectMatchPayload(CaseAssistActions.suggestionClick, myFakeDocumentSuggestion, fakeTicket);
|
|
260
283
|
});
|
|
261
284
|
|
|
262
|
-
it('should send proper payload for #
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
await client.logSelectDocumentSuggestion({
|
|
266
|
-
suggestion: myFakeDocumentSuggestion,
|
|
285
|
+
it('should send proper payload for #logQuickviewDocumentSuggestion', async () => {
|
|
286
|
+
await client.logQuickviewDocumentSuggestion({
|
|
287
|
+
suggestion: fakeDocumentSuggestion,
|
|
267
288
|
ticket: fakeTicket,
|
|
268
289
|
});
|
|
269
290
|
|
|
270
|
-
|
|
291
|
+
expectMatchDocumentPayload(CaseAssistActions.documentSuggestionQuickview, fakeDocumentSuggestion.suggestion, {
|
|
292
|
+
contentIDKey: 'permanentId',
|
|
293
|
+
contentIDValue: fakeDocumentSuggestion.permanentId,
|
|
294
|
+
});
|
|
271
295
|
});
|
|
272
296
|
|
|
273
297
|
it('should send proper payload for #logRateDocumentSuggestion', async () => {
|
|
@@ -275,17 +299,17 @@ describe('CaseAssistClient', () => {
|
|
|
275
299
|
|
|
276
300
|
await client.logRateDocumentSuggestion({
|
|
277
301
|
rating,
|
|
278
|
-
suggestion: fakeDocumentSuggestion
|
|
302
|
+
suggestion: fakeDocumentSuggestion,
|
|
279
303
|
ticket: fakeTicket,
|
|
280
304
|
});
|
|
281
305
|
|
|
282
306
|
expectMatchPayload(
|
|
283
307
|
CaseAssistActions.suggestionRate,
|
|
284
308
|
{
|
|
285
|
-
...fakeDocumentSuggestion
|
|
309
|
+
...fakeDocumentSuggestion,
|
|
286
310
|
rate: rating,
|
|
287
311
|
},
|
|
288
|
-
fakeTicket
|
|
312
|
+
fakeTicket,
|
|
289
313
|
);
|
|
290
314
|
});
|
|
291
315
|
|
|
@@ -310,7 +334,7 @@ describe('CaseAssistClient', () => {
|
|
|
310
334
|
{
|
|
311
335
|
reason: CaseCancelledReasons.quit,
|
|
312
336
|
},
|
|
313
|
-
fakeTicket
|
|
337
|
+
fakeTicket,
|
|
314
338
|
);
|
|
315
339
|
});
|
|
316
340
|
|
|
@@ -324,7 +348,7 @@ describe('CaseAssistClient', () => {
|
|
|
324
348
|
{
|
|
325
349
|
reason: CaseCancelledReasons.solved,
|
|
326
350
|
},
|
|
327
|
-
fakeTicket
|
|
351
|
+
fakeTicket,
|
|
328
352
|
);
|
|
329
353
|
});
|
|
330
354
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import CoveoAnalyticsClient, {AnalyticsClient, ClientOptions} from '../client/analytics';
|
|
2
2
|
import {NoopAnalytics} from '../client/noopAnalytics';
|
|
3
3
|
import doNotTrack from '../donottrack';
|
|
4
|
+
import {ClickEventRequest} from '../events';
|
|
4
5
|
import {SVCPlugin} from '../plugins/svc';
|
|
6
|
+
import {DocumentIdentifier, PartialDocumentInformation, SearchPageEvents} from '../searchPage/searchPageEvents';
|
|
5
7
|
import {
|
|
6
8
|
CaseAssistActions,
|
|
7
9
|
CaseAssistEvents,
|
|
@@ -19,6 +21,12 @@ import {
|
|
|
19
21
|
|
|
20
22
|
export interface CaseAssistClientProvider {
|
|
21
23
|
getOriginLevel1: () => string;
|
|
24
|
+
getOriginLevel2: () => string;
|
|
25
|
+
getOriginLevel3: () => string;
|
|
26
|
+
getOriginContext: () => string;
|
|
27
|
+
getIsAnonymous: () => boolean;
|
|
28
|
+
getSearchUID: () => string;
|
|
29
|
+
getLanguage: () => string;
|
|
22
30
|
}
|
|
23
31
|
|
|
24
32
|
export interface CaseAssistClientOptions extends ClientOptions {
|
|
@@ -29,7 +37,10 @@ export class CaseAssistClient {
|
|
|
29
37
|
public coveoAnalyticsClient: AnalyticsClient;
|
|
30
38
|
private svc: SVCPlugin;
|
|
31
39
|
|
|
32
|
-
constructor(
|
|
40
|
+
constructor(
|
|
41
|
+
private options: Partial<CaseAssistClientOptions>,
|
|
42
|
+
private provider?: CaseAssistClientProvider,
|
|
43
|
+
) {
|
|
33
44
|
const analyticsEnabled = (options.enableAnalytics ?? true) && !doNotTrack();
|
|
34
45
|
|
|
35
46
|
this.coveoAnalyticsClient = analyticsEnabled ? new CoveoAnalyticsClient(options) : new NoopAnalytics();
|
|
@@ -67,9 +78,17 @@ export class CaseAssistClient {
|
|
|
67
78
|
}
|
|
68
79
|
|
|
69
80
|
public logSelectDocumentSuggestion(meta: SelectDocumentSuggestionMetadata) {
|
|
70
|
-
this.
|
|
71
|
-
|
|
72
|
-
|
|
81
|
+
return this.logClickEvent(CaseAssistActions.documentSuggestionClick, meta.suggestion.suggestion, {
|
|
82
|
+
contentIDKey: 'permanentId',
|
|
83
|
+
contentIDValue: meta.suggestion.permanentId,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public logQuickviewDocumentSuggestion(meta: SelectDocumentSuggestionMetadata) {
|
|
88
|
+
return this.logClickEvent(CaseAssistActions.documentSuggestionQuickview, meta.suggestion.suggestion, {
|
|
89
|
+
contentIDKey: 'permanentId',
|
|
90
|
+
contentIDValue: meta.suggestion.permanentId,
|
|
91
|
+
});
|
|
73
92
|
}
|
|
74
93
|
|
|
75
94
|
public logRateDocumentSuggestion(meta: RateDocumentSuggestionMetadata) {
|
|
@@ -120,7 +139,7 @@ export class CaseAssistClient {
|
|
|
120
139
|
? {
|
|
121
140
|
searchHub: this.provider.getOriginLevel1(),
|
|
122
141
|
}
|
|
123
|
-
: null
|
|
142
|
+
: null,
|
|
124
143
|
);
|
|
125
144
|
}
|
|
126
145
|
|
|
@@ -133,7 +152,49 @@ export class CaseAssistClient {
|
|
|
133
152
|
? {
|
|
134
153
|
searchHub: this.provider.getOriginLevel1(),
|
|
135
154
|
}
|
|
136
|
-
: null
|
|
155
|
+
: null,
|
|
137
156
|
);
|
|
138
157
|
}
|
|
158
|
+
|
|
159
|
+
private async getBaseEventRequest(metadata?: Record<string, any>) {
|
|
160
|
+
const customData = {...metadata};
|
|
161
|
+
return {
|
|
162
|
+
...this.getOrigins(),
|
|
163
|
+
customData,
|
|
164
|
+
language: this.provider?.getLanguage(),
|
|
165
|
+
anonymous: this.provider?.getIsAnonymous(),
|
|
166
|
+
clientId: await this.getClientId(),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private getClientId() {
|
|
171
|
+
return this.coveoAnalyticsClient instanceof CoveoAnalyticsClient
|
|
172
|
+
? this.coveoAnalyticsClient.getCurrentVisitorId()
|
|
173
|
+
: undefined;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private getOrigins() {
|
|
177
|
+
return {
|
|
178
|
+
originContext: this.provider?.getOriginContext?.(),
|
|
179
|
+
originLevel1: this.provider?.getOriginLevel1(),
|
|
180
|
+
originLevel2: this.provider?.getOriginLevel2(),
|
|
181
|
+
originLevel3: this.provider?.getOriginLevel3(),
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
private async logClickEvent(
|
|
186
|
+
event: CaseAssistActions,
|
|
187
|
+
info: PartialDocumentInformation,
|
|
188
|
+
identifier: DocumentIdentifier,
|
|
189
|
+
metadata?: Record<string, any>,
|
|
190
|
+
) {
|
|
191
|
+
const payload: ClickEventRequest = {
|
|
192
|
+
...info,
|
|
193
|
+
...(await this.getBaseEventRequest({...identifier, ...metadata})),
|
|
194
|
+
searchQueryUid: this.provider?.getSearchUID() ?? '',
|
|
195
|
+
actionCause: event,
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
return this.coveoAnalyticsClient.sendClickEvent(payload);
|
|
199
|
+
}
|
|
139
200
|
}
|
|
@@ -713,7 +713,7 @@ describe('custom clientId', () => {
|
|
|
713
713
|
const client = new CoveoAnalyticsClient({});
|
|
714
714
|
expect.assertions(1);
|
|
715
715
|
await expect(client.setClientId('somestring')).rejects.toEqual(
|
|
716
|
-
Error('Cannot generate uuid client id without a specific namespace string.')
|
|
716
|
+
Error('Cannot generate uuid client id without a specific namespace string.'),
|
|
717
717
|
);
|
|
718
718
|
//uuid v5 specific uuid generation
|
|
719
719
|
});
|
package/src/client/analytics.ts
CHANGED
|
@@ -79,19 +79,19 @@ export interface AnalyticsClient {
|
|
|
79
79
|
): Promise<PreparedEvent<TPreparedRequest, TCompleteRequest, TResponse>>;
|
|
80
80
|
sendEvent(eventType: string, ...payload: VariableArgumentsPayload): Promise<AnyEventResponse | void>;
|
|
81
81
|
makeSearchEvent(
|
|
82
|
-
request: PreparedSearchEventRequest
|
|
82
|
+
request: PreparedSearchEventRequest,
|
|
83
83
|
): Promise<PreparedEvent<PreparedSearchEventRequest, SearchEventRequest, SearchEventResponse>>;
|
|
84
84
|
sendSearchEvent(request: SearchEventRequest): Promise<SearchEventResponse | void>;
|
|
85
85
|
makeClickEvent(
|
|
86
|
-
request: PreparedClickEventRequest
|
|
86
|
+
request: PreparedClickEventRequest,
|
|
87
87
|
): Promise<PreparedEvent<PreparedClickEventRequest, ClickEventRequest, ClickEventResponse>>;
|
|
88
88
|
sendClickEvent(request: ClickEventRequest): Promise<ClickEventResponse | void>;
|
|
89
89
|
makeCustomEvent(
|
|
90
|
-
request: PreparedCustomEventRequest
|
|
90
|
+
request: PreparedCustomEventRequest,
|
|
91
91
|
): Promise<PreparedEvent<PreparedCustomEventRequest, CustomEventRequest, CustomEventResponse>>;
|
|
92
92
|
sendCustomEvent(request: CustomEventRequest): Promise<CustomEventResponse | void>;
|
|
93
93
|
makeViewEvent(
|
|
94
|
-
request: PreparedViewEventRequest
|
|
94
|
+
request: PreparedViewEventRequest,
|
|
95
95
|
): Promise<PreparedEvent<PreparedViewEventRequest, ViewEventRequest, ViewEventResponse>>;
|
|
96
96
|
sendViewEvent(request: ViewEventRequest): Promise<ViewEventResponse | void>;
|
|
97
97
|
getVisit(): Promise<VisitResponse>;
|
|
@@ -220,7 +220,7 @@ export class CoveoAnalyticsClient implements AnalyticsClient, VisitorIdProvider
|
|
|
220
220
|
} catch (err) {
|
|
221
221
|
console.log(
|
|
222
222
|
'Could not get visitor ID from the current runtime environment storage. Using a random ID instead.',
|
|
223
|
-
err
|
|
223
|
+
err,
|
|
224
224
|
);
|
|
225
225
|
return uuidv4();
|
|
226
226
|
}
|
|
@@ -394,7 +394,7 @@ export class CoveoAnalyticsClient implements AnalyticsClient, VisitorIdProvider
|
|
|
394
394
|
payload: {...payloadToSend, ...remainingPayload},
|
|
395
395
|
});
|
|
396
396
|
await Promise.all(
|
|
397
|
-
this.afterSendHooks.map((hook) => hook(eventType, {...parametersToSend, ...remainingPayload}))
|
|
397
|
+
this.afterSendHooks.map((hook) => hook(eventType, {...parametersToSend, ...remainingPayload})),
|
|
398
398
|
);
|
|
399
399
|
await this.deferExecution();
|
|
400
400
|
return (await this.sendFromBuffer()) as TResponse | void;
|
|
@@ -431,7 +431,7 @@ export class CoveoAnalyticsClient implements AnalyticsClient, VisitorIdProvider
|
|
|
431
431
|
async makeSearchEvent(request: PreparedSearchEventRequest) {
|
|
432
432
|
return this.makeEvent<PreparedSearchEventRequest, SearchEventRequest, SearchEventResponse>(
|
|
433
433
|
EventType.search,
|
|
434
|
-
request
|
|
434
|
+
request,
|
|
435
435
|
);
|
|
436
436
|
}
|
|
437
437
|
|
|
@@ -442,7 +442,7 @@ export class CoveoAnalyticsClient implements AnalyticsClient, VisitorIdProvider
|
|
|
442
442
|
async makeClickEvent(request: PreparedClickEventRequest) {
|
|
443
443
|
return this.makeEvent<PreparedClickEventRequest, ClickEventRequest, ClickEventResponse>(
|
|
444
444
|
EventType.click,
|
|
445
|
-
request
|
|
445
|
+
request,
|
|
446
446
|
);
|
|
447
447
|
}
|
|
448
448
|
|
|
@@ -453,7 +453,7 @@ export class CoveoAnalyticsClient implements AnalyticsClient, VisitorIdProvider
|
|
|
453
453
|
async makeCustomEvent(request: PreparedCustomEventRequest) {
|
|
454
454
|
return this.makeEvent<PreparedCustomEventRequest, CustomEventRequest, CustomEventResponse>(
|
|
455
455
|
EventType.custom,
|
|
456
|
-
request
|
|
456
|
+
request,
|
|
457
457
|
);
|
|
458
458
|
}
|
|
459
459
|
|
|
@@ -535,7 +535,7 @@ export class CoveoAnalyticsClient implements AnalyticsClient, VisitorIdProvider
|
|
|
535
535
|
...newPayload,
|
|
536
536
|
[key]: payload[key],
|
|
537
537
|
}),
|
|
538
|
-
{}
|
|
538
|
+
{},
|
|
539
539
|
);
|
|
540
540
|
}
|
|
541
541
|
|
|
@@ -553,7 +553,7 @@ export class CoveoAnalyticsClient implements AnalyticsClient, VisitorIdProvider
|
|
|
553
553
|
...newPayload,
|
|
554
554
|
[key]: payload[key],
|
|
555
555
|
}),
|
|
556
|
-
{}
|
|
556
|
+
{},
|
|
557
557
|
);
|
|
558
558
|
return newPayload;
|
|
559
559
|
}
|
|
@@ -39,7 +39,7 @@ describe('AnalyticsBeaconClient', () => {
|
|
|
39
39
|
|
|
40
40
|
expect(sendBeaconMock).toHaveBeenCalledWith(
|
|
41
41
|
`${baseUrl}/analytics/custom?access_token=👛&visitorId=${currentVisitorId}&discardVisitInfo=true`,
|
|
42
|
-
expect.anything()
|
|
42
|
+
expect.anything(),
|
|
43
43
|
);
|
|
44
44
|
expect(await getSendBeaconFirstCallBlobArgument()).toBe(`customEvent=${encodeURIComponent('{"wow":"ok"}')}`);
|
|
45
45
|
});
|
|
@@ -63,12 +63,12 @@ describe('AnalyticsBeaconClient', () => {
|
|
|
63
63
|
|
|
64
64
|
expect(sendBeaconMock).toHaveBeenCalledWith(
|
|
65
65
|
`${baseUrl}/analytics/collect?visitorId=${currentVisitorId}&discardVisitInfo=true`,
|
|
66
|
-
expect.anything()
|
|
66
|
+
expect.anything(),
|
|
67
67
|
);
|
|
68
68
|
expect(await getSendBeaconFirstCallBlobArgument()).toBe(
|
|
69
69
|
`access_token=${encodeURIComponent('👛')}&collectEvent=${encodeURIComponent(
|
|
70
|
-
'{"pr1a":"value","to encode":"to encode"}'
|
|
71
|
-
)}
|
|
70
|
+
'{"pr1a":"value","to encode":"to encode"}',
|
|
71
|
+
)}`,
|
|
72
72
|
);
|
|
73
73
|
});
|
|
74
74
|
|
|
@@ -94,10 +94,10 @@ describe('AnalyticsBeaconClient', () => {
|
|
|
94
94
|
|
|
95
95
|
expect(sendBeaconMock).toHaveBeenCalledWith(
|
|
96
96
|
`${baseUrl}/analytics/collect?visitorId=${currentVisitorId}&discardVisitInfo=true`,
|
|
97
|
-
expect.anything()
|
|
97
|
+
expect.anything(),
|
|
98
98
|
);
|
|
99
99
|
expect(await getSendBeaconFirstCallBlobArgument()).toBe(
|
|
100
|
-
`access_token=${encodeURIComponent('👛')}&collectEvent=${encodeURIComponent('{"value":{"subvalue":"ok"}}')}
|
|
100
|
+
`access_token=${encodeURIComponent('👛')}&collectEvent=${encodeURIComponent('{"value":{"subvalue":"ok"}}')}`,
|
|
101
101
|
);
|
|
102
102
|
});
|
|
103
103
|
|
|
@@ -147,7 +147,7 @@ describe('AnalyticsBeaconClient', () => {
|
|
|
147
147
|
|
|
148
148
|
await client.sendEvent(EventType.collect, {foo: 'bar'});
|
|
149
149
|
expect(await getSendBeaconFirstCallBlobArgument()).toBe(
|
|
150
|
-
'access_token=%F0%9F%91%9B&collectEvent=%7B%22foo%22%3A%22baz%22%7D'
|
|
150
|
+
'access_token=%F0%9F%91%9B&collectEvent=%7B%22foo%22%3A%22baz%22%7D',
|
|
151
151
|
);
|
|
152
152
|
});
|
|
153
153
|
|
|
@@ -162,7 +162,7 @@ describe('AnalyticsBeaconClient', () => {
|
|
|
162
162
|
|
|
163
163
|
await client.sendEvent(EventType.click, {actionCause: 'foo'});
|
|
164
164
|
expect(await getSendBeaconFirstCallBlobArgument()).toContain(
|
|
165
|
-
`clickEvent=${encodeURIComponent('{"actionCause":"bar"}')}
|
|
165
|
+
`clickEvent=${encodeURIComponent('{"actionCause":"bar"}')}`,
|
|
166
166
|
);
|
|
167
167
|
});
|
|
168
168
|
|
|
@@ -176,7 +176,7 @@ describe('AnalyticsBeaconClient', () => {
|
|
|
176
176
|
|
|
177
177
|
await client.sendEvent(EventType.click, {actionCause: 'foo'});
|
|
178
178
|
expect(await getSendBeaconFirstCallBlobArgument()).toContain(
|
|
179
|
-
`clickEvent=${encodeURIComponent('{"actionCause":"foo","aNewProperty":"bar"}')}
|
|
179
|
+
`clickEvent=${encodeURIComponent('{"actionCause":"foo","aNewProperty":"bar"}')}`,
|
|
180
180
|
);
|
|
181
181
|
});
|
|
182
182
|
|
|
@@ -188,7 +188,7 @@ describe('AnalyticsBeaconClient', () => {
|
|
|
188
188
|
|
|
189
189
|
await client.sendEvent(EventType.click, {actionCause: 'bar'});
|
|
190
190
|
expect(await getSendBeaconFirstCallBlobArgument()).toContain(
|
|
191
|
-
`clickEvent=${encodeURIComponent(`{"actionCause":"bar"}`)}
|
|
191
|
+
`clickEvent=${encodeURIComponent(`{"actionCause":"bar"}`)}`,
|
|
192
192
|
);
|
|
193
193
|
});
|
|
194
194
|
});
|
|
@@ -7,7 +7,7 @@ export class AnalyticsBeaconClient implements AnalyticsRequestClient {
|
|
|
7
7
|
public async sendEvent(eventType: EventType, originalPayload: IRequestPayload): Promise<void> {
|
|
8
8
|
if (!this.isAvailable()) {
|
|
9
9
|
throw new Error(
|
|
10
|
-
`navigator.sendBeacon is not supported in this browser. Consider adding a polyfill like "sendbeacon-polyfill"
|
|
10
|
+
`navigator.sendBeacon is not supported in this browser. Consider adding a polyfill like "sendbeacon-polyfill".`,
|
|
11
11
|
);
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -18,7 +18,7 @@ export class AnalyticsBeaconClient implements AnalyticsRequestClient {
|
|
|
18
18
|
const {url, payload} = await this.preProcessRequestAsPotentialJSONString(
|
|
19
19
|
`${baseUrl}/analytics/${eventType}?${paramsFragments}`,
|
|
20
20
|
originalPayload,
|
|
21
|
-
preprocessRequest
|
|
21
|
+
preprocessRequest,
|
|
22
22
|
);
|
|
23
23
|
|
|
24
24
|
const parsedRequestData = this.encodeForEventType(eventType, payload);
|
|
@@ -41,7 +41,7 @@ export class AnalyticsBeaconClient implements AnalyticsRequestClient {
|
|
|
41
41
|
private async preProcessRequestAsPotentialJSONString(
|
|
42
42
|
originalURL: string,
|
|
43
43
|
originalPayload: IRequestPayload,
|
|
44
|
-
preprocessRequest?: PreprocessAnalyticsRequest
|
|
44
|
+
preprocessRequest?: PreprocessAnalyticsRequest,
|
|
45
45
|
): Promise<{url: string; payload: IRequestPayload}> {
|
|
46
46
|
let returnedUrl = originalURL;
|
|
47
47
|
let returnedPayload = originalPayload;
|
|
@@ -49,7 +49,7 @@ export class AnalyticsBeaconClient implements AnalyticsRequestClient {
|
|
|
49
49
|
if (preprocessRequest) {
|
|
50
50
|
const processedRequest = await preprocessRequest(
|
|
51
51
|
{url: originalURL, body: JSON.stringify(originalPayload)},
|
|
52
|
-
'analyticsBeacon'
|
|
52
|
+
'analyticsBeacon',
|
|
53
53
|
);
|
|
54
54
|
const {url: processedURL, body: processedBody} = processedRequest;
|
|
55
55
|
returnedUrl = processedURL || originalURL;
|
|
@@ -47,7 +47,7 @@ export class AnalyticsFetchClient implements AnalyticsRequestClient {
|
|
|
47
47
|
}
|
|
48
48
|
console.error(`An error has occured when sending the "${eventType}" event.`, response, payload);
|
|
49
49
|
throw new Error(
|
|
50
|
-
`An error has occurred when sending the "${eventType}" event. Check the console logs for more details
|
|
50
|
+
`An error has occurred when sending the "${eventType}" event. Check the console logs for more details.`,
|
|
51
51
|
);
|
|
52
52
|
}
|
|
53
53
|
}
|
|
@@ -21,7 +21,7 @@ export type AnalyticsClientOrigin = 'analyticsFetch' | 'analyticsBeacon';
|
|
|
21
21
|
|
|
22
22
|
export type PreprocessAnalyticsRequest = (
|
|
23
23
|
request: IAnalyticsRequestOptions,
|
|
24
|
-
clientOrigin: AnalyticsClientOrigin
|
|
24
|
+
clientOrigin: AnalyticsClientOrigin,
|
|
25
25
|
) => IAnalyticsRequestOptions | Promise<IAnalyticsRequestOptions>;
|
|
26
26
|
|
|
27
27
|
export interface IAnalyticsRequestOptions extends RequestInit {
|
|
@@ -24,7 +24,7 @@ export const convertKeysToMeasurementProtocol = (params: any) => {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
const measurementProtocolKeysMappingValues = keysOf(measurementProtocolKeysMapping).map(
|
|
27
|
-
(key) => measurementProtocolKeysMapping[key]
|
|
27
|
+
(key) => measurementProtocolKeysMapping[key],
|
|
28
28
|
);
|
|
29
29
|
|
|
30
30
|
const isKnownMeasurementProtocolKey = (key: string) => measurementProtocolKeysMappingValues.indexOf(key) !== -1;
|
|
@@ -66,6 +66,6 @@ const convertCustomObject = (prefix: string, customData: {[name: string]: string
|
|
|
66
66
|
...allCustom,
|
|
67
67
|
[`${prefix}${currentCustomKey}`]: customData[currentCustomKey],
|
|
68
68
|
}),
|
|
69
|
-
{}
|
|
69
|
+
{},
|
|
70
70
|
);
|
|
71
71
|
};
|
|
@@ -112,7 +112,7 @@ export const convertProductToMeasurementProtocol = (product: Product, index: num
|
|
|
112
112
|
export const convertImpressionListToMeasurementProtocol = (
|
|
113
113
|
impressionList: ImpressionList,
|
|
114
114
|
listIndex: number,
|
|
115
|
-
prefix: string
|
|
115
|
+
prefix: string,
|
|
116
116
|
) => {
|
|
117
117
|
const payload: {[name: string]: any} = impressionList.impressions.reduce(
|
|
118
118
|
(mappedImpressions, impression, productIndex) => {
|
|
@@ -121,7 +121,7 @@ export const convertImpressionListToMeasurementProtocol = (
|
|
|
121
121
|
...convertImpressionToMeasurementProtocol(impression, listIndex, productIndex, prefix),
|
|
122
122
|
};
|
|
123
123
|
},
|
|
124
|
-
{}
|
|
124
|
+
{},
|
|
125
125
|
);
|
|
126
126
|
|
|
127
127
|
if (impressionList.listName) {
|
|
@@ -135,7 +135,7 @@ const convertImpressionToMeasurementProtocol = (
|
|
|
135
135
|
impression: BaseImpression,
|
|
136
136
|
listIndex: number,
|
|
137
137
|
productIndex: number,
|
|
138
|
-
prefix: string
|
|
138
|
+
prefix: string,
|
|
139
139
|
) => {
|
|
140
140
|
return keysOf(impression).reduce((mappedImpression, key) => {
|
|
141
141
|
const newKey = `il${listIndex + 1}${prefix}${productIndex + 1}${impressionKeysMapping[key] || key}`;
|
|
@@ -150,7 +150,7 @@ const productKeysMappingValues = keysOf(productKeysMapping).map((key) => product
|
|
|
150
150
|
const impressionKeysMappingValues = keysOf(impressionKeysMapping).map((key) => impressionKeysMapping[key]);
|
|
151
151
|
const productActionsKeysMappingValues = keysOf(productActionsKeysMapping).map((key) => productActionsKeysMapping[key]);
|
|
152
152
|
const transactionActionsKeysMappingValues = keysOf(transactionActionsKeysMapping).map(
|
|
153
|
-
(key) => transactionActionsKeysMapping[key]
|
|
153
|
+
(key) => transactionActionsKeysMapping[key],
|
|
154
154
|
);
|
|
155
155
|
const reviewKeysMappingValues = keysOf(reviewActionsKeysMapping).map((key) => reviewActionsKeysMapping[key]);
|
|
156
156
|
const quoteKeysMappingValues = keysOf(quoteActionsKeysMapping).map((key) => quoteActionsKeysMapping[key]);
|
|
@@ -166,7 +166,7 @@ const transactionActionsKeyRegex = new RegExp(`^(${transactionActionsKeysMapping
|
|
|
166
166
|
const customProductKeyRegex = new RegExp(`^${productPrefixMatchGroup}custom$`);
|
|
167
167
|
const customImpressionKeyRegex = new RegExp(`^${impressionPrefixMatchGroup}custom$`);
|
|
168
168
|
const coveoCommerceExtensionKeysRegex = new RegExp(
|
|
169
|
-
`^(${[...coveoCommerceExtensionKeys, ...reviewKeysMappingValues, ...quoteKeysMappingValues].join('|')})
|
|
169
|
+
`^(${[...coveoCommerceExtensionKeys, ...reviewKeysMappingValues, ...quoteKeysMappingValues].join('|')})$`,
|
|
170
170
|
);
|
|
171
171
|
|
|
172
172
|
const isProductKey = (key: string) => productKeyRegex.test(key);
|
|
@@ -28,7 +28,7 @@ export class NoopAnalytics implements AnalyticsClient {
|
|
|
28
28
|
return Promise.resolve();
|
|
29
29
|
}
|
|
30
30
|
makeEvent<TPreparedRequest, TCompleteRequest, TResponse extends AnyEventResponse>(
|
|
31
|
-
eventType: EventType | string
|
|
31
|
+
eventType: EventType | string,
|
|
32
32
|
): Promise<PreparedEvent<TPreparedRequest, TCompleteRequest, TResponse>> {
|
|
33
33
|
return Promise.resolve({eventType: eventType as EventType, payload: null, log: () => Promise.resolve()});
|
|
34
34
|
}
|