@segment/analytics-browser-actions-cj 1.1.0
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/dist/cjs/generated-types.d.ts +4 -0
- package/dist/cjs/generated-types.js +3 -0
- package/dist/cjs/generated-types.js.map +1 -0
- package/dist/cjs/index.d.ts +11 -0
- package/dist/cjs/index.js +38 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/order/generated-types.d.ts +141 -0
- package/dist/cjs/order/generated-types.js +3 -0
- package/dist/cjs/order/generated-types.js.map +1 -0
- package/dist/cjs/order/hashing-utils.d.ts +15 -0
- package/dist/cjs/order/hashing-utils.js +96 -0
- package/dist/cjs/order/hashing-utils.js.map +1 -0
- package/dist/cjs/order/index.d.ts +6 -0
- package/dist/cjs/order/index.js +58 -0
- package/dist/cjs/order/index.js.map +1 -0
- package/dist/cjs/order/order-fields.d.ts +6 -0
- package/dist/cjs/order/order-fields.js +1091 -0
- package/dist/cjs/order/order-fields.js.map +1 -0
- package/dist/cjs/order/utils.d.ts +3 -0
- package/dist/cjs/order/utils.js +19 -0
- package/dist/cjs/order/utils.js.map +1 -0
- package/dist/cjs/sitePage/generated-types.d.ts +13 -0
- package/dist/cjs/sitePage/generated-types.js +3 -0
- package/dist/cjs/sitePage/generated-types.js.map +1 -0
- package/dist/cjs/sitePage/index.d.ts +6 -0
- package/dist/cjs/sitePage/index.js +125 -0
- package/dist/cjs/sitePage/index.js.map +1 -0
- package/dist/cjs/sitePage/utils.d.ts +2 -0
- package/dist/cjs/sitePage/utils.js +7 -0
- package/dist/cjs/sitePage/utils.js.map +1 -0
- package/dist/cjs/types.d.ts +34 -0
- package/dist/cjs/types.js +3 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/utils.d.ts +1 -0
- package/dist/cjs/utils.js +23 -0
- package/dist/cjs/utils.js.map +1 -0
- package/dist/esm/generated-types.d.ts +4 -0
- package/dist/esm/generated-types.js +2 -0
- package/dist/esm/generated-types.js.map +1 -0
- package/dist/esm/index.d.ts +11 -0
- package/dist/esm/index.js +34 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/order/generated-types.d.ts +141 -0
- package/dist/esm/order/generated-types.js +2 -0
- package/dist/esm/order/generated-types.js.map +1 -0
- package/dist/esm/order/hashing-utils.d.ts +15 -0
- package/dist/esm/order/hashing-utils.js +88 -0
- package/dist/esm/order/hashing-utils.js.map +1 -0
- package/dist/esm/order/index.d.ts +6 -0
- package/dist/esm/order/index.js +56 -0
- package/dist/esm/order/index.js.map +1 -0
- package/dist/esm/order/order-fields.d.ts +6 -0
- package/dist/esm/order/order-fields.js +1088 -0
- package/dist/esm/order/order-fields.js.map +1 -0
- package/dist/esm/order/utils.d.ts +3 -0
- package/dist/esm/order/utils.js +15 -0
- package/dist/esm/order/utils.js.map +1 -0
- package/dist/esm/sitePage/generated-types.d.ts +13 -0
- package/dist/esm/sitePage/generated-types.js +2 -0
- package/dist/esm/sitePage/generated-types.js.map +1 -0
- package/dist/esm/sitePage/index.d.ts +6 -0
- package/dist/esm/sitePage/index.js +123 -0
- package/dist/esm/sitePage/index.js.map +1 -0
- package/dist/esm/sitePage/utils.d.ts +2 -0
- package/dist/esm/sitePage/utils.js +4 -0
- package/dist/esm/sitePage/utils.js.map +1 -0
- package/dist/esm/types.d.ts +34 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/utils.d.ts +1 -0
- package/dist/esm/utils.js +20 -0
- package/dist/esm/utils.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +25 -0
- package/src/generated-types.ts +12 -0
- package/src/index.ts +46 -0
- package/src/order/__tests__/index.test.ts +985 -0
- package/src/order/generated-types.ts +545 -0
- package/src/order/hashing-utils.ts +141 -0
- package/src/order/index.ts +90 -0
- package/src/order/order-fields.ts +1117 -0
- package/src/order/utils.ts +19 -0
- package/src/sitePage/__tests__/index.test.ts +124 -0
- package/src/sitePage/generated-types.ts +45 -0
- package/src/sitePage/index.ts +128 -0
- package/src/sitePage/utils.ts +5 -0
- package/src/types.ts +38 -0
- package/src/utils.ts +21 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CJ } from '../types'
|
|
2
|
+
|
|
3
|
+
export function getCookieValue(cookieName: string): string | null {
|
|
4
|
+
const name = cookieName + '='
|
|
5
|
+
const decodedCookie = decodeURIComponent(document.cookie)
|
|
6
|
+
const cookieArray = decodedCookie.split('; ')
|
|
7
|
+
|
|
8
|
+
for (const cookie of cookieArray) {
|
|
9
|
+
if (cookie.startsWith(name)) {
|
|
10
|
+
return cookie.substring(name.length)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return null
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function setOrderJSON(cj: CJ, orderJSON: CJ['order']) {
|
|
18
|
+
cj.order = orderJSON
|
|
19
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { Analytics, Context } from '@segment/analytics-next'
|
|
2
|
+
import { Subscription } from '@segment/browser-destination-runtime'
|
|
3
|
+
import CJDestination, { destination } from '../../index'
|
|
4
|
+
import { CJ } from '../../types'
|
|
5
|
+
import * as sendModule from '../../utils'
|
|
6
|
+
import * as sitePageModule from '../utils'
|
|
7
|
+
|
|
8
|
+
describe('CJ init', () => {
|
|
9
|
+
const settings = {
|
|
10
|
+
tagId: '123456789',
|
|
11
|
+
actionTrackerId: '987654321'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let mockCJ: CJ
|
|
15
|
+
let sitePageEvent: any
|
|
16
|
+
beforeEach(async () => {
|
|
17
|
+
jest.spyOn(destination, 'initialize').mockImplementation(() => {
|
|
18
|
+
mockCJ = {} as CJ
|
|
19
|
+
return Promise.resolve(mockCJ)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
jest.spyOn(sendModule, 'send').mockImplementation(() => {
|
|
23
|
+
return Promise.resolve()
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
jest.spyOn(sitePageModule, 'setSitePageJSON')
|
|
27
|
+
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
afterEach(() => {
|
|
31
|
+
jest.restoreAllMocks()
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
test('CJ pixel sitePage event', async () => {
|
|
35
|
+
const subscriptions: Subscription[] = [
|
|
36
|
+
{
|
|
37
|
+
partnerAction: 'sitePage',
|
|
38
|
+
name: 'sitePage',
|
|
39
|
+
enabled: true,
|
|
40
|
+
subscribe: 'type = "page"',
|
|
41
|
+
mapping: {
|
|
42
|
+
userId: { '@path': '$.userId' },
|
|
43
|
+
enterpriseId: 999999,
|
|
44
|
+
pageType: 'homepage',
|
|
45
|
+
referringChannel: { '@path': '$.properties.referring_channel' },
|
|
46
|
+
cartSubtotal: { '@path': '$.properties.sub_total' },
|
|
47
|
+
items: {
|
|
48
|
+
'@arrayPath': [
|
|
49
|
+
'$.properties.products',
|
|
50
|
+
{
|
|
51
|
+
itemPrice: { '@path': '$.price' },
|
|
52
|
+
itemId: { '@path': '$.id' },
|
|
53
|
+
quantity: { '@path': '$.quantity' },
|
|
54
|
+
discount: { '@path': '$.discount' }
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
const context = new Context({
|
|
62
|
+
type: 'page',
|
|
63
|
+
userId: 'userId-abc123',
|
|
64
|
+
properties: {
|
|
65
|
+
referring_channel: 'Email',
|
|
66
|
+
sub_total: 10.99,
|
|
67
|
+
products: [
|
|
68
|
+
{
|
|
69
|
+
id: '123',
|
|
70
|
+
quantity: 1,
|
|
71
|
+
price: 1,
|
|
72
|
+
discount: 0.5
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
id: '456',
|
|
76
|
+
quantity: 2,
|
|
77
|
+
price: 2,
|
|
78
|
+
discount: 0
|
|
79
|
+
}
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
const [event] = await CJDestination({
|
|
84
|
+
...settings,
|
|
85
|
+
subscriptions
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
const sitePageJSON = {
|
|
89
|
+
userId: 'userId-abc123',
|
|
90
|
+
enterpriseId: 999999,
|
|
91
|
+
pageType: 'homepage',
|
|
92
|
+
referringChannel: 'Email',
|
|
93
|
+
cartSubtotal: 10.99,
|
|
94
|
+
items:[
|
|
95
|
+
{
|
|
96
|
+
itemId: '123',
|
|
97
|
+
quantity: 1,
|
|
98
|
+
itemPrice: 1,
|
|
99
|
+
discount: 0.5
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
itemId: '456',
|
|
103
|
+
quantity: 2,
|
|
104
|
+
itemPrice: 2,
|
|
105
|
+
discount: 0
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
sitePageEvent = event
|
|
111
|
+
const sendSpy = jest.spyOn(sendModule, 'send').mockResolvedValue(undefined)
|
|
112
|
+
await sitePageEvent.load(Context.system(), {} as Analytics)
|
|
113
|
+
await sitePageEvent.track?.(context)
|
|
114
|
+
expect(destination.initialize).toHaveBeenCalled()
|
|
115
|
+
expect(sitePageModule.setSitePageJSON).toHaveBeenCalled()
|
|
116
|
+
expect(sitePageModule.setSitePageJSON).toHaveBeenCalledWith(
|
|
117
|
+
expect.any(Object),
|
|
118
|
+
expect.objectContaining(sitePageJSON)
|
|
119
|
+
)
|
|
120
|
+
expect(sendSpy).toHaveBeenCalledWith('123456789')
|
|
121
|
+
expect(mockCJ.sitePage).toBe(undefined)
|
|
122
|
+
expect(mockCJ.order).toBe(undefined)
|
|
123
|
+
})
|
|
124
|
+
})
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Generated file. DO NOT MODIFY IT BY HAND.
|
|
2
|
+
|
|
3
|
+
export interface Payload {
|
|
4
|
+
/**
|
|
5
|
+
* A unique ID assigned by you to the user.
|
|
6
|
+
*/
|
|
7
|
+
userId?: string
|
|
8
|
+
/**
|
|
9
|
+
* Your CJ Enterprise ID.
|
|
10
|
+
*/
|
|
11
|
+
enterpriseId: number
|
|
12
|
+
/**
|
|
13
|
+
* Page type to be sent to CJ.
|
|
14
|
+
*/
|
|
15
|
+
pageType: string
|
|
16
|
+
/**
|
|
17
|
+
* The referring channel to be sent to CJ.
|
|
18
|
+
*/
|
|
19
|
+
referringChannel?: string
|
|
20
|
+
/**
|
|
21
|
+
* The cart subtotal to be sent to CJ.
|
|
22
|
+
*/
|
|
23
|
+
cartSubtotal?: number
|
|
24
|
+
/**
|
|
25
|
+
* The items to be sent to CJ.
|
|
26
|
+
*/
|
|
27
|
+
items?: {
|
|
28
|
+
/**
|
|
29
|
+
* the price of the item before tax and discount.
|
|
30
|
+
*/
|
|
31
|
+
unitPrice: number
|
|
32
|
+
/**
|
|
33
|
+
* The item sku.
|
|
34
|
+
*/
|
|
35
|
+
itemId: string
|
|
36
|
+
/**
|
|
37
|
+
* The quantity of the item.
|
|
38
|
+
*/
|
|
39
|
+
quantity: number
|
|
40
|
+
/**
|
|
41
|
+
* The discount applied to the item.
|
|
42
|
+
*/
|
|
43
|
+
discount?: number
|
|
44
|
+
}[]
|
|
45
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import type { BrowserActionDefinition } from '@segment/browser-destination-runtime/types'
|
|
2
|
+
import type { Settings } from '../generated-types'
|
|
3
|
+
import type { Payload } from './generated-types'
|
|
4
|
+
import { CJ } from '../types'
|
|
5
|
+
import { send } from '../utils'
|
|
6
|
+
import { setSitePageJSON } from './utils'
|
|
7
|
+
|
|
8
|
+
const action: BrowserActionDefinition<Settings, CJ, Payload> = {
|
|
9
|
+
title: 'Site Page',
|
|
10
|
+
description: 'Send site page data to CJ.',
|
|
11
|
+
platform: 'web',
|
|
12
|
+
defaultSubscription: 'type = "page"',
|
|
13
|
+
fields: {
|
|
14
|
+
userId: {
|
|
15
|
+
label: 'User ID',
|
|
16
|
+
description: 'A unique ID assigned by you to the user.',
|
|
17
|
+
type: 'string',
|
|
18
|
+
required: false,
|
|
19
|
+
default: { '@path': '$.userId' }
|
|
20
|
+
},
|
|
21
|
+
enterpriseId: {
|
|
22
|
+
label: 'Enterprise ID',
|
|
23
|
+
description: 'Your CJ Enterprise ID.',
|
|
24
|
+
type: 'number',
|
|
25
|
+
required: true
|
|
26
|
+
},
|
|
27
|
+
pageType: {
|
|
28
|
+
label: 'Page Type',
|
|
29
|
+
description: 'Page type to be sent to CJ.',
|
|
30
|
+
type: 'string',
|
|
31
|
+
choices: [
|
|
32
|
+
{ label: 'Account Center', value: 'accountCenter' },
|
|
33
|
+
{ label: 'Account Signup', value: 'accountSignup' },
|
|
34
|
+
{ label: 'Application Start', value: 'applicationStart' },
|
|
35
|
+
{ label: 'Branch Locator', value: 'branchLocator' },
|
|
36
|
+
{ label: 'Cart', value: 'cart' },
|
|
37
|
+
{ label: 'Category', value: 'category' },
|
|
38
|
+
{ label: 'Conversion Confirmation', value: 'conversionConfirmation' },
|
|
39
|
+
{ label: 'Department', value: 'department' },
|
|
40
|
+
{ label: 'Homepage', value: 'homepage' },
|
|
41
|
+
{ label: 'Information', value: 'information' },
|
|
42
|
+
{ label: 'Product Detail', value: 'productDetail' },
|
|
43
|
+
{ label: 'Property Detail', value: 'propertyDetail' },
|
|
44
|
+
{ label: 'Property Results', value: 'propertyResults' },
|
|
45
|
+
{ label: 'Search Results', value: 'searchResults' },
|
|
46
|
+
{ label: 'Store Locator', value: 'storeLocator' },
|
|
47
|
+
{ label: 'Sub Category', value: 'subCategory' }
|
|
48
|
+
],
|
|
49
|
+
required: true
|
|
50
|
+
},
|
|
51
|
+
referringChannel: {
|
|
52
|
+
label: 'Referring Channel',
|
|
53
|
+
description: 'The referring channel to be sent to CJ.',
|
|
54
|
+
type: 'string',
|
|
55
|
+
choices: [
|
|
56
|
+
{ label: 'Affiliate', value: 'Affiliate' },
|
|
57
|
+
{ label: 'Display', value: 'Display' },
|
|
58
|
+
{ label: 'Social', value: 'Social' },
|
|
59
|
+
{ label: 'Search', value: 'Search' },
|
|
60
|
+
{ label: 'Email', value: 'Email' },
|
|
61
|
+
{ label: 'Direct Navigation', value: 'Direct_Navigation' }
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
cartSubtotal: {
|
|
65
|
+
label: 'Cart Subtotal',
|
|
66
|
+
description: 'The cart subtotal to be sent to CJ.',
|
|
67
|
+
type: 'number',
|
|
68
|
+
required: false
|
|
69
|
+
},
|
|
70
|
+
items: {
|
|
71
|
+
label: 'Items',
|
|
72
|
+
description: 'The items to be sent to CJ.',
|
|
73
|
+
type: 'object',
|
|
74
|
+
multiple: true,
|
|
75
|
+
properties: {
|
|
76
|
+
unitPrice: {
|
|
77
|
+
label: 'Unit Price',
|
|
78
|
+
description: 'the price of the item before tax and discount.',
|
|
79
|
+
type: 'number',
|
|
80
|
+
required: true
|
|
81
|
+
},
|
|
82
|
+
itemId: {
|
|
83
|
+
label: 'Item ID',
|
|
84
|
+
description: 'The item sku.',
|
|
85
|
+
type: 'string',
|
|
86
|
+
required: true
|
|
87
|
+
},
|
|
88
|
+
quantity: {
|
|
89
|
+
label: 'Quantity',
|
|
90
|
+
description: 'The quantity of the item.',
|
|
91
|
+
type: 'number',
|
|
92
|
+
required: true
|
|
93
|
+
},
|
|
94
|
+
discount: {
|
|
95
|
+
label: 'Discount',
|
|
96
|
+
description: 'The discount applied to the item.',
|
|
97
|
+
type: 'number',
|
|
98
|
+
required: false
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
default: {
|
|
102
|
+
'@arrayPath': [
|
|
103
|
+
'$.properties.products',
|
|
104
|
+
{
|
|
105
|
+
itemPrice: { '@path': '$.price' },
|
|
106
|
+
itemId: { '@path': '$.id' },
|
|
107
|
+
quantity: { '@path': '$.quantity' },
|
|
108
|
+
discount: { '@path': '$.discount' }
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
perform: (cj, { payload, settings }) => {
|
|
115
|
+
setSitePageJSON(cj, payload)
|
|
116
|
+
const { tagId } = settings
|
|
117
|
+
send(tagId)
|
|
118
|
+
.then(() => {
|
|
119
|
+
cj.sitePage = undefined
|
|
120
|
+
cj.order = undefined
|
|
121
|
+
})
|
|
122
|
+
.catch((err) => {
|
|
123
|
+
console.warn(err)
|
|
124
|
+
})
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export default action
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export interface CJ {
|
|
2
|
+
sitePage?: {
|
|
3
|
+
enterpriseId: number
|
|
4
|
+
pageType: string
|
|
5
|
+
referringChannel?: string
|
|
6
|
+
cartSubtotal?: number
|
|
7
|
+
items?: Item[]
|
|
8
|
+
userId?: string
|
|
9
|
+
}
|
|
10
|
+
order?: SimpleOrder | AdvancedOrder
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface Item {
|
|
14
|
+
unitPrice: number
|
|
15
|
+
itemId: string
|
|
16
|
+
quantity: number
|
|
17
|
+
discount?: number
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface SimpleOrder {
|
|
21
|
+
trackingSource: 'Segment'
|
|
22
|
+
enterpriseId: number
|
|
23
|
+
pageType?: string
|
|
24
|
+
userId?: string
|
|
25
|
+
emailHash?: string
|
|
26
|
+
orderId: string
|
|
27
|
+
actionTrackerId?: string // This is required. If not provided, log a warning to the console.
|
|
28
|
+
currency: string
|
|
29
|
+
amount: number // should default to 0 if not provided
|
|
30
|
+
discount?: number
|
|
31
|
+
coupon?: string
|
|
32
|
+
cjeventOrder?: string //required whenever advertiser uses their own cookie to store the Event ID
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface AdvancedOrder extends SimpleOrder {
|
|
36
|
+
items: Item[]
|
|
37
|
+
}
|
|
38
|
+
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
|
|
4
|
+
export function send(tagId): Promise<void> {
|
|
5
|
+
return new Promise((resolve, reject) => {
|
|
6
|
+
;(function (a, b, c, d) {
|
|
7
|
+
a = `//www.mczbf.com/tags/${tagId}/tag.js`
|
|
8
|
+
b = document
|
|
9
|
+
c = 'script'
|
|
10
|
+
d = b.createElement(c)
|
|
11
|
+
d.src = a
|
|
12
|
+
d.type = 'text/java' + c
|
|
13
|
+
d.async = true
|
|
14
|
+
d.id = 'cjapitag'
|
|
15
|
+
d.onload = () => resolve()
|
|
16
|
+
d.onerror = () => reject(new Error('JC script failed to load correctly'))
|
|
17
|
+
a = b.getElementsByTagName(c)[0]
|
|
18
|
+
a.parentNode.insertBefore(d, a)
|
|
19
|
+
})()
|
|
20
|
+
})
|
|
21
|
+
}
|