@segment/analytics-browser-appcues-web-actions 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/README.md +31 -0
- package/dist/cjs/constants.d.ts +4 -0
- package/dist/cjs/constants.js +8 -0
- package/dist/cjs/constants.js.map +1 -0
- package/dist/cjs/generated-types.d.ts +5 -0
- package/dist/cjs/generated-types.js +3 -0
- package/dist/cjs/generated-types.js.map +1 -0
- package/dist/cjs/group/generated-types.d.ts +6 -0
- package/dist/cjs/group/generated-types.js +3 -0
- package/dist/cjs/group/generated-types.js.map +1 -0
- package/dist/cjs/group/index.d.ts +6 -0
- package/dist/cjs/group/index.js +30 -0
- package/dist/cjs/group/index.js.map +1 -0
- package/dist/cjs/identify/generated-types.d.ts +6 -0
- package/dist/cjs/identify/generated-types.js +3 -0
- package/dist/cjs/identify/generated-types.js.map +1 -0
- package/dist/cjs/identify/index.d.ts +6 -0
- package/dist/cjs/identify/index.js +30 -0
- package/dist/cjs/identify/index.js.map +1 -0
- package/dist/cjs/index.d.ts +6 -0
- package/dist/cjs/index.js +67 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/page/generated-types.d.ts +2 -0
- package/dist/cjs/page/generated-types.js +3 -0
- package/dist/cjs/page/generated-types.js.map +1 -0
- package/dist/cjs/page/index.d.ts +6 -0
- package/dist/cjs/page/index.js +14 -0
- package/dist/cjs/page/index.js.map +1 -0
- package/dist/cjs/track/generated-types.d.ts +6 -0
- package/dist/cjs/track/generated-types.js +3 -0
- package/dist/cjs/track/generated-types.js.map +1 -0
- package/dist/cjs/track/index.d.ts +6 -0
- package/dist/cjs/track/index.js +30 -0
- package/dist/cjs/track/index.js.map +1 -0
- package/dist/cjs/types.d.ts +18 -0
- package/dist/cjs/types.js +3 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/esm/constants.d.ts +4 -0
- package/dist/esm/constants.js +5 -0
- package/dist/esm/constants.js.map +1 -0
- package/dist/esm/generated-types.d.ts +5 -0
- package/dist/esm/generated-types.js +2 -0
- package/dist/esm/generated-types.js.map +1 -0
- package/dist/esm/group/generated-types.d.ts +6 -0
- package/dist/esm/group/generated-types.js +2 -0
- package/dist/esm/group/generated-types.js.map +1 -0
- package/dist/esm/group/index.d.ts +6 -0
- package/dist/esm/group/index.js +28 -0
- package/dist/esm/group/index.js.map +1 -0
- package/dist/esm/identify/generated-types.d.ts +6 -0
- package/dist/esm/identify/generated-types.js +2 -0
- package/dist/esm/identify/generated-types.js.map +1 -0
- package/dist/esm/identify/index.d.ts +6 -0
- package/dist/esm/identify/index.js +28 -0
- package/dist/esm/identify/index.js.map +1 -0
- package/dist/esm/index.d.ts +6 -0
- package/dist/esm/index.js +63 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/page/generated-types.d.ts +2 -0
- package/dist/esm/page/generated-types.js +2 -0
- package/dist/esm/page/generated-types.js.map +1 -0
- package/dist/esm/page/index.d.ts +6 -0
- package/dist/esm/page/index.js +12 -0
- package/dist/esm/page/index.js.map +1 -0
- package/dist/esm/track/generated-types.d.ts +6 -0
- package/dist/esm/track/generated-types.js +2 -0
- package/dist/esm/track/generated-types.js.map +1 -0
- package/dist/esm/track/index.d.ts +6 -0
- package/dist/esm/track/index.js +28 -0
- package/dist/esm/track/index.js.map +1 -0
- package/dist/esm/types.d.ts +18 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +24 -0
- package/src/__tests__/initialization.test.ts +83 -0
- package/src/constants.ts +4 -0
- package/src/generated-types.ts +16 -0
- package/src/group/__tests__/index.test.ts +119 -0
- package/src/group/generated-types.ts +14 -0
- package/src/group/index.ts +33 -0
- package/src/identify/__tests__/index.test.ts +119 -0
- package/src/identify/generated-types.ts +14 -0
- package/src/identify/index.ts +33 -0
- package/src/index.ts +71 -0
- package/src/page/__tests__/index.test.ts +63 -0
- package/src/page/generated-types.ts +3 -0
- package/src/page/index.ts +17 -0
- package/src/track/__tests__/index.test.ts +125 -0
- package/src/track/generated-types.ts +14 -0
- package/src/track/index.ts +33 -0
- package/src/types.ts +21 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { Analytics, Context } from '@segment/analytics-next'
|
|
2
|
+
import { Subscription } from '@segment/browser-destination-runtime'
|
|
3
|
+
import AppcuesDestination, { destination } from '../../index'
|
|
4
|
+
import { Appcues } from '../../types'
|
|
5
|
+
|
|
6
|
+
describe('Appcues.identify', () => {
|
|
7
|
+
const settings = {
|
|
8
|
+
accountID: 'test-account-id',
|
|
9
|
+
region: 'US' as const,
|
|
10
|
+
enableURLDetection: true
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let mockAppcues: Appcues
|
|
14
|
+
let event: any
|
|
15
|
+
|
|
16
|
+
beforeEach(async () => {
|
|
17
|
+
jest.restoreAllMocks()
|
|
18
|
+
jest.spyOn(destination, 'initialize').mockImplementation(() => {
|
|
19
|
+
mockAppcues = {
|
|
20
|
+
track: jest.fn(),
|
|
21
|
+
identify: jest.fn(),
|
|
22
|
+
group: jest.fn(),
|
|
23
|
+
page: jest.fn()
|
|
24
|
+
}
|
|
25
|
+
return Promise.resolve(mockAppcues)
|
|
26
|
+
})
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
test('identify() handled correctly', async () => {
|
|
30
|
+
const subscriptions: Subscription[] = [
|
|
31
|
+
{
|
|
32
|
+
partnerAction: 'identify',
|
|
33
|
+
name: 'Identify',
|
|
34
|
+
enabled: true,
|
|
35
|
+
subscribe: 'type = "identify"',
|
|
36
|
+
mapping: {
|
|
37
|
+
userId: { '@path': '$.userId' },
|
|
38
|
+
traits: { '@path': '$.traits' }
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
const context = new Context({
|
|
44
|
+
messageId: 'ajs-test-message-id',
|
|
45
|
+
type: 'identify',
|
|
46
|
+
anonymousId: 'anonymous-id-123',
|
|
47
|
+
userId: 'user-123',
|
|
48
|
+
traits: {
|
|
49
|
+
name: 'John Doe',
|
|
50
|
+
email: 'john@example.com',
|
|
51
|
+
plan: 'premium',
|
|
52
|
+
age: 30
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
const [identifyEvent] = await AppcuesDestination({
|
|
57
|
+
...settings,
|
|
58
|
+
subscriptions
|
|
59
|
+
})
|
|
60
|
+
event = identifyEvent
|
|
61
|
+
|
|
62
|
+
await event.load(Context.system(), {} as Analytics)
|
|
63
|
+
await event.identify?.(context)
|
|
64
|
+
|
|
65
|
+
expect(mockAppcues.identify).toHaveBeenCalledWith('user-123', {
|
|
66
|
+
name: 'John Doe',
|
|
67
|
+
email: 'john@example.com',
|
|
68
|
+
plan: 'premium',
|
|
69
|
+
age: 30
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
test('identify() handles nested traits and arrays', async () => {
|
|
74
|
+
const subscriptions: Subscription[] = [
|
|
75
|
+
{
|
|
76
|
+
partnerAction: 'identify',
|
|
77
|
+
name: 'Identify',
|
|
78
|
+
enabled: true,
|
|
79
|
+
subscribe: 'type = "identify"',
|
|
80
|
+
mapping: {
|
|
81
|
+
userId: { '@path': '$.userId' },
|
|
82
|
+
traits: { '@path': '$.traits' }
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
const context = new Context({
|
|
88
|
+
messageId: 'ajs-test-message-id',
|
|
89
|
+
type: 'identify',
|
|
90
|
+
userId: 'user-123',
|
|
91
|
+
traits: {
|
|
92
|
+
name: 'John Doe',
|
|
93
|
+
address: {
|
|
94
|
+
city: 'San Francisco',
|
|
95
|
+
state: 'CA'
|
|
96
|
+
},
|
|
97
|
+
tags: ['vip', 'beta']
|
|
98
|
+
}
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
const [identifyEvent] = await AppcuesDestination({
|
|
102
|
+
...settings,
|
|
103
|
+
subscriptions
|
|
104
|
+
})
|
|
105
|
+
event = identifyEvent
|
|
106
|
+
|
|
107
|
+
await event.load(Context.system(), {} as Analytics)
|
|
108
|
+
await event.identify?.(context)
|
|
109
|
+
|
|
110
|
+
expect(mockAppcues.identify).toHaveBeenCalledWith('user-123', {
|
|
111
|
+
name: 'John Doe',
|
|
112
|
+
address: {
|
|
113
|
+
city: 'San Francisco',
|
|
114
|
+
state: 'CA'
|
|
115
|
+
},
|
|
116
|
+
tags: ['vip', 'beta']
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
})
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Generated file. DO NOT MODIFY IT BY HAND.
|
|
2
|
+
|
|
3
|
+
export interface Payload {
|
|
4
|
+
/**
|
|
5
|
+
* The ID of the user to identify in Appcues.
|
|
6
|
+
*/
|
|
7
|
+
userId: string
|
|
8
|
+
/**
|
|
9
|
+
* Properties to associate with the user.
|
|
10
|
+
*/
|
|
11
|
+
traits?: {
|
|
12
|
+
[k: string]: unknown
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
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 type { Appcues } from '../types'
|
|
5
|
+
|
|
6
|
+
const action: BrowserActionDefinition<Settings, Appcues, Payload> = {
|
|
7
|
+
title: 'Identify',
|
|
8
|
+
description: 'Send Segment identify events to Appcues.',
|
|
9
|
+
platform: 'web',
|
|
10
|
+
fields: {
|
|
11
|
+
userId: {
|
|
12
|
+
label: 'User ID',
|
|
13
|
+
description: 'The ID of the user to identify in Appcues.',
|
|
14
|
+
required: true,
|
|
15
|
+
type: 'string',
|
|
16
|
+
default: { '@path': '$.userId' }
|
|
17
|
+
},
|
|
18
|
+
traits: {
|
|
19
|
+
label: 'User traits',
|
|
20
|
+
description: 'Properties to associate with the user.',
|
|
21
|
+
required: false,
|
|
22
|
+
type: 'object',
|
|
23
|
+
default: { '@path': '$.traits' }
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
defaultSubscription: 'type = "identify"',
|
|
27
|
+
perform: (appcues, { payload }) => {
|
|
28
|
+
const { userId, traits } = payload
|
|
29
|
+
appcues.identify(userId, traits)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default action
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
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 type { Appcues } from './types'
|
|
5
|
+
import track from './track'
|
|
6
|
+
import page from './page'
|
|
7
|
+
import identify from './identify'
|
|
8
|
+
import group from './group'
|
|
9
|
+
import { URL } from './constants'
|
|
10
|
+
import { defaultValues } from '@segment/actions-core'
|
|
11
|
+
|
|
12
|
+
export const destination: BrowserDestinationDefinition<Settings, Appcues> = {
|
|
13
|
+
name: 'Appcues Web',
|
|
14
|
+
slug: 'appcues-web-actions',
|
|
15
|
+
mode: 'device',
|
|
16
|
+
settings: {
|
|
17
|
+
accountID: {
|
|
18
|
+
label: 'Appcues Account ID',
|
|
19
|
+
description: 'Your Appcues Account ID.',
|
|
20
|
+
type: 'password',
|
|
21
|
+
required: true
|
|
22
|
+
},
|
|
23
|
+
region: {
|
|
24
|
+
label: 'Region',
|
|
25
|
+
description: 'Select the Appcues region for your account.',
|
|
26
|
+
type: 'string',
|
|
27
|
+
required: true,
|
|
28
|
+
choices: [
|
|
29
|
+
{ label: 'US', value: 'US' },
|
|
30
|
+
{ label: 'EU', value: 'EU' }
|
|
31
|
+
],
|
|
32
|
+
default: 'US'
|
|
33
|
+
},
|
|
34
|
+
enableURLDetection: {
|
|
35
|
+
label: 'Enable URL Detection',
|
|
36
|
+
description: 'Enable or disable URL detection in Appcues. If enabled, page events should not be triggered manually using the page action.',
|
|
37
|
+
type: 'boolean',
|
|
38
|
+
required: true,
|
|
39
|
+
default: false
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
initialize: async ({ settings }, deps) => {
|
|
43
|
+
const {
|
|
44
|
+
region,
|
|
45
|
+
accountID,
|
|
46
|
+
enableURLDetection
|
|
47
|
+
} = settings
|
|
48
|
+
const url = region === 'EU' ? URL.EU : URL.US
|
|
49
|
+
window.AppcuesSettings = { enableURLDetection }
|
|
50
|
+
await deps.loadScript(`//${url}/${accountID}.js`)
|
|
51
|
+
await deps.resolveWhen(() => Object.prototype.hasOwnProperty.call(window, 'Appcues'), 100)
|
|
52
|
+
return window.Appcues
|
|
53
|
+
},
|
|
54
|
+
presets: [
|
|
55
|
+
{
|
|
56
|
+
name: 'Page',
|
|
57
|
+
subscribe: 'type = "page"',
|
|
58
|
+
partnerAction: 'page',
|
|
59
|
+
mapping: defaultValues(page.fields),
|
|
60
|
+
type: 'automatic'
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
actions: {
|
|
64
|
+
track,
|
|
65
|
+
page,
|
|
66
|
+
identify,
|
|
67
|
+
group
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export default browserDestination(destination)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Analytics, Context } from '@segment/analytics-next'
|
|
2
|
+
import { Subscription } from '@segment/browser-destination-runtime'
|
|
3
|
+
import AppcuesDestination, { destination } from '../../index'
|
|
4
|
+
import { Appcues } from '../../types'
|
|
5
|
+
|
|
6
|
+
describe('Appcues.page', () => {
|
|
7
|
+
const settings = {
|
|
8
|
+
accountID: 'test-account-id',
|
|
9
|
+
region: 'US' as const,
|
|
10
|
+
enableURLDetection: true
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let mockAppcues: Appcues
|
|
14
|
+
let event: any
|
|
15
|
+
|
|
16
|
+
beforeEach(async () => {
|
|
17
|
+
jest.restoreAllMocks()
|
|
18
|
+
jest.spyOn(destination, 'initialize').mockImplementation(() => {
|
|
19
|
+
mockAppcues = {
|
|
20
|
+
track: jest.fn(),
|
|
21
|
+
identify: jest.fn(),
|
|
22
|
+
group: jest.fn(),
|
|
23
|
+
page: jest.fn()
|
|
24
|
+
}
|
|
25
|
+
return Promise.resolve(mockAppcues)
|
|
26
|
+
})
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
test('page() handled correctly', async () => {
|
|
30
|
+
const subscriptions: Subscription[] = [
|
|
31
|
+
{
|
|
32
|
+
partnerAction: 'page',
|
|
33
|
+
name: 'Page',
|
|
34
|
+
enabled: true,
|
|
35
|
+
subscribe: 'type = "page"',
|
|
36
|
+
mapping: {}
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
const context = new Context({
|
|
41
|
+
messageId: 'ajs-test-message-id',
|
|
42
|
+
type: 'page',
|
|
43
|
+
anonymousId: 'anonymous-id-123',
|
|
44
|
+
userId: 'user-123',
|
|
45
|
+
properties: {
|
|
46
|
+
url: 'https://example.com/home',
|
|
47
|
+
path: '/home',
|
|
48
|
+
title: 'Home Page'
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
const [pageEvent] = await AppcuesDestination({
|
|
53
|
+
...settings,
|
|
54
|
+
subscriptions
|
|
55
|
+
})
|
|
56
|
+
event = pageEvent
|
|
57
|
+
|
|
58
|
+
await event.load(Context.system(), {} as Analytics)
|
|
59
|
+
await event.page?.(context)
|
|
60
|
+
|
|
61
|
+
expect(mockAppcues.page).toHaveBeenCalled()
|
|
62
|
+
})
|
|
63
|
+
})
|
|
@@ -0,0 +1,17 @@
|
|
|
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 type { Appcues } from '../types'
|
|
5
|
+
|
|
6
|
+
const action: BrowserActionDefinition<Settings, Appcues, Payload> = {
|
|
7
|
+
title: 'Page',
|
|
8
|
+
description: 'Send Segment page events to Appcues.',
|
|
9
|
+
platform: 'web',
|
|
10
|
+
fields: {},
|
|
11
|
+
defaultSubscription: 'type = "page"',
|
|
12
|
+
perform: (appcues) => {
|
|
13
|
+
appcues.page()
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default action
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { Analytics, Context } from '@segment/analytics-next'
|
|
2
|
+
import { Subscription } from '@segment/browser-destination-runtime'
|
|
3
|
+
import AppcuesDestination, { destination } from '../../index'
|
|
4
|
+
import { Appcues } from '../../types'
|
|
5
|
+
|
|
6
|
+
describe('Appcues.track', () => {
|
|
7
|
+
const settings = {
|
|
8
|
+
accountID: 'test-account-id',
|
|
9
|
+
region: 'US' as const,
|
|
10
|
+
enableURLDetection: true
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let mockAppcues: Appcues
|
|
14
|
+
let event: any
|
|
15
|
+
|
|
16
|
+
beforeEach(async () => {
|
|
17
|
+
jest.restoreAllMocks()
|
|
18
|
+
jest.spyOn(destination, 'initialize').mockImplementation(() => {
|
|
19
|
+
mockAppcues = {
|
|
20
|
+
track: jest.fn(),
|
|
21
|
+
identify: jest.fn(),
|
|
22
|
+
group: jest.fn(),
|
|
23
|
+
page: jest.fn()
|
|
24
|
+
}
|
|
25
|
+
return Promise.resolve(mockAppcues)
|
|
26
|
+
})
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
test('track() handled correctly', async () => {
|
|
30
|
+
const subscriptions: Subscription[] = [
|
|
31
|
+
{
|
|
32
|
+
partnerAction: 'track',
|
|
33
|
+
name: 'Track',
|
|
34
|
+
enabled: true,
|
|
35
|
+
subscribe: 'type = "track"',
|
|
36
|
+
mapping: {
|
|
37
|
+
event: { '@path': '$.event' },
|
|
38
|
+
properties: { '@path': '$.properties' }
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
const context = new Context({
|
|
44
|
+
messageId: 'ajs-test-message-id',
|
|
45
|
+
type: 'track',
|
|
46
|
+
event: 'Button Clicked',
|
|
47
|
+
anonymousId: 'anonymous-id-123',
|
|
48
|
+
userId: 'user-123',
|
|
49
|
+
properties: {
|
|
50
|
+
buttonName: 'Sign Up',
|
|
51
|
+
color: 'blue',
|
|
52
|
+
position: 'header'
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
const [trackEvent] = await AppcuesDestination({
|
|
57
|
+
...settings,
|
|
58
|
+
subscriptions
|
|
59
|
+
})
|
|
60
|
+
event = trackEvent
|
|
61
|
+
|
|
62
|
+
await event.load(Context.system(), {} as Analytics)
|
|
63
|
+
await event.track?.(context)
|
|
64
|
+
|
|
65
|
+
expect(mockAppcues.track).toHaveBeenCalledWith('Button Clicked', {
|
|
66
|
+
buttonName: 'Sign Up',
|
|
67
|
+
color: 'blue',
|
|
68
|
+
position: 'header'
|
|
69
|
+
})
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
test('track() handles nested properties and arrays', async () => {
|
|
73
|
+
const subscriptions: Subscription[] = [
|
|
74
|
+
{
|
|
75
|
+
partnerAction: 'track',
|
|
76
|
+
name: 'Track',
|
|
77
|
+
enabled: true,
|
|
78
|
+
subscribe: 'type = "track"',
|
|
79
|
+
mapping: {
|
|
80
|
+
event: { '@path': '$.event' },
|
|
81
|
+
properties: { '@path': '$.properties' }
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
const context = new Context({
|
|
87
|
+
messageId: 'ajs-test-message-id',
|
|
88
|
+
type: 'track',
|
|
89
|
+
event: 'Purchase Completed',
|
|
90
|
+
userId: 'user-123',
|
|
91
|
+
properties: {
|
|
92
|
+
total: 99.99,
|
|
93
|
+
items: [
|
|
94
|
+
{ name: 'Product A', price: 49.99 },
|
|
95
|
+
{ name: 'Product B', price: 50.00 }
|
|
96
|
+
],
|
|
97
|
+
shipping: {
|
|
98
|
+
method: 'express',
|
|
99
|
+
cost: 10
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
const [trackEvent] = await AppcuesDestination({
|
|
105
|
+
...settings,
|
|
106
|
+
subscriptions
|
|
107
|
+
})
|
|
108
|
+
event = trackEvent
|
|
109
|
+
|
|
110
|
+
await event.load(Context.system(), {} as Analytics)
|
|
111
|
+
await event.track?.(context)
|
|
112
|
+
|
|
113
|
+
expect(mockAppcues.track).toHaveBeenCalledWith('Purchase Completed', {
|
|
114
|
+
total: 99.99,
|
|
115
|
+
items: [
|
|
116
|
+
{ name: 'Product A', price: 49.99 },
|
|
117
|
+
{ name: 'Product B', price: 50.00 }
|
|
118
|
+
],
|
|
119
|
+
shipping: {
|
|
120
|
+
method: 'express',
|
|
121
|
+
cost: 10
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
})
|
|
125
|
+
})
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Generated file. DO NOT MODIFY IT BY HAND.
|
|
2
|
+
|
|
3
|
+
export interface Payload {
|
|
4
|
+
/**
|
|
5
|
+
* The name of the event to track in Appcues.
|
|
6
|
+
*/
|
|
7
|
+
event: string
|
|
8
|
+
/**
|
|
9
|
+
* Properties to associate with the event.
|
|
10
|
+
*/
|
|
11
|
+
properties?: {
|
|
12
|
+
[k: string]: unknown
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
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 type { Appcues } from '../types'
|
|
5
|
+
|
|
6
|
+
const action: BrowserActionDefinition<Settings, Appcues, Payload> = {
|
|
7
|
+
title: 'Track',
|
|
8
|
+
description: 'Send Segment track events to Appcues.',
|
|
9
|
+
platform: 'web',
|
|
10
|
+
fields: {
|
|
11
|
+
event: {
|
|
12
|
+
label: 'Event Name',
|
|
13
|
+
description: 'The name of the event to track in Appcues.',
|
|
14
|
+
required: true,
|
|
15
|
+
type: 'string',
|
|
16
|
+
default: { '@path': '$.event' }
|
|
17
|
+
},
|
|
18
|
+
properties: {
|
|
19
|
+
label: 'Event Properties',
|
|
20
|
+
description: 'Properties to associate with the event.',
|
|
21
|
+
required: false,
|
|
22
|
+
type: 'object',
|
|
23
|
+
default: { '@path': '$.properties' }
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
defaultSubscription: 'type = "track"',
|
|
27
|
+
perform: (appcues, { payload }) => {
|
|
28
|
+
const { event, properties } = payload
|
|
29
|
+
appcues.track(event, properties)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default action
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
interface Window {
|
|
3
|
+
Appcues: Appcues
|
|
4
|
+
AppcuesSettings: AppcuesSettings
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface Appcues {
|
|
9
|
+
track(event_name: string, properties?: Properties): void
|
|
10
|
+
identify(userId: string, traits?: Properties): void
|
|
11
|
+
group(groupId: string, traits?: Properties): void
|
|
12
|
+
page(): void
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface AppcuesSettings {
|
|
16
|
+
enableURLDetection: boolean
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type Properties = {
|
|
20
|
+
[k: string]: unknown
|
|
21
|
+
}
|