Skip to content

Commit 933c312

Browse files
zhu-xiaoweixiaoweii
andauthored
feat: add preset traffic source attributes (#51)
Co-authored-by: xiaoweii <xiaoweii@amazom.com>
1 parent 7b6138f commit 933c312

File tree

5 files changed

+110
-15
lines changed

5 files changed

+110
-15
lines changed

.github/workflows/test.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ jobs:
1616
npm i
1717
npm run test
1818
- name: Upload Test Report
19-
uses: codecov/codecov-action@v3
19+
uses: codecov/codecov-action@v4
2020
with:
21+
token: ${{ secrets.CODECOV_TOKEN }}
2122
name: report
2223
files: coverage/coverage-final.json

README.md

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,22 +79,34 @@ When opening for the first time after integrating the SDK, you need to manually
7979
#### Add global attribute
8080
1. Add global attributes when initializing the SDK
8181

82+
The following example code shows how to add traffic source fields as global attributes when initializing the SDK.
83+
8284
```typescript
85+
import { ClickstreamAnalytics, Attr } from '@aws/clickstream-web';
86+
8387
ClickstreamAnalytics.init({
8488
appId: "your appId",
8589
endpoint: "https://example.com/collect",
8690
globalAttributes:{
87-
_traffic_source_medium: "Search engine",
88-
_traffic_source_name: "Summer promotion",
91+
[Attr.TRAFFIC_SOURCE_SOURCE]: 'amazon',
92+
[Attr.TRAFFIC_SOURCE_MEDIUM]: 'cpc',
93+
[Attr.TRAFFIC_SOURCE_CAMPAIGN]: 'summer_promotion',
94+
[Attr.TRAFFIC_SOURCE_CAMPAIGN_ID]: 'summer_promotion_01',
95+
[Attr.TRAFFIC_SOURCE_TERM]: 'running_shoes',
96+
[Attr.TRAFFIC_SOURCE_CONTENT]: 'banner_ad_1',
97+
[Attr.TRAFFIC_SOURCE_CLID]: 'amazon_ad_123',
98+
[Attr.TRAFFIC_SOURCE_CLID_PLATFORM]: 'amazon_ads',
8999
}
90100
});
91101
```
92102

93103
2. Add global attributes after initializing the SDK
94104

95105
``` typescript
106+
import { ClickstreamAnalytics, Attr } from '@aws/clickstream-web';
107+
96108
ClickstreamAnalytics.setGlobalAttributes({
97-
_traffic_source_medium: "Search engine",
109+
[Attr.TRAFFIC_SOURCE_MEDIUM]: "Search engine",
98110
level: 10,
99111
});
100112
```
@@ -108,7 +120,7 @@ You can add the following code to log an event with an item.
108120
**Note: Only pipelines from version 1.1+ can handle items with custom attribute.**
109121

110122
```typescript
111-
import { ClickstreamAnalytics, Item } from '@aws/clickstream-web';
123+
import { ClickstreamAnalytics, Item, Attr } from '@aws/clickstream-web';
112124

113125
const itemBook: Item = {
114126
id: '123',
@@ -120,7 +132,8 @@ const itemBook: Item = {
120132
ClickstreamAnalytics.record({
121133
name: 'view_item',
122134
attributes: {
123-
currency: 'USD',
135+
[Attr.CURRENCY]: 'USD',
136+
[Attr.VALUE]: 99,
124137
event_category: 'recommended',
125138
},
126139
items: [itemBook],

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@
1212
*/
1313

1414
export { ClickstreamAnalytics } from './ClickstreamAnalytics';
15-
export { PageType, SendMode, Item } from './types';
15+
export { PageType, SendMode, Item, Attr } from './types';

src/types/Analytics.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,31 @@ export enum PageType {
4646
multiPageApp = 'multiPageApp',
4747
}
4848

49+
export enum Attr {
50+
TRAFFIC_SOURCE_SOURCE = '_traffic_source_source',
51+
TRAFFIC_SOURCE_MEDIUM = '_traffic_source_medium',
52+
TRAFFIC_SOURCE_CAMPAIGN = '_traffic_source_campaign',
53+
TRAFFIC_SOURCE_CAMPAIGN_ID = '_traffic_source_campaign_id',
54+
TRAFFIC_SOURCE_TERM = '_traffic_source_term',
55+
TRAFFIC_SOURCE_CONTENT = '_traffic_source_content',
56+
TRAFFIC_SOURCE_CLID = '_traffic_source_clid',
57+
TRAFFIC_SOURCE_CLID_PLATFORM = '_traffic_source_clid_platform',
58+
VALUE = '_value',
59+
CURRENCY = '_currency',
60+
}
61+
4962
export interface ClickstreamAttribute {
63+
[Attr.TRAFFIC_SOURCE_SOURCE]?: string;
64+
[Attr.TRAFFIC_SOURCE_MEDIUM]?: string;
65+
[Attr.TRAFFIC_SOURCE_CAMPAIGN]?: string;
66+
[Attr.TRAFFIC_SOURCE_CAMPAIGN_ID]?: string;
67+
[Attr.TRAFFIC_SOURCE_TERM]?: string;
68+
[Attr.TRAFFIC_SOURCE_CONTENT]?: string;
69+
[Attr.TRAFFIC_SOURCE_CLID]?: string;
70+
[Attr.TRAFFIC_SOURCE_CLID_PLATFORM]?: string;
71+
[Attr.VALUE]?: number;
72+
[Attr.CURRENCY]?: string;
73+
5074
[key: string]: string | number | boolean | null;
5175
}
5276

test/ClickstreamAnalytics.test.ts

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
* OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
1111
* and limitations under the License.
1212
*/
13-
import { setUpBrowserPerformance } from "./browser/BrowserUtil";
14-
import { ClickstreamAnalytics, Item, SendMode } from '../src';
13+
import { setUpBrowserPerformance } from './browser/BrowserUtil';
14+
import { ClickstreamAnalytics, Item, SendMode, Attr } from '../src';
1515
import { NetRequest } from '../src/network/NetRequest';
1616
import { Event } from '../src/provider';
1717
import { StorageUtil } from '../src/util/StorageUtil';
@@ -66,17 +66,72 @@ describe('ClickstreamAnalytics test', () => {
6666
);
6767
const firstEvent = eventList[0];
6868
expect(firstEvent.event_type).toBe(Event.PresetEvent.FIRST_OPEN);
69-
expect(firstEvent.user[Event.ReservedAttribute.USER_FIRST_TOUCH_TIMESTAMP]).not.toBeUndefined()
69+
expect(
70+
firstEvent.user[Event.ReservedAttribute.USER_FIRST_TOUCH_TIMESTAMP]
71+
).not.toBeUndefined();
7072
expect(firstEvent.attributes.brand).toBe('Samsung');
7173
expect(firstEvent.attributes.level).toBe(10);
72-
expect(firstEvent.attributes[Event.ReservedAttribute.SESSION_ID]).not.toBeUndefined();
73-
expect(firstEvent.attributes[Event.ReservedAttribute.SESSION_NUMBER]).not.toBeUndefined();
74-
expect(firstEvent.attributes[Event.ReservedAttribute.SESSION_START_TIMESTAMP]).not.toBeUndefined();
75-
expect(firstEvent.attributes[Event.ReservedAttribute.SESSION_DURATION]).not.toBeUndefined();
74+
expect(
75+
firstEvent.attributes[Event.ReservedAttribute.SESSION_ID]
76+
).not.toBeUndefined();
77+
expect(
78+
firstEvent.attributes[Event.ReservedAttribute.SESSION_NUMBER]
79+
).not.toBeUndefined();
80+
expect(
81+
firstEvent.attributes[Event.ReservedAttribute.SESSION_START_TIMESTAMP]
82+
).not.toBeUndefined();
83+
expect(
84+
firstEvent.attributes[Event.ReservedAttribute.SESSION_DURATION]
85+
).not.toBeUndefined();
7686
const testEvent = eventList[eventList.length - 1];
7787
expect(testEvent.attributes.brand).toBeUndefined();
7888
});
7989

90+
test('test init sdk with traffic source global attributes', async () => {
91+
const result = ClickstreamAnalytics.init({
92+
appId: 'testApp',
93+
endpoint: 'https://example.com/collect',
94+
sendMode: SendMode.Batch,
95+
globalAttributes: {
96+
[Attr.TRAFFIC_SOURCE_SOURCE]: 'amazon',
97+
[Attr.TRAFFIC_SOURCE_MEDIUM]: 'cpc',
98+
[Attr.TRAFFIC_SOURCE_CAMPAIGN]: 'summer_promotion',
99+
[Attr.TRAFFIC_SOURCE_CAMPAIGN_ID]: 'summer_promotion_01',
100+
[Attr.TRAFFIC_SOURCE_TERM]: 'running_shoes',
101+
[Attr.TRAFFIC_SOURCE_CONTENT]: 'banner_ad_1',
102+
[Attr.TRAFFIC_SOURCE_CLID]: 'amazon_ad_123',
103+
[Attr.TRAFFIC_SOURCE_CLID_PLATFORM]: 'amazon_ads',
104+
},
105+
});
106+
expect(result).toBeTruthy();
107+
await sleep(100);
108+
const eventList = JSON.parse(
109+
StorageUtil.getAllEvents() + Event.Constants.SUFFIX
110+
);
111+
const firstEvent = eventList[0];
112+
expect(firstEvent.event_type).toBe(Event.PresetEvent.FIRST_OPEN);
113+
expect(firstEvent.attributes[Attr.TRAFFIC_SOURCE_SOURCE]).toBe('amazon');
114+
expect(firstEvent.attributes[Attr.TRAFFIC_SOURCE_MEDIUM]).toBe('cpc');
115+
expect(firstEvent.attributes[Attr.TRAFFIC_SOURCE_CAMPAIGN]).toBe(
116+
'summer_promotion'
117+
);
118+
expect(firstEvent.attributes[Attr.TRAFFIC_SOURCE_CAMPAIGN_ID]).toBe(
119+
'summer_promotion_01'
120+
);
121+
expect(firstEvent.attributes[Attr.TRAFFIC_SOURCE_TERM]).toBe(
122+
'running_shoes'
123+
);
124+
expect(firstEvent.attributes[Attr.TRAFFIC_SOURCE_CONTENT]).toBe(
125+
'banner_ad_1'
126+
);
127+
expect(firstEvent.attributes[Attr.TRAFFIC_SOURCE_CLID]).toBe(
128+
'amazon_ad_123'
129+
);
130+
expect(firstEvent.attributes[Attr.TRAFFIC_SOURCE_CLID_PLATFORM]).toBe(
131+
'amazon_ads'
132+
);
133+
});
134+
80135
test('test record event with name success', async () => {
81136
const sendRequestMock = jest.spyOn(NetRequest, 'sendRequest');
82137
ClickstreamAnalytics.init({
@@ -111,7 +166,7 @@ describe('ClickstreamAnalytics test', () => {
111166
name: 'Nature',
112167
category: 'book',
113168
price: 56.5,
114-
customKey: "customValue",
169+
customKey: 'customValue',
115170
};
116171
ClickstreamAnalytics.record({
117172
name: 'testEvent',
@@ -120,6 +175,8 @@ describe('ClickstreamAnalytics test', () => {
120175
longValue: 4232032890992380000,
121176
isNew: true,
122177
score: 85.22,
178+
[Attr.VALUE]: 56.5,
179+
[Attr.CURRENCY]: 'USD',
123180
},
124181
items: [item],
125182
});

0 commit comments

Comments
 (0)