Skip to content

Commit 026b5c4

Browse files
zhu-xiaoweixiaoweii
andauthored
feat: add publish configure, fix redundant click event (#6)
Co-authored-by: xiaoweii <[email protected]>
1 parent 16d32ac commit 026b5c4

File tree

8 files changed

+88
-56
lines changed

8 files changed

+88
-56
lines changed

README.md

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -10,40 +10,20 @@ The SDK relies on the Amplify for JS SDK Core Library and is developed according
1010

1111
### Include SDK
1212

13-
**1. Using NPM repository** (The package is pending release)
14-
15-
```bash
16-
npm install @awslabs/clickstream-web
17-
```
18-
19-
**2. Using source code**
20-
21-
Clone this repository locally.
22-
```bash
23-
git clone https://github.com/awslabs/clickstream-web.git
24-
```
25-
26-
Execute the following script to Generate `clickstream-web-x.x.x.tgz` zip package, which will be located in the project root folder.
2713
```bash
28-
cd clickstream-web && npm run build && npm run pack
14+
npm install @aws/clickstream-web
2915
```
3016

31-
Copy the `clickstream-web-x.x.x.tgz` into your project, then execute the following script in your project root folder to install the SDK.
32-
```bash
33-
npm install ./clickstream-web-x.x.x.tgz
34-
```
35-
Note: Please correct the SDK version and change the path to where the `clickstream-web-x.x.x.tgz` file is located.
36-
3717
### Initialize the SDK
3818
You need to configure the SDK with default information before using it. Copy your configuration code from your clickstream solution control plane, the configuration code should look like as follows. You can also manually add this code snippet and replace the values of appId and endpoint after you registered app to a data pipeline in the Clickstream Analytics solution console.
3919

4020
```typescript
41-
import { ClickstreamAnalytics, EventMode, PageType } from 'clickstream-web';
21+
import { ClickstreamAnalytics } from '@aws/clickstream-web';
4222

4323
ClickstreamAnalytics.configure({
4424
appId: "your appId",
4525
endpoint: "https://example.com/collect",
46-
)};
26+
});
4727
```
4828

4929
Your `appId` and `endpoint` are already set up in it.
@@ -55,7 +35,7 @@ Your `appId` and `endpoint` are already set up in it.
5535
Add the following code where you need to record event.
5636

5737
```typescript
58-
import { ClickstreamAnalytics } from 'clickstream-web';
38+
import { ClickstreamAnalytics } from '@aws/clickstream-web';
5939

6040
ClickstreamAnalytics.record({ name: 'albumVisit' });
6141
ClickstreamAnalytics.record({
@@ -67,7 +47,7 @@ ClickstreamAnalytics.record({
6747
#### Login and logout
6848

6949
```typescript
70-
import { ClickstreamAnalytics } from 'clickstream-web';
50+
import { ClickstreamAnalytics } from '@aws/clickstream-web';
7151

7252
// when user login success.
7353
ClickstreamAnalytics.setUserId("UserId");
@@ -91,7 +71,7 @@ Current login user's attributes will be cached in localStorage, so the next time
9171
In addition to the required `appId` and `endpoint`, you can configure other information to get more customized usage:
9272

9373
```typescript
94-
import { ClickstreamAnalytics, EventMode, PageType } from 'clickstream-web';
74+
import { ClickstreamAnalytics, EventMode, PageType } from '@aws/clickstream-web';
9575

9676
ClickstreamAnalytics.configure({
9777
appId: "your appId",
@@ -106,7 +86,9 @@ ClickstreamAnalytics.configure({
10686
isLogEvents: false,
10787
authCookie: "your auth cookie",
10888
sessionTimeoutDuration: 1800000,
109-
)};
89+
searchKeyWords: ['product', 'class'],
90+
domainList: ['example1.com', 'example2.com'],
91+
});
11092
```
11193

11294
Here is an explanation of each property:
@@ -123,12 +105,14 @@ Here is an explanation of each property:
123105
- **isLogEvents**: whether to print out event json for debugging, default is false.
124106
- **authCookie**: your auth cookie for AWS application load balancer auth cookie.
125107
- **sessionTimeoutDuration**: the duration for session timeout millisecond, default is 1800000
108+
- **searchKeyWords**: the customized Keywords for trigger the `_search` event, by default we detect `q`, `s`, `search`, `query` and `keyword` in query parameters.
109+
- **domainList**: if your website cross multiple domain, you can customize the domain list. The `_outbound` attribute of the `_click` event will be true when a link leads to a website that's not a part of your configured domain.
126110

127111
#### Configuration update
128112
You can update the default configuration after initializing the SDK, below are the additional configuration options you can customize.
129113

130114
```typescript
131-
import { ClickstreamAnalytics } from 'clickstream-web';
115+
import { ClickstreamAnalytics } from '@aws/clickstream-web';
132116

133117
ClickstreamAnalytics.updateConfigure({
134118
isLogEvents: true,
@@ -137,19 +121,23 @@ ClickstreamAnalytics.updateConfigure({
137121
isTrackClickEvents: false,
138122
isTrackScrollEvents: false,
139123
isTrackSearchEvents: false,
140-
searchKeyWords: ['product', 'class'],
141124
});
142125
```
143126

144-
## How to build&test locally
127+
## How to integrate and test locally
145128

146-
**Build**
129+
**Integrate**
147130

148-
Open your terminal window, at the root project folder to execute:
131+
Clone this repository locally, execute the following script to generate `aws-clickstream-web-x.x.x.tgz` zip package, which will be located in the project root folder.
132+
```bash
133+
cd clickstream-web && npm run pack
134+
```
149135

136+
Copy the `aws-clickstream-web-x.x.x.tgz` into your project, then execute the following script in your project root folder to install the SDK.
150137
```bash
151-
npm run build
138+
npm install ./aws-clickstream-web-x.x.x.tgz
152139
```
140+
Note: Please correct the SDK version and change the path to where the `aws-clickstream-web-x.x.x.tgz` file is located.
153141

154142
**Test**
155143

package.json

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"name": "clickstream-web",
3-
"version": "0.1.0",
2+
"name": "@aws/clickstream-web",
3+
"version": "0.1.1",
44
"description": "ClickstreamAnalytics Web SDK",
55
"license": "Apache-2.0",
66
"main": "./lib/index.ts",
@@ -19,8 +19,13 @@
1919
"lint": "npx eslint src",
2020
"test": "npm run prebuild && npx jest -w 1 --coverage",
2121
"clean": "rimraf lib-esm lib dist",
22-
"pack": "npm run prebuild && npm pack"
22+
"pack": "npm run build && npm pack"
2323
},
24+
"repository": {
25+
"type": "git",
26+
"url": "https://github.com/awslabs/clickstream-web.git"
27+
},
28+
"author": "AWS GCR Solutions Team",
2429
"dependencies": {
2530
"@aws-amplify/core": "^5.5.1",
2631
"uuid": "^9.0.0",

src/provider/ClickstreamProvider.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ export class ClickstreamProvider implements AnalyticsProvider {
5757
pageType: PageType.SPA,
5858
isLogEvents: false,
5959
sessionTimeoutDuration: 1800000,
60+
searchKeyWords: [],
61+
domainList: [],
6062
};
6163
}
6264

src/tracker/ClickTracker.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ export class ClickTracker extends BaseTracker {
2121
init() {
2222
this.trackClick = this.trackClick.bind(this);
2323
document.addEventListener('click', this.trackClick);
24+
const currentDomain = window.location.host;
25+
const domainList = this.context.configuration.domainList;
26+
if (!domainList.includes(currentDomain)) {
27+
domainList.push(currentDomain);
28+
}
2429
}
2530

2631
trackClick(event: MouseEvent) {
@@ -36,9 +41,11 @@ export class ClickTracker extends BaseTracker {
3641
} catch (error) {
3742
logger.debug('parse link domain failed: ' + error);
3843
}
44+
if (linkDomain === '') return;
3945
const linkClasses = targetElement.getAttribute('class');
4046
const linkId = targetElement.getAttribute('id');
41-
const outbound = window.location.host !== linkDomain;
47+
const outbound =
48+
!this.context.configuration.domainList.includes(linkDomain);
4249
this.provider.record({
4350
name: Event.PresetEvent.CLICK,
4451
attributes: {

src/tracker/PageViewTracker.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@ export class PageViewTracker extends BaseTracker {
2525
provider: ClickstreamProvider;
2626
context: ClickstreamContext;
2727
isEntrances = false;
28+
searchKeywords = Event.Constants.KEYWORDS;
2829

2930
init() {
31+
const configuredSearchKeywords = this.provider.configuration.searchKeyWords;
32+
Object.assign(this.searchKeywords, configuredSearchKeywords);
3033
this.trackPageView = this.trackPageView.bind(this);
3134
if (this.context.configuration.pageType === PageType.SPA) {
3235
this.trackPageViewForSPA();
@@ -90,12 +93,7 @@ export class PageViewTracker extends BaseTracker {
9093
const searchStr = window.location.search;
9194
if (!searchStr || searchStr.length === 0) return;
9295
const urlParams = new URLSearchParams(searchStr);
93-
const searchKeywords = Event.Constants.KEYWORDS;
94-
const configuredSearchKeywords = this.provider.configuration.searchKeyWords;
95-
if (configuredSearchKeywords !== undefined) {
96-
Object.assign(searchKeywords, configuredSearchKeywords);
97-
}
98-
for (const keyword of searchKeywords) {
96+
for (const keyword of this.searchKeywords) {
9997
if (urlParams.has(keyword)) {
10098
const searchTerm = urlParams.get(keyword);
10199
this.provider.record({

src/types/Analytics.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ export interface ClickstreamConfiguration extends Configuration {
1818
readonly sendEventsInterval?: number;
1919
readonly pageType?: PageType;
2020
readonly sessionTimeoutDuration?: number;
21+
readonly searchKeyWords?: string[];
22+
readonly domainList?: string[];
2123
}
2224

2325
export interface Configuration {
@@ -27,7 +29,6 @@ export interface Configuration {
2729
isTrackClickEvents?: boolean;
2830
isTrackScrollEvents?: boolean;
2931
isTrackSearchEvents?: boolean;
30-
searchKeyWords?: string[];
3132
}
3233

3334
export enum SendMode {

test/ClickstreamAnalytics.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ describe('ClickstreamAnalytics test', () => {
9292
isTrackClickEvents: false,
9393
isTrackScrollEvents: false,
9494
isTrackSearchEvents: false,
95-
searchKeyWords: ['video', 'product', 'class'],
9695
});
9796
const newConfigure = ClickstreamAnalytics['provider'].configuration;
9897
expect(newConfigure.isLogEvents).toBeTruthy();
@@ -101,7 +100,7 @@ describe('ClickstreamAnalytics test', () => {
101100
expect(newConfigure.isTrackClickEvents).toBeFalsy();
102101
expect(newConfigure.isTrackScrollEvents).toBeFalsy();
103102
expect(newConfigure.isTrackSearchEvents).toBeFalsy();
104-
expect(newConfigure.searchKeyWords.length).toBe(3);
103+
expect(newConfigure.searchKeyWords.length).toBe(0);
105104
});
106105

107106
function sleep(ms: number): Promise<void> {

test/tracker/ClickTracker.test.ts

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ describe('ClickTracker test', () => {
3535
appId: 'testAppId',
3636
endpoint: 'https://example.com/click',
3737
sendMode: SendMode.Batch,
38+
domainList: ['example1.com', 'example2.com'],
3839
});
3940
context = new ClickstreamContext(new BrowserInfo(), provider.configuration);
4041
const sessionTracker = new SessionTracker(provider, context);
@@ -67,35 +68,53 @@ describe('ClickTracker test', () => {
6768
expect(trackClickMock).toBeCalled();
6869
});
6970

70-
test('test click a element will full attribute', () => {
71+
test('test click a element with current domain', () => {
7172
const clickEvent = getMockMouseEvent(
7273
'A',
73-
'https://example.com',
74+
'https://localhost/collect',
7475
'link-class',
7576
'link-id'
7677
);
78+
clickTracker.setUp()
7779
clickTracker.trackClick(clickEvent);
7880
expect(recordMethodMock).toBeCalledWith({
7981
name: Event.PresetEvent.CLICK,
8082
attributes: {
81-
[Event.ReservedAttribute.LINK_URL]: 'https://example.com',
82-
[Event.ReservedAttribute.LINK_DOMAIN]: 'example.com',
83+
[Event.ReservedAttribute.LINK_URL]: 'https://localhost/collect',
84+
[Event.ReservedAttribute.LINK_DOMAIN]: 'localhost',
8385
[Event.ReservedAttribute.LINK_CLASSES]: 'link-class',
8486
[Event.ReservedAttribute.LINK_ID]: 'link-id',
85-
[Event.ReservedAttribute.OUTBOUND]: true,
87+
[Event.ReservedAttribute.OUTBOUND]: false,
8688
},
8789
});
8890
});
8991

90-
test('test click a element without link', () => {
92+
test('test click a element in configured domain', () => {
9193
const clickEvent = getMockMouseEvent(
9294
'A',
93-
'',
95+
'https://example1.com/collect',
9496
'link-class',
9597
'link-id'
9698
);
99+
clickTracker.setUp()
97100
clickTracker.trackClick(clickEvent);
98-
expect(recordMethodMock).not.toBeCalled()
101+
expect(recordMethodMock).toBeCalledWith({
102+
name: Event.PresetEvent.CLICK,
103+
attributes: {
104+
[Event.ReservedAttribute.LINK_URL]: 'https://example1.com/collect',
105+
[Event.ReservedAttribute.LINK_DOMAIN]: 'example1.com',
106+
[Event.ReservedAttribute.LINK_CLASSES]: 'link-class',
107+
[Event.ReservedAttribute.LINK_ID]: 'link-id',
108+
[Event.ReservedAttribute.OUTBOUND]: false,
109+
},
110+
});
111+
});
112+
113+
test('test click a element without link', () => {
114+
const clickEvent = getMockMouseEvent('A', '', 'link-class', 'link-id');
115+
clickTracker.setUp()
116+
clickTracker.trackClick(clickEvent);
117+
expect(recordMethodMock).not.toBeCalled();
99118
});
100119

101120
test('test click a element without host', () => {
@@ -105,12 +124,25 @@ describe('ClickTracker test', () => {
105124
'link-class',
106125
'link-id'
107126
);
127+
clickTracker.setUp()
128+
clickTracker.trackClick(clickEvent);
129+
expect(recordMethodMock).not.toBeCalled();
130+
});
131+
132+
test('test click a element with outbound', () => {
133+
const clickEvent = getMockMouseEvent(
134+
'A',
135+
'https://example3.com',
136+
'link-class',
137+
'link-id'
138+
);
139+
clickTracker.setUp()
108140
clickTracker.trackClick(clickEvent);
109141
expect(recordMethodMock).toBeCalledWith({
110142
name: Event.PresetEvent.CLICK,
111143
attributes: {
112-
[Event.ReservedAttribute.LINK_URL]: '/products',
113-
[Event.ReservedAttribute.LINK_DOMAIN]: '',
144+
[Event.ReservedAttribute.LINK_URL]: 'https://example3.com',
145+
[Event.ReservedAttribute.LINK_DOMAIN]: 'example3.com',
114146
[Event.ReservedAttribute.LINK_CLASSES]: 'link-class',
115147
[Event.ReservedAttribute.LINK_ID]: 'link-id',
116148
[Event.ReservedAttribute.OUTBOUND]: true,

0 commit comments

Comments
 (0)