@segment/analytics-browser-actions-adobe-target 1.0.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/package.json +20 -0
- package/src/__tests__/index.test.ts +44 -0
- package/src/__tests__/utils.test.ts +22 -0
- package/src/generated-types.ts +24 -0
- package/src/index.ts +86 -0
- package/src/init-script.ts +18 -0
- package/src/trackEvent/__tests__/index.test.ts +85 -0
- package/src/trackEvent/generated-types.ts +22 -0
- package/src/trackEvent/index.ts +74 -0
- package/src/triggerView/__tests__/index.test.ts +91 -0
- package/src/triggerView/generated-types.ts +22 -0
- package/src/triggerView/index.ts +68 -0
- package/src/types.ts +8 -0
- package/src/upsertProfile/__tests__/index.test.ts +137 -0
- package/src/upsertProfile/generated-types.ts +14 -0
- package/src/upsertProfile/index.ts +64 -0
- package/src/utils.ts +32 -0
- package/tsconfig.json +9 -0
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@segment/analytics-browser-actions-adobe-target",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"main": "./dist/cjs",
|
|
6
|
+
"module": "./dist/esm",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "yarn build:esm && yarn build:cjs",
|
|
9
|
+
"build-es": "tsc",
|
|
10
|
+
"build:cjs": "tsc --module commonjs --outDir ./dist/cjs",
|
|
11
|
+
"build:esm": "tsc --outDir ./dist/esm"
|
|
12
|
+
},
|
|
13
|
+
"typings": "./dist/esm",
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@segment/browser-destination-runtime": "^1.0.0"
|
|
16
|
+
},
|
|
17
|
+
"peerDependencies": {
|
|
18
|
+
"@segment/analytics-next": "*"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Analytics, Context } from '@segment/analytics-next'
|
|
2
|
+
import adobeTarget, { destination } from '../index'
|
|
3
|
+
import { Subscription } from '@segment/browser-destination-runtime/types'
|
|
4
|
+
|
|
5
|
+
describe('Adobe Target Web', () => {
|
|
6
|
+
test('can load ATJS', async () => {
|
|
7
|
+
const subscriptions: Subscription[] = [
|
|
8
|
+
{
|
|
9
|
+
partnerAction: 'upsertProfile',
|
|
10
|
+
name: 'Upsert Profile',
|
|
11
|
+
enabled: true,
|
|
12
|
+
subscribe: 'type = "identify"',
|
|
13
|
+
mapping: {}
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
const [event] = await adobeTarget({
|
|
17
|
+
client_code: 'segmentexchangepartn',
|
|
18
|
+
admin_number: '10',
|
|
19
|
+
version: '2.8.0',
|
|
20
|
+
cookie_domain: 'segment.com',
|
|
21
|
+
mbox_name: 'target-global-mbox',
|
|
22
|
+
subscriptions
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
jest.spyOn(destination, 'initialize')
|
|
26
|
+
|
|
27
|
+
await event.load(Context.system(), {} as Analytics)
|
|
28
|
+
expect(destination.initialize).toHaveBeenCalled()
|
|
29
|
+
|
|
30
|
+
const scripts = window.document.querySelectorAll('script')
|
|
31
|
+
expect(scripts).toMatchInlineSnapshot(`
|
|
32
|
+
NodeList [
|
|
33
|
+
<script
|
|
34
|
+
src="https://admin10.testandtarget.omniture.com/admin/rest/v1/libraries/atjs/download?client=segmentexchangepartn&version=2.8.0"
|
|
35
|
+
status="loaded"
|
|
36
|
+
type="text/javascript"
|
|
37
|
+
/>,
|
|
38
|
+
<script>
|
|
39
|
+
// the emptiness
|
|
40
|
+
</script>,
|
|
41
|
+
]
|
|
42
|
+
`)
|
|
43
|
+
})
|
|
44
|
+
})
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { serializeProperties } from '../utils'
|
|
2
|
+
|
|
3
|
+
describe('Utils', () => {
|
|
4
|
+
describe('serializeProperties', () => {
|
|
5
|
+
test('converts array properties to string', async () => {
|
|
6
|
+
const tags = ['leonardo', 'michelangelo', 'donatello', 'raphael']
|
|
7
|
+
const properties = {
|
|
8
|
+
eventName: 'purchase',
|
|
9
|
+
total: 42.42,
|
|
10
|
+
item: 'car',
|
|
11
|
+
itemTags: tags
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
expect(serializeProperties(properties)).toEqual({
|
|
15
|
+
eventName: 'purchase',
|
|
16
|
+
total: 42.42,
|
|
17
|
+
item: 'car',
|
|
18
|
+
itemTags: '["leonardo","michelangelo","donatello","raphael"]'
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
})
|
|
22
|
+
})
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Generated file. DO NOT MODIFY IT BY HAND.
|
|
2
|
+
|
|
3
|
+
export interface Settings {
|
|
4
|
+
/**
|
|
5
|
+
* Your Adobe Target client code. To find your client code in Adobe Target, navigate to **Administration > Implementation**. The client code is shown at the top under Account Details.
|
|
6
|
+
*/
|
|
7
|
+
client_code: string
|
|
8
|
+
/**
|
|
9
|
+
* Your Adobe Target admin number. To find your admin number, please follow the instructions in [Adobe Docs](https://experienceleague.adobe.com/docs/target/using/implement-target/client-side/at-js-implementation/deploy-at-js/implementing-target-without-a-tag-manager.html).
|
|
10
|
+
*/
|
|
11
|
+
admin_number: string
|
|
12
|
+
/**
|
|
13
|
+
* The version of ATJS to use. Defaults to 2.8.0.
|
|
14
|
+
*/
|
|
15
|
+
version: string
|
|
16
|
+
/**
|
|
17
|
+
* The name of the Adobe Target mbox to use. Defaults to `target-global-mbox`.
|
|
18
|
+
*/
|
|
19
|
+
mbox_name: string
|
|
20
|
+
/**
|
|
21
|
+
* The domain from which you serve the mbox. Adobe Target recommends setting this value to your company's top-level domain.
|
|
22
|
+
*/
|
|
23
|
+
cookie_domain: string
|
|
24
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { Settings } from './generated-types'
|
|
2
|
+
import type { BrowserDestinationDefinition } from '@segment/browser-destination-runtime/types'
|
|
3
|
+
import { browserDestination } from '@segment/browser-destination-runtime/shim'
|
|
4
|
+
import { Adobe } from './types'
|
|
5
|
+
import { initScript } from './init-script'
|
|
6
|
+
|
|
7
|
+
import upsertProfile from './upsertProfile'
|
|
8
|
+
import triggerView from './triggerView'
|
|
9
|
+
import trackEvent from './trackEvent'
|
|
10
|
+
|
|
11
|
+
declare global {
|
|
12
|
+
interface Window {
|
|
13
|
+
adobe: Adobe
|
|
14
|
+
targetPageParams: Function
|
|
15
|
+
pageParams: Object
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const destination: BrowserDestinationDefinition<Settings, Adobe> = {
|
|
20
|
+
name: 'Adobe Target Web',
|
|
21
|
+
slug: 'actions-adobe-target-web',
|
|
22
|
+
mode: 'device',
|
|
23
|
+
|
|
24
|
+
settings: {
|
|
25
|
+
client_code: {
|
|
26
|
+
label: 'Client Code',
|
|
27
|
+
description:
|
|
28
|
+
'Your Adobe Target client code. To find your client code in Adobe Target, navigate to **Administration > Implementation**. The client code is shown at the top under Account Details.',
|
|
29
|
+
required: true,
|
|
30
|
+
type: 'string'
|
|
31
|
+
},
|
|
32
|
+
admin_number: {
|
|
33
|
+
label: 'Admin number',
|
|
34
|
+
description:
|
|
35
|
+
'Your Adobe Target admin number. To find your admin number, please follow the instructions in [Adobe Docs](https://experienceleague.adobe.com/docs/target/using/implement-target/client-side/at-js-implementation/deploy-at-js/implementing-target-without-a-tag-manager.html).',
|
|
36
|
+
required: true,
|
|
37
|
+
type: 'string'
|
|
38
|
+
},
|
|
39
|
+
version: {
|
|
40
|
+
label: 'ATJS Version',
|
|
41
|
+
description: 'The version of ATJS to use. Defaults to 2.8.0.',
|
|
42
|
+
type: 'string',
|
|
43
|
+
choices: [
|
|
44
|
+
{
|
|
45
|
+
value: '2.8.0',
|
|
46
|
+
label: '2.8.0'
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
default: '2.8.0',
|
|
50
|
+
required: true
|
|
51
|
+
},
|
|
52
|
+
mbox_name: {
|
|
53
|
+
label: 'Mbox Name',
|
|
54
|
+
description: 'The name of the Adobe Target mbox to use. Defaults to `target-global-mbox`.',
|
|
55
|
+
type: 'string',
|
|
56
|
+
required: true,
|
|
57
|
+
default: 'target-global-mbox'
|
|
58
|
+
},
|
|
59
|
+
cookie_domain: {
|
|
60
|
+
label: 'Cookie Domain',
|
|
61
|
+
description:
|
|
62
|
+
"The domain from which you serve the mbox. Adobe Target recommends setting this value to your company's top-level domain.",
|
|
63
|
+
type: 'string',
|
|
64
|
+
required: true
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
initialize: async ({ settings }, deps) => {
|
|
69
|
+
initScript(settings)
|
|
70
|
+
|
|
71
|
+
const targetUrl = 'testandtarget.omniture.com/admin/rest/v1/libraries/atjs/download'
|
|
72
|
+
const atjsUrl = `https://admin${settings.admin_number}.${targetUrl}?client=${settings.client_code}&version=${settings.version}`
|
|
73
|
+
|
|
74
|
+
await deps.loadScript(atjsUrl)
|
|
75
|
+
await deps.resolveWhen(() => Object.prototype.hasOwnProperty.call(window, 'adobe'), 100)
|
|
76
|
+
return window.adobe
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
actions: {
|
|
80
|
+
upsertProfile,
|
|
81
|
+
triggerView,
|
|
82
|
+
trackEvent
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export default browserDestination(destination)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
|
|
4
|
+
import { getPageParams } from './utils'
|
|
5
|
+
|
|
6
|
+
export function initScript(settings) {
|
|
7
|
+
window.pageParams = {}
|
|
8
|
+
window.targetGlobalSettings = {
|
|
9
|
+
cookieDomain: settings.cookie_domain,
|
|
10
|
+
enabled: true
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// DO NOT RENAME. This function is required by Adobe Target.
|
|
14
|
+
// Learn More: https://experienceleague.adobe.com/docs/target/using/implement-target/client-side/at-js-implementation/functions-overview/targetpageparams.html?lang=en
|
|
15
|
+
window.targetPageParams = function () {
|
|
16
|
+
return getPageParams()
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Analytics, Context } from '@segment/analytics-next'
|
|
2
|
+
import adobeTarget, { destination } from '../../index'
|
|
3
|
+
import { Subscription } from '@segment/browser-destination-runtime/types'
|
|
4
|
+
|
|
5
|
+
describe('Adobe Target Web', () => {
|
|
6
|
+
describe('#track', () => {
|
|
7
|
+
test('Calls track to track events', async () => {
|
|
8
|
+
const subscriptions: Subscription[] = [
|
|
9
|
+
{
|
|
10
|
+
partnerAction: 'trackEvent',
|
|
11
|
+
name: 'Track Event',
|
|
12
|
+
enabled: true,
|
|
13
|
+
subscribe: 'type = "track"',
|
|
14
|
+
mapping: {
|
|
15
|
+
userId: {
|
|
16
|
+
'@if': {
|
|
17
|
+
exists: {
|
|
18
|
+
'@path': '$.userId'
|
|
19
|
+
},
|
|
20
|
+
then: {
|
|
21
|
+
'@path': '$.userId'
|
|
22
|
+
},
|
|
23
|
+
else: {
|
|
24
|
+
'@path': '$.anonymousId'
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
type: {
|
|
29
|
+
'@path': '$.event'
|
|
30
|
+
},
|
|
31
|
+
properties: {
|
|
32
|
+
'@path': '$.properties'
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
const targetSettings = {
|
|
39
|
+
client_code: 'segmentexchangepartn',
|
|
40
|
+
admin_number: '10',
|
|
41
|
+
version: '2.8.0',
|
|
42
|
+
cookie_domain: 'segment.com',
|
|
43
|
+
mbox_name: 'target-global-mbox'
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const trackParams = {
|
|
47
|
+
properties: {
|
|
48
|
+
purchase_amount: 42.21,
|
|
49
|
+
currency: 'USD',
|
|
50
|
+
item: 'Shirt'
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const [event] = await adobeTarget({
|
|
55
|
+
...targetSettings,
|
|
56
|
+
subscriptions
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
jest.spyOn(destination, 'initialize')
|
|
60
|
+
|
|
61
|
+
destination.actions.trackEvent.perform = jest.fn(destination.actions.trackEvent.perform)
|
|
62
|
+
|
|
63
|
+
await event.load(Context.system(), {} as Analytics)
|
|
64
|
+
expect(destination.initialize).toHaveBeenCalled()
|
|
65
|
+
|
|
66
|
+
await event.track?.(
|
|
67
|
+
new Context({
|
|
68
|
+
event: 'purchase',
|
|
69
|
+
type: 'track',
|
|
70
|
+
...trackParams
|
|
71
|
+
})
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
expect(destination.actions.trackEvent.perform).toHaveBeenCalledWith(
|
|
75
|
+
expect.anything(),
|
|
76
|
+
expect.objectContaining({
|
|
77
|
+
payload: {
|
|
78
|
+
...trackParams,
|
|
79
|
+
type: 'purchase'
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
)
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
})
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Generated file. DO NOT MODIFY IT BY HAND.
|
|
2
|
+
|
|
3
|
+
export interface Payload {
|
|
4
|
+
/**
|
|
5
|
+
* The event type. Please ensure the type entered here is registered and available.
|
|
6
|
+
*/
|
|
7
|
+
type?: string
|
|
8
|
+
/**
|
|
9
|
+
* This will be sent to Adobe Target as an event parameter called "event_name".
|
|
10
|
+
*/
|
|
11
|
+
eventName?: string
|
|
12
|
+
/**
|
|
13
|
+
* Parameters specific to the event.
|
|
14
|
+
*/
|
|
15
|
+
properties?: {
|
|
16
|
+
[k: string]: unknown
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A user’s unique visitor ID. Setting an Mbox 3rd Party ID allows for updates via the Adobe Target Cloud Mode Destination. For more information, please see our Adobe Target Destination documentation.
|
|
20
|
+
*/
|
|
21
|
+
userId?: string
|
|
22
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
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 { Adobe } from '../types'
|
|
5
|
+
import { setMbox3rdPartyId, serializeProperties } from '../utils'
|
|
6
|
+
|
|
7
|
+
// Adobe Target only takes certain event types as valid parameters. We are defaulting to "display".
|
|
8
|
+
// Beware of changing it since other event types drop the event properties from AT's audience builder.
|
|
9
|
+
|
|
10
|
+
const TARGET_EVENT_TYPE = 'display'
|
|
11
|
+
|
|
12
|
+
const action: BrowserActionDefinition<Settings, Adobe, Payload> = {
|
|
13
|
+
title: 'Track Event',
|
|
14
|
+
description: 'Send user actions, such as clicks and conversions, to Adobe Target.',
|
|
15
|
+
platform: 'web',
|
|
16
|
+
defaultSubscription: 'type = "track"',
|
|
17
|
+
fields: {
|
|
18
|
+
type: {
|
|
19
|
+
label: 'Event Type',
|
|
20
|
+
description: 'The event type. Please ensure the type entered here is registered and available.',
|
|
21
|
+
type: 'string',
|
|
22
|
+
default: TARGET_EVENT_TYPE
|
|
23
|
+
},
|
|
24
|
+
eventName: {
|
|
25
|
+
label: 'Event Name',
|
|
26
|
+
description: 'This will be sent to Adobe Target as an event parameter called "event_name".',
|
|
27
|
+
type: 'string',
|
|
28
|
+
default: {
|
|
29
|
+
'@path': '$.event'
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
properties: {
|
|
33
|
+
label: 'Event Parameters',
|
|
34
|
+
description: 'Parameters specific to the event.',
|
|
35
|
+
type: 'object',
|
|
36
|
+
default: {
|
|
37
|
+
'@path': '$.properties'
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
userId: {
|
|
41
|
+
type: 'string',
|
|
42
|
+
description:
|
|
43
|
+
'A user’s unique visitor ID. Setting an Mbox 3rd Party ID allows for updates via the Adobe Target Cloud Mode Destination. For more information, please see our Adobe Target Destination documentation.',
|
|
44
|
+
label: 'Mbox 3rd Party ID',
|
|
45
|
+
default: {
|
|
46
|
+
'@if': {
|
|
47
|
+
exists: { '@path': '$.userId' },
|
|
48
|
+
then: { '@path': '$.userId' },
|
|
49
|
+
else: { '@path': '$.anonymousId' }
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
perform: (Adobe, event) => {
|
|
55
|
+
const payload = event.payload
|
|
56
|
+
setMbox3rdPartyId(payload.userId)
|
|
57
|
+
|
|
58
|
+
const event_params = {
|
|
59
|
+
...serializeProperties(payload.properties),
|
|
60
|
+
event_name: payload.eventName
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const params = {
|
|
64
|
+
mbox: event.settings.mbox_name,
|
|
65
|
+
preventDefault: true,
|
|
66
|
+
params: event_params,
|
|
67
|
+
type: payload.type
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
Adobe.target.trackEvent(params)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export default action
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { Analytics, Context } from '@segment/analytics-next'
|
|
2
|
+
import adobeTarget, { destination } from '../../index'
|
|
3
|
+
import { Subscription } from '@segment/browser-destination-runtime/types'
|
|
4
|
+
|
|
5
|
+
describe('Adobe Target Web', () => {
|
|
6
|
+
describe('#page', () => {
|
|
7
|
+
test('tracks a view with the page() parameters', async () => {
|
|
8
|
+
const subscriptions: Subscription[] = [
|
|
9
|
+
{
|
|
10
|
+
partnerAction: 'triggerView',
|
|
11
|
+
name: 'Trigger View',
|
|
12
|
+
enabled: true,
|
|
13
|
+
subscribe: 'type = "page"',
|
|
14
|
+
mapping: {
|
|
15
|
+
viewName: { '@path': '$.name' },
|
|
16
|
+
pageParameters: { '@path': '$.properties' },
|
|
17
|
+
sendNotification: true,
|
|
18
|
+
traits: {
|
|
19
|
+
'@path': '$.traits'
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
const targetSettings = {
|
|
26
|
+
client_code: 'segmentexchangepartn',
|
|
27
|
+
admin_number: '10',
|
|
28
|
+
version: '2.8.0',
|
|
29
|
+
cookie_domain: 'segment.com',
|
|
30
|
+
mbox_name: 'target-global-mbox'
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const pageParams = {
|
|
34
|
+
name: 'The Test Suite',
|
|
35
|
+
properties: {
|
|
36
|
+
language: 'ES',
|
|
37
|
+
currency: 'MXN',
|
|
38
|
+
region: {
|
|
39
|
+
country_code: 'MX',
|
|
40
|
+
state: 'Mich'
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const [event] = await adobeTarget({
|
|
46
|
+
...targetSettings,
|
|
47
|
+
subscriptions
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
jest.spyOn(destination, 'initialize')
|
|
51
|
+
|
|
52
|
+
destination.actions.triggerView.perform = jest.fn(destination.actions.triggerView.perform)
|
|
53
|
+
|
|
54
|
+
await event.load(Context.system(), {} as Analytics)
|
|
55
|
+
expect(destination.initialize).toHaveBeenCalled()
|
|
56
|
+
|
|
57
|
+
await event.page?.(
|
|
58
|
+
new Context({
|
|
59
|
+
type: 'page',
|
|
60
|
+
...pageParams
|
|
61
|
+
})
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
expect(destination.actions.triggerView.perform).toHaveBeenCalledWith(
|
|
65
|
+
expect.anything(),
|
|
66
|
+
expect.objectContaining({
|
|
67
|
+
payload: {
|
|
68
|
+
viewName: 'The Test Suite',
|
|
69
|
+
pageParameters: {
|
|
70
|
+
currency: 'MXN',
|
|
71
|
+
language: 'ES',
|
|
72
|
+
region: { country_code: 'MX', state: 'Mich' }
|
|
73
|
+
},
|
|
74
|
+
sendNotification: true
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
expect(window.pageParams).toEqual({
|
|
80
|
+
page: {
|
|
81
|
+
language: 'ES',
|
|
82
|
+
currency: 'MXN',
|
|
83
|
+
region: {
|
|
84
|
+
country_code: 'MX',
|
|
85
|
+
state: 'Mich'
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
})
|
|
89
|
+
})
|
|
90
|
+
})
|
|
91
|
+
})
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Generated file. DO NOT MODIFY IT BY HAND.
|
|
2
|
+
|
|
3
|
+
export interface Payload {
|
|
4
|
+
/**
|
|
5
|
+
* Name of the view or page.
|
|
6
|
+
*/
|
|
7
|
+
viewName: string
|
|
8
|
+
/**
|
|
9
|
+
* Parameters specific to the view or page.
|
|
10
|
+
*/
|
|
11
|
+
pageParameters?: {
|
|
12
|
+
[k: string]: unknown
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* By default, notifications are sent to the Adobe Target backend for incrementing impression count. If false, notifications are not sent for incrementing impression count.
|
|
16
|
+
*/
|
|
17
|
+
sendNotification?: boolean
|
|
18
|
+
/**
|
|
19
|
+
* A user’s unique visitor ID. Setting an Mbox 3rd Party ID allows for updates via the Adobe Target Cloud Mode Destination. For more information, please see our Adobe Target Destination documentation.
|
|
20
|
+
*/
|
|
21
|
+
userId?: string
|
|
22
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
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 { Adobe } from '../types'
|
|
5
|
+
import { setPageParams, setMbox3rdPartyId } from '../utils'
|
|
6
|
+
|
|
7
|
+
const action: BrowserActionDefinition<Settings, Adobe, Payload> = {
|
|
8
|
+
title: 'Trigger View',
|
|
9
|
+
defaultSubscription: 'type = "page"',
|
|
10
|
+
description: 'Send page-level data to Adobe Target.',
|
|
11
|
+
platform: 'web',
|
|
12
|
+
fields: {
|
|
13
|
+
viewName: {
|
|
14
|
+
type: 'string',
|
|
15
|
+
description: 'Name of the view or page.',
|
|
16
|
+
label: 'View Name',
|
|
17
|
+
default: {
|
|
18
|
+
'@path': '$.name'
|
|
19
|
+
},
|
|
20
|
+
required: true
|
|
21
|
+
},
|
|
22
|
+
pageParameters: {
|
|
23
|
+
type: 'object',
|
|
24
|
+
description: 'Parameters specific to the view or page.',
|
|
25
|
+
label: 'Page Parameters',
|
|
26
|
+
default: {
|
|
27
|
+
'@path': '$.properties'
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
sendNotification: {
|
|
31
|
+
type: 'boolean',
|
|
32
|
+
description:
|
|
33
|
+
'By default, notifications are sent to the Adobe Target backend for incrementing impression count. If false, notifications are not sent for incrementing impression count. ',
|
|
34
|
+
label: 'Send Notifications to Adobe Target.',
|
|
35
|
+
default: true
|
|
36
|
+
},
|
|
37
|
+
userId: {
|
|
38
|
+
type: 'string',
|
|
39
|
+
description:
|
|
40
|
+
'A user’s unique visitor ID. Setting an Mbox 3rd Party ID allows for updates via the Adobe Target Cloud Mode Destination. For more information, please see our Adobe Target Destination documentation.',
|
|
41
|
+
label: 'Mbox 3rd Party ID',
|
|
42
|
+
default: {
|
|
43
|
+
'@if': {
|
|
44
|
+
exists: { '@path': '$.userId' },
|
|
45
|
+
then: { '@path': '$.userId' },
|
|
46
|
+
else: { '@path': '$.anonymousId' }
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
perform: (Adobe, event) => {
|
|
52
|
+
const sendNotification = event.payload.sendNotification
|
|
53
|
+
const pageParams = event.payload.pageParameters
|
|
54
|
+
|
|
55
|
+
setMbox3rdPartyId(event.payload.userId)
|
|
56
|
+
|
|
57
|
+
/*
|
|
58
|
+
NOTE:
|
|
59
|
+
Page data needs to be set before the call to adobe.target.triggerView.
|
|
60
|
+
This is because the page data needs to be part of the global pageParams object.
|
|
61
|
+
*/
|
|
62
|
+
setPageParams({ page: { ...pageParams } })
|
|
63
|
+
|
|
64
|
+
Adobe.target.triggerView(event.payload.viewName, { page: sendNotification })
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export default action
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { Analytics, Context } from '@segment/analytics-next'
|
|
2
|
+
import adobeTarget, { destination } from '../../index'
|
|
3
|
+
import { Subscription } from '@segment/browser-destination-runtime/types'
|
|
4
|
+
|
|
5
|
+
describe('Adobe Target Web', () => {
|
|
6
|
+
describe('#identify', () => {
|
|
7
|
+
test('calls identify and simulates a login flow', async () => {
|
|
8
|
+
const subscriptions: Subscription[] = [
|
|
9
|
+
{
|
|
10
|
+
partnerAction: 'upsertProfile',
|
|
11
|
+
name: 'Upsert Profile',
|
|
12
|
+
enabled: true,
|
|
13
|
+
subscribe: 'type = "identify"',
|
|
14
|
+
mapping: {
|
|
15
|
+
userId: {
|
|
16
|
+
'@if': {
|
|
17
|
+
exists: {
|
|
18
|
+
'@path': '$.userId'
|
|
19
|
+
},
|
|
20
|
+
then: {
|
|
21
|
+
'@path': '$.userId'
|
|
22
|
+
},
|
|
23
|
+
else: {
|
|
24
|
+
'@path': '$.anonymousId'
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
traits: {
|
|
29
|
+
'@path': '$.traits'
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
const targetSettings = {
|
|
36
|
+
client_code: 'segmentexchangepartn',
|
|
37
|
+
admin_number: '10',
|
|
38
|
+
version: '2.8.0',
|
|
39
|
+
cookie_domain: 'segment.com',
|
|
40
|
+
mbox_name: 'target-global-mbox'
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const identifyParams = {
|
|
44
|
+
traits: {
|
|
45
|
+
favorite_color: 'blue',
|
|
46
|
+
location: {
|
|
47
|
+
country_code: 'MX',
|
|
48
|
+
state: 'Mich'
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const [event] = await adobeTarget({
|
|
54
|
+
...targetSettings,
|
|
55
|
+
subscriptions
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
jest.spyOn(destination, 'initialize')
|
|
59
|
+
|
|
60
|
+
destination.actions.upsertProfile.perform = jest.fn(destination.actions.upsertProfile.perform)
|
|
61
|
+
|
|
62
|
+
await event.load(Context.system(), {} as Analytics)
|
|
63
|
+
expect(destination.initialize).toHaveBeenCalled()
|
|
64
|
+
|
|
65
|
+
await event.identify?.(
|
|
66
|
+
new Context({
|
|
67
|
+
anonymousId: 'random-id-42',
|
|
68
|
+
type: 'identify',
|
|
69
|
+
...identifyParams
|
|
70
|
+
})
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
expect(destination.actions.upsertProfile.perform).toHaveBeenCalledWith(
|
|
74
|
+
expect.anything(),
|
|
75
|
+
expect.objectContaining({
|
|
76
|
+
payload: {
|
|
77
|
+
userId: 'random-id-42',
|
|
78
|
+
traits: {
|
|
79
|
+
favorite_color: 'blue',
|
|
80
|
+
location: {
|
|
81
|
+
country_code: 'MX',
|
|
82
|
+
state: 'Mich'
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
expect(window.pageParams).toEqual({
|
|
90
|
+
mbox3rdPartyId: 'random-id-42',
|
|
91
|
+
profile: {
|
|
92
|
+
favorite_color: 'blue',
|
|
93
|
+
location: {
|
|
94
|
+
country_code: 'MX',
|
|
95
|
+
state: 'Mich'
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
await event.identify?.(
|
|
101
|
+
new Context({
|
|
102
|
+
userId: 'The-Real-ID',
|
|
103
|
+
anonymousId: 'random-id-42',
|
|
104
|
+
type: 'identify',
|
|
105
|
+
...identifyParams
|
|
106
|
+
})
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
expect(destination.actions.upsertProfile.perform).toHaveBeenCalledWith(
|
|
110
|
+
expect.anything(),
|
|
111
|
+
expect.objectContaining({
|
|
112
|
+
payload: {
|
|
113
|
+
userId: 'The-Real-ID',
|
|
114
|
+
traits: {
|
|
115
|
+
favorite_color: 'blue',
|
|
116
|
+
location: {
|
|
117
|
+
country_code: 'MX',
|
|
118
|
+
state: 'Mich'
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
expect(window.pageParams).toEqual({
|
|
126
|
+
mbox3rdPartyId: 'The-Real-ID',
|
|
127
|
+
profile: {
|
|
128
|
+
favorite_color: 'blue',
|
|
129
|
+
location: {
|
|
130
|
+
country_code: 'MX',
|
|
131
|
+
state: 'Mich'
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
})
|
|
135
|
+
})
|
|
136
|
+
})
|
|
137
|
+
})
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Generated file. DO NOT MODIFY IT BY HAND.
|
|
2
|
+
|
|
3
|
+
export interface Payload {
|
|
4
|
+
/**
|
|
5
|
+
* A user’s unique visitor ID. Setting an Mbox 3rd Party ID allows for updates via the Adobe Target Cloud Mode Destination. For more information, please see our Adobe Target Destination documentation.
|
|
6
|
+
*/
|
|
7
|
+
userId?: string
|
|
8
|
+
/**
|
|
9
|
+
* Profile parameters specific to a user. Please note, Adobe recommends that PII is hashed prior to sending to Adobe.
|
|
10
|
+
*/
|
|
11
|
+
traits?: {
|
|
12
|
+
[k: string]: unknown
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { BrowserActionDefinition } from '@segment/browser-destination-runtime/types'
|
|
2
|
+
import type { Settings } from '../generated-types'
|
|
3
|
+
import { Adobe } from '../types'
|
|
4
|
+
import type { Payload } from './generated-types'
|
|
5
|
+
import { setPageParams, setMbox3rdPartyId } from '../utils'
|
|
6
|
+
|
|
7
|
+
const action: BrowserActionDefinition<Settings, Adobe, Payload> = {
|
|
8
|
+
title: 'Upsert Profile',
|
|
9
|
+
description: 'Create or update a user profile in Adobe Target.',
|
|
10
|
+
platform: 'web',
|
|
11
|
+
defaultSubscription: 'type = "identify"',
|
|
12
|
+
fields: {
|
|
13
|
+
userId: {
|
|
14
|
+
type: 'string',
|
|
15
|
+
description:
|
|
16
|
+
'A user’s unique visitor ID. Setting an Mbox 3rd Party ID allows for updates via the Adobe Target Cloud Mode Destination. For more information, please see our Adobe Target Destination documentation.',
|
|
17
|
+
label: 'Mbox 3rd Party ID',
|
|
18
|
+
default: {
|
|
19
|
+
'@if': {
|
|
20
|
+
exists: { '@path': '$.userId' },
|
|
21
|
+
then: { '@path': '$.userId' },
|
|
22
|
+
else: { '@path': '$.anonymousId' }
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
traits: {
|
|
27
|
+
type: 'object',
|
|
28
|
+
description:
|
|
29
|
+
'Profile parameters specific to a user. Please note, Adobe recommends that PII is hashed prior to sending to Adobe.',
|
|
30
|
+
label: 'Profile Attributes',
|
|
31
|
+
defaultObjectUI: 'keyvalue'
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
perform: (Adobe, event) => {
|
|
35
|
+
/*
|
|
36
|
+
NOTE:
|
|
37
|
+
identify() and track() actions leverage the same function (adobe.target.trackEvent()) to send data to Adobe.
|
|
38
|
+
identify does not pass an event name, track does.
|
|
39
|
+
*/
|
|
40
|
+
setMbox3rdPartyId(event.payload.userId)
|
|
41
|
+
|
|
42
|
+
/*
|
|
43
|
+
NOTE:
|
|
44
|
+
Profile data needs to be set before the call to adobe.target.trackEvent.
|
|
45
|
+
This is because the profile data needs to be part of the global pageParams object.
|
|
46
|
+
*/
|
|
47
|
+
setPageParams({
|
|
48
|
+
profile: {
|
|
49
|
+
...event.payload.traits
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
const params = {
|
|
54
|
+
mbox: event.settings.mbox_name,
|
|
55
|
+
params: {
|
|
56
|
+
event_name: 'profile_update' // DO NOT CHANGE. profile_update is used to differentiate between track and identify calls.
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
Adobe.target.trackEvent(params)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export default action
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
|
|
4
|
+
export function getPageParams() {
|
|
5
|
+
return window.pageParams
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function setPageParams(params) {
|
|
9
|
+
return (window.pageParams = { ...window.pageParams, ...params })
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function setMbox3rdPartyId(id) {
|
|
13
|
+
setPageParams({ mbox3rdPartyId: id })
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Track does not accept arrays as valid properties, therefore we are stringifying them.
|
|
17
|
+
export function serializeProperties(props: { [key: string]: unknown } | undefined) {
|
|
18
|
+
if (props === undefined) {
|
|
19
|
+
return {}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const serialized: { [key: string]: unknown } = {}
|
|
23
|
+
|
|
24
|
+
for (const key in props) {
|
|
25
|
+
serialized[key] = props[key]
|
|
26
|
+
if (Array.isArray(props[key])) {
|
|
27
|
+
serialized[key] = JSON.stringify(props[key])
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return serialized
|
|
32
|
+
}
|