Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add preset traffic source attributes #51

Merged
merged 2 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ jobs:
npm i
npm run test
- name: Upload Test Report
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
name: report
files: coverage/coverage-final.json
23 changes: 18 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,22 +79,34 @@ When opening for the first time after integrating the SDK, you need to manually
#### Add global attribute
1. Add global attributes when initializing the SDK

The following example code shows how to add traffic source fields as global attributes when initializing the SDK.

```typescript
import { ClickstreamAnalytics, Attr } from '@aws/clickstream-web';

ClickstreamAnalytics.init({
appId: "your appId",
endpoint: "https://example.com/collect",
globalAttributes:{
_traffic_source_medium: "Search engine",
_traffic_source_name: "Summer promotion",
[Attr.TRAFFIC_SOURCE_SOURCE]: 'amazon',
[Attr.TRAFFIC_SOURCE_MEDIUM]: 'cpc',
[Attr.TRAFFIC_SOURCE_CAMPAIGN]: 'summer_promotion',
[Attr.TRAFFIC_SOURCE_CAMPAIGN_ID]: 'summer_promotion_01',
[Attr.TRAFFIC_SOURCE_TERM]: 'running_shoes',
[Attr.TRAFFIC_SOURCE_CONTENT]: 'banner_ad_1',
[Attr.TRAFFIC_SOURCE_CLID]: 'amazon_ad_123',
[Attr.TRAFFIC_SOURCE_CLID_PLATFORM]: 'amazon_ads',
}
});
```

2. Add global attributes after initializing the SDK

``` typescript
import { ClickstreamAnalytics, Attr } from '@aws/clickstream-web';

ClickstreamAnalytics.setGlobalAttributes({
_traffic_source_medium: "Search engine",
[Attr.TRAFFIC_SOURCE_MEDIUM]: "Search engine",
level: 10,
});
```
Expand All @@ -108,7 +120,7 @@ You can add the following code to log an event with an item.
**Note: Only pipelines from version 1.1+ can handle items with custom attribute.**

```typescript
import { ClickstreamAnalytics, Item } from '@aws/clickstream-web';
import { ClickstreamAnalytics, Item, Attr } from '@aws/clickstream-web';

const itemBook: Item = {
id: '123',
Expand All @@ -120,7 +132,8 @@ const itemBook: Item = {
ClickstreamAnalytics.record({
name: 'view_item',
attributes: {
currency: 'USD',
[Attr.CURRENCY]: 'USD',
[Attr.VALUE]: 99,
event_category: 'recommended',
},
items: [itemBook],
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
*/

export { ClickstreamAnalytics } from './ClickstreamAnalytics';
export { PageType, SendMode, Item } from './types';
export { PageType, SendMode, Item, Attr } from './types';
24 changes: 24 additions & 0 deletions src/types/Analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,31 @@ export enum PageType {
multiPageApp = 'multiPageApp',
}

export enum Attr {
TRAFFIC_SOURCE_SOURCE = '_traffic_source_source',
TRAFFIC_SOURCE_MEDIUM = '_traffic_source_medium',
TRAFFIC_SOURCE_CAMPAIGN = '_traffic_source_campaign',
TRAFFIC_SOURCE_CAMPAIGN_ID = '_traffic_source_campaign_id',
TRAFFIC_SOURCE_TERM = '_traffic_source_term',
TRAFFIC_SOURCE_CONTENT = '_traffic_source_content',
TRAFFIC_SOURCE_CLID = '_traffic_source_clid',
TRAFFIC_SOURCE_CLID_PLATFORM = '_traffic_source_clid_platform',
VALUE = '_value',
CURRENCY = '_currency',
}

export interface ClickstreamAttribute {
[Attr.TRAFFIC_SOURCE_SOURCE]?: string;
[Attr.TRAFFIC_SOURCE_MEDIUM]?: string;
[Attr.TRAFFIC_SOURCE_CAMPAIGN]?: string;
[Attr.TRAFFIC_SOURCE_CAMPAIGN_ID]?: string;
[Attr.TRAFFIC_SOURCE_TERM]?: string;
[Attr.TRAFFIC_SOURCE_CONTENT]?: string;
[Attr.TRAFFIC_SOURCE_CLID]?: string;
[Attr.TRAFFIC_SOURCE_CLID_PLATFORM]?: string;
[Attr.VALUE]?: number;
[Attr.CURRENCY]?: string;

[key: string]: string | number | boolean | null;
}

Expand Down
73 changes: 65 additions & 8 deletions test/ClickstreamAnalytics.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
* OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
import { setUpBrowserPerformance } from "./browser/BrowserUtil";
import { ClickstreamAnalytics, Item, SendMode } from '../src';
import { setUpBrowserPerformance } from './browser/BrowserUtil';
import { ClickstreamAnalytics, Item, SendMode, Attr } from '../src';
import { NetRequest } from '../src/network/NetRequest';
import { Event } from '../src/provider';
import { StorageUtil } from '../src/util/StorageUtil';
Expand Down Expand Up @@ -66,17 +66,72 @@ describe('ClickstreamAnalytics test', () => {
);
const firstEvent = eventList[0];
expect(firstEvent.event_type).toBe(Event.PresetEvent.FIRST_OPEN);
expect(firstEvent.user[Event.ReservedAttribute.USER_FIRST_TOUCH_TIMESTAMP]).not.toBeUndefined()
expect(
firstEvent.user[Event.ReservedAttribute.USER_FIRST_TOUCH_TIMESTAMP]
).not.toBeUndefined();
expect(firstEvent.attributes.brand).toBe('Samsung');
expect(firstEvent.attributes.level).toBe(10);
expect(firstEvent.attributes[Event.ReservedAttribute.SESSION_ID]).not.toBeUndefined();
expect(firstEvent.attributes[Event.ReservedAttribute.SESSION_NUMBER]).not.toBeUndefined();
expect(firstEvent.attributes[Event.ReservedAttribute.SESSION_START_TIMESTAMP]).not.toBeUndefined();
expect(firstEvent.attributes[Event.ReservedAttribute.SESSION_DURATION]).not.toBeUndefined();
expect(
firstEvent.attributes[Event.ReservedAttribute.SESSION_ID]
).not.toBeUndefined();
expect(
firstEvent.attributes[Event.ReservedAttribute.SESSION_NUMBER]
).not.toBeUndefined();
expect(
firstEvent.attributes[Event.ReservedAttribute.SESSION_START_TIMESTAMP]
).not.toBeUndefined();
expect(
firstEvent.attributes[Event.ReservedAttribute.SESSION_DURATION]
).not.toBeUndefined();
const testEvent = eventList[eventList.length - 1];
expect(testEvent.attributes.brand).toBeUndefined();
});

test('test init sdk with traffic source global attributes', async () => {
const result = ClickstreamAnalytics.init({
appId: 'testApp',
endpoint: 'https://example.com/collect',
sendMode: SendMode.Batch,
globalAttributes: {
[Attr.TRAFFIC_SOURCE_SOURCE]: 'amazon',
[Attr.TRAFFIC_SOURCE_MEDIUM]: 'cpc',
[Attr.TRAFFIC_SOURCE_CAMPAIGN]: 'summer_promotion',
[Attr.TRAFFIC_SOURCE_CAMPAIGN_ID]: 'summer_promotion_01',
[Attr.TRAFFIC_SOURCE_TERM]: 'running_shoes',
[Attr.TRAFFIC_SOURCE_CONTENT]: 'banner_ad_1',
[Attr.TRAFFIC_SOURCE_CLID]: 'amazon_ad_123',
[Attr.TRAFFIC_SOURCE_CLID_PLATFORM]: 'amazon_ads',
},
});
expect(result).toBeTruthy();
await sleep(100);
const eventList = JSON.parse(
StorageUtil.getAllEvents() + Event.Constants.SUFFIX
);
const firstEvent = eventList[0];
expect(firstEvent.event_type).toBe(Event.PresetEvent.FIRST_OPEN);
expect(firstEvent.attributes[Attr.TRAFFIC_SOURCE_SOURCE]).toBe('amazon');
expect(firstEvent.attributes[Attr.TRAFFIC_SOURCE_MEDIUM]).toBe('cpc');
expect(firstEvent.attributes[Attr.TRAFFIC_SOURCE_CAMPAIGN]).toBe(
'summer_promotion'
);
expect(firstEvent.attributes[Attr.TRAFFIC_SOURCE_CAMPAIGN_ID]).toBe(
'summer_promotion_01'
);
expect(firstEvent.attributes[Attr.TRAFFIC_SOURCE_TERM]).toBe(
'running_shoes'
);
expect(firstEvent.attributes[Attr.TRAFFIC_SOURCE_CONTENT]).toBe(
'banner_ad_1'
);
expect(firstEvent.attributes[Attr.TRAFFIC_SOURCE_CLID]).toBe(
'amazon_ad_123'
);
expect(firstEvent.attributes[Attr.TRAFFIC_SOURCE_CLID_PLATFORM]).toBe(
'amazon_ads'
);
});

test('test record event with name success', async () => {
const sendRequestMock = jest.spyOn(NetRequest, 'sendRequest');
ClickstreamAnalytics.init({
Expand Down Expand Up @@ -111,7 +166,7 @@ describe('ClickstreamAnalytics test', () => {
name: 'Nature',
category: 'book',
price: 56.5,
customKey: "customValue",
customKey: 'customValue',
};
ClickstreamAnalytics.record({
name: 'testEvent',
Expand All @@ -120,6 +175,8 @@ describe('ClickstreamAnalytics test', () => {
longValue: 4232032890992380000,
isNew: true,
score: 85.22,
[Attr.VALUE]: 56.5,
[Attr.CURRENCY]: 'USD',
},
items: [item],
});
Expand Down
Loading