@segment/analytics-browser-actions-vwo 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 +43 -0
- package/src/generated-types.ts +24 -0
- package/src/identifyUser/__tests__/index.test.ts +63 -0
- package/src/identifyUser/generated-types.ts +10 -0
- package/src/identifyUser/index.ts +40 -0
- package/src/index.ts +93 -0
- package/src/init-script.ts +81 -0
- package/src/trackEvent/__tests__/index.test.ts +86 -0
- package/src/trackEvent/generated-types.ts +14 -0
- package/src/trackEvent/index.ts +52 -0
- package/src/types.ts +9 -0
- package/src/utility.ts +11 -0
- package/tsconfig.json +9 -0
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@segment/analytics-browser-actions-vwo",
|
|
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:cjs": "tsc --module commonjs --outDir ./dist/cjs",
|
|
10
|
+
"build:esm": "tsc --outDir ./dist/esm"
|
|
11
|
+
},
|
|
12
|
+
"typings": "./dist/esm",
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@segment/actions-core": "^3.71.0",
|
|
15
|
+
"@segment/browser-destination-runtime": "^1.0.0"
|
|
16
|
+
},
|
|
17
|
+
"peerDependencies": {
|
|
18
|
+
"@segment/analytics-next": "*"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Subscription } from '@segment/browser-destination-runtime/types'
|
|
2
|
+
import { Analytics, Context } from '@segment/analytics-next'
|
|
3
|
+
import vwoDestination, { destination } from '../index'
|
|
4
|
+
|
|
5
|
+
const subscriptions: Subscription[] = [
|
|
6
|
+
{
|
|
7
|
+
partnerAction: 'trackEvent',
|
|
8
|
+
name: 'Show',
|
|
9
|
+
enabled: true,
|
|
10
|
+
subscribe: 'type = "track"',
|
|
11
|
+
mapping: {
|
|
12
|
+
eventName: {
|
|
13
|
+
'@path': '$.event'
|
|
14
|
+
},
|
|
15
|
+
properties: {
|
|
16
|
+
'@path': '$.properties'
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
describe('VWO Web (Actions)', () => {
|
|
23
|
+
test('Loads VWO SmartCode with AccountID', async () => {
|
|
24
|
+
const [vwo] = await vwoDestination({
|
|
25
|
+
vwoAccountId: 654331,
|
|
26
|
+
addSmartcode: true,
|
|
27
|
+
subscriptions
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
jest.spyOn(destination, 'initialize')
|
|
31
|
+
|
|
32
|
+
await vwo.load(Context.system(), {} as Analytics)
|
|
33
|
+
expect(destination.initialize).toHaveBeenCalled()
|
|
34
|
+
|
|
35
|
+
const vwoObject = window.VWO
|
|
36
|
+
expect(vwoObject).toBeDefined()
|
|
37
|
+
|
|
38
|
+
const script = window.document.querySelector(
|
|
39
|
+
'script[src~="https://dev.visualwebsiteoptimizer.com/j.php?a=654331]'
|
|
40
|
+
) as HTMLScriptElement
|
|
41
|
+
expect(script).toBeDefined()
|
|
42
|
+
})
|
|
43
|
+
})
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Generated file. DO NOT MODIFY IT BY HAND.
|
|
2
|
+
|
|
3
|
+
export interface Settings {
|
|
4
|
+
/**
|
|
5
|
+
* Your VWO account ID, used for fetching your VWO async smart code.
|
|
6
|
+
*/
|
|
7
|
+
vwoAccountId: number
|
|
8
|
+
/**
|
|
9
|
+
* The maximum amount of time (in milliseconds) to wait for test settings before VWO will simply display your original page.
|
|
10
|
+
*/
|
|
11
|
+
settingsTolerance?: number
|
|
12
|
+
/**
|
|
13
|
+
* The maximum amount of time (in milliseconds) to wait for VWO’s full library to be downloaded before simply displaying your original page.
|
|
14
|
+
*/
|
|
15
|
+
libraryTolerance?: number
|
|
16
|
+
/**
|
|
17
|
+
* If your page already includes JQuery, you can set this to “true”. Otherwise, VWO will include JQuery onto the page for you. VWO needs JQuery on the page to function correctly.
|
|
18
|
+
*/
|
|
19
|
+
useExistingJquery?: boolean
|
|
20
|
+
/**
|
|
21
|
+
* When enabled, Segment will load the VWO SmartCode onto the webpage. When disabled, you will have to manually add SmartCode to your webpage. The setting is enabled by default, however we recommended manually adding SmartCode to the webpage to avoid flicker issues.
|
|
22
|
+
*/
|
|
23
|
+
addSmartcode?: boolean
|
|
24
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Analytics, Context } from '@segment/analytics-next'
|
|
2
|
+
import { Subscription } from '@segment/browser-destination-runtime'
|
|
3
|
+
import vwoDestination, { destination } from '../../index'
|
|
4
|
+
|
|
5
|
+
const subscriptions: Subscription[] = [
|
|
6
|
+
{
|
|
7
|
+
partnerAction: 'identifyUser',
|
|
8
|
+
name: 'Identify User',
|
|
9
|
+
enabled: true,
|
|
10
|
+
subscribe: 'type = "identify"',
|
|
11
|
+
mapping: {
|
|
12
|
+
attributes: {
|
|
13
|
+
'@path': '$.traits'
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
describe('VWO.identifyUser', () => {
|
|
20
|
+
const settings = {
|
|
21
|
+
vwoAccountId: 654331
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let identifyUser: any
|
|
25
|
+
beforeEach(async () => {
|
|
26
|
+
jest.restoreAllMocks()
|
|
27
|
+
|
|
28
|
+
const [identifyUserPlugin] = await vwoDestination({
|
|
29
|
+
...settings,
|
|
30
|
+
subscriptions
|
|
31
|
+
})
|
|
32
|
+
identifyUser = identifyUserPlugin
|
|
33
|
+
|
|
34
|
+
jest.spyOn(destination, 'initialize').mockImplementation(() => {
|
|
35
|
+
window.VWO = {
|
|
36
|
+
push: jest.fn(),
|
|
37
|
+
event: jest.fn(),
|
|
38
|
+
visitor: jest.fn()
|
|
39
|
+
}
|
|
40
|
+
return Promise.resolve(window.VWO)
|
|
41
|
+
})
|
|
42
|
+
await identifyUser.load(Context.system(), {} as Analytics)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
test('Visitor call with attributes', async () => {
|
|
46
|
+
const context = new Context({
|
|
47
|
+
type: 'identify',
|
|
48
|
+
traits: {
|
|
49
|
+
textAttribute: 'Hello'
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
await identifyUser.identify?.(context)
|
|
53
|
+
|
|
54
|
+
expect(window.VWO.visitor).toHaveBeenCalledWith(
|
|
55
|
+
{
|
|
56
|
+
'segment.textAttribute': 'Hello'
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
source: 'segment.web'
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
})
|
|
63
|
+
})
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { BrowserActionDefinition } from '@segment/browser-destination-runtime/types'
|
|
2
|
+
import type { VWO } from '../types'
|
|
3
|
+
import type { Settings } from '../generated-types'
|
|
4
|
+
import type { Payload } from './generated-types'
|
|
5
|
+
import { formatAttributes } from '../utility'
|
|
6
|
+
|
|
7
|
+
// Change from unknown to the partner SDK types
|
|
8
|
+
const action: BrowserActionDefinition<Settings, VWO, Payload> = {
|
|
9
|
+
title: 'Identify User',
|
|
10
|
+
description: `Sends Segment's page event to VWO`,
|
|
11
|
+
defaultSubscription: 'type = "identify"',
|
|
12
|
+
platform: 'web',
|
|
13
|
+
fields: {
|
|
14
|
+
attributes: {
|
|
15
|
+
description: 'JSON object containing additional attributes that will be associated with the user.',
|
|
16
|
+
label: 'Attributes',
|
|
17
|
+
required: true,
|
|
18
|
+
type: 'object',
|
|
19
|
+
default: {
|
|
20
|
+
'@path': '$.traits'
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
perform: (_, event) => {
|
|
25
|
+
const { attributes } = event.payload
|
|
26
|
+
const formattedAttributes = formatAttributes(attributes)
|
|
27
|
+
|
|
28
|
+
window.VWO = window.VWO || []
|
|
29
|
+
|
|
30
|
+
if (!window.VWO.visitor) {
|
|
31
|
+
window.VWO.visitor = function (...args) {
|
|
32
|
+
window.VWO.push(['visitor', ...args])
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
window.VWO.visitor(formattedAttributes, { source: 'segment.web' })
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default action
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
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 { VWO } from './types'
|
|
5
|
+
import { initScript } from './init-script'
|
|
6
|
+
import { defaultValues } from '@segment/actions-core'
|
|
7
|
+
|
|
8
|
+
import trackEvent from './trackEvent'
|
|
9
|
+
import identifyUser from './identifyUser'
|
|
10
|
+
|
|
11
|
+
declare global {
|
|
12
|
+
interface Window {
|
|
13
|
+
VWO: VWO
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Switch from unknown to the partner SDK client types
|
|
18
|
+
export const destination: BrowserDestinationDefinition<Settings, VWO> = {
|
|
19
|
+
name: 'VWO Web Mode (Actions)',
|
|
20
|
+
slug: 'actions-vwo-web',
|
|
21
|
+
mode: 'device',
|
|
22
|
+
presets: [
|
|
23
|
+
{
|
|
24
|
+
name: 'Track Event',
|
|
25
|
+
subscribe: 'type = "track"',
|
|
26
|
+
partnerAction: 'trackEvent',
|
|
27
|
+
mapping: defaultValues(trackEvent.fields)
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'Identify User',
|
|
31
|
+
subscribe: 'type = "identify"',
|
|
32
|
+
partnerAction: 'identifyUser',
|
|
33
|
+
mapping: defaultValues(identifyUser.fields)
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
settings: {
|
|
37
|
+
// Add any Segment destination settings required here
|
|
38
|
+
vwoAccountId: {
|
|
39
|
+
description: 'Your VWO account ID, used for fetching your VWO async smart code.',
|
|
40
|
+
label: 'VWO Account ID',
|
|
41
|
+
type: 'number',
|
|
42
|
+
required: true
|
|
43
|
+
},
|
|
44
|
+
settingsTolerance: {
|
|
45
|
+
description:
|
|
46
|
+
'The maximum amount of time (in milliseconds) to wait for test settings before VWO will simply display your original page.',
|
|
47
|
+
label: 'Settings Tolerance',
|
|
48
|
+
type: 'number',
|
|
49
|
+
default: 2000
|
|
50
|
+
},
|
|
51
|
+
libraryTolerance: {
|
|
52
|
+
description:
|
|
53
|
+
'The maximum amount of time (in milliseconds) to wait for VWO’s full library to be downloaded before simply displaying your original page.',
|
|
54
|
+
label: 'Library Tolerance',
|
|
55
|
+
type: 'number',
|
|
56
|
+
default: 2500
|
|
57
|
+
},
|
|
58
|
+
useExistingJquery: {
|
|
59
|
+
description:
|
|
60
|
+
'If your page already includes JQuery, you can set this to “true”. Otherwise, VWO will include JQuery onto the page for you. VWO needs JQuery on the page to function correctly. ',
|
|
61
|
+
label: 'Use Existing JQuery',
|
|
62
|
+
type: 'boolean',
|
|
63
|
+
default: false
|
|
64
|
+
},
|
|
65
|
+
addSmartcode: {
|
|
66
|
+
description:
|
|
67
|
+
'When enabled, Segment will load the VWO SmartCode onto the webpage. When disabled, you will have to manually add SmartCode to your webpage. The setting is enabled by default, however we recommended manually adding SmartCode to the webpage to avoid flicker issues.',
|
|
68
|
+
label: 'Add Asynchronous SmartCode',
|
|
69
|
+
type: 'boolean',
|
|
70
|
+
default: true
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
initialize: async ({ settings }, deps) => {
|
|
75
|
+
if (settings.addSmartcode != false) {
|
|
76
|
+
initScript({
|
|
77
|
+
vwoAccountId: settings.vwoAccountId,
|
|
78
|
+
settingsTolerance: settings.settingsTolerance,
|
|
79
|
+
libraryTolerance: settings.libraryTolerance,
|
|
80
|
+
useExistingJquery: settings.useExistingJquery
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
await deps.resolveWhen(() => Object.prototype.hasOwnProperty.call(window, 'VWO'), 100)
|
|
84
|
+
return window.VWO
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
actions: {
|
|
88
|
+
trackEvent,
|
|
89
|
+
identifyUser
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export default browserDestination(destination)
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
|
|
4
|
+
export function initScript({
|
|
5
|
+
vwoAccountId,
|
|
6
|
+
settingsTolerance = 2000,
|
|
7
|
+
libraryTolerance = 2500,
|
|
8
|
+
useExistingJquery = false,
|
|
9
|
+
isSpa = 1
|
|
10
|
+
}) {
|
|
11
|
+
window._vwo_code =
|
|
12
|
+
window._vwo_code ||
|
|
13
|
+
(function () {
|
|
14
|
+
var account_id = vwoAccountId,
|
|
15
|
+
settings_tolerance = settingsTolerance,
|
|
16
|
+
library_tolerance = libraryTolerance,
|
|
17
|
+
use_existing_jquery = useExistingJquery,
|
|
18
|
+
is_spa = isSpa,
|
|
19
|
+
hide_element = 'body',
|
|
20
|
+
/* DO NOT EDIT BELOW THIS LINE */
|
|
21
|
+
f = false,
|
|
22
|
+
d = document,
|
|
23
|
+
code = {
|
|
24
|
+
use_existing_jquery: function () {
|
|
25
|
+
return use_existing_jquery
|
|
26
|
+
},
|
|
27
|
+
library_tolerance: function () {
|
|
28
|
+
return library_tolerance
|
|
29
|
+
},
|
|
30
|
+
finish: function () {
|
|
31
|
+
if (!f) {
|
|
32
|
+
f = true
|
|
33
|
+
var a = d.getElementById('_vis_opt_path_hides')
|
|
34
|
+
if (a) a.parentNode.removeChild(a)
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
finished: function () {
|
|
38
|
+
return f
|
|
39
|
+
},
|
|
40
|
+
load: function (a) {
|
|
41
|
+
var b = d.createElement('script')
|
|
42
|
+
b.src = a
|
|
43
|
+
b.type = 'text/javascript'
|
|
44
|
+
b.innerText
|
|
45
|
+
b.onerror = function () {
|
|
46
|
+
_vwo_code.finish()
|
|
47
|
+
}
|
|
48
|
+
d.getElementsByTagName('head')[0].appendChild(b)
|
|
49
|
+
},
|
|
50
|
+
init: function () {
|
|
51
|
+
window.settings_timer = setTimeout(function () {
|
|
52
|
+
_vwo_code.finish()
|
|
53
|
+
}, settings_tolerance)
|
|
54
|
+
var a = d.createElement('style'),
|
|
55
|
+
b = hide_element
|
|
56
|
+
? hide_element + '{opacity:0 !important;filter:alpha(opacity=0) !important;background:none !important;}'
|
|
57
|
+
: '',
|
|
58
|
+
h = d.getElementsByTagName('head')[0]
|
|
59
|
+
a.setAttribute('id', '_vis_opt_path_hides')
|
|
60
|
+
a.setAttribute('type', 'text/css')
|
|
61
|
+
if (a.styleSheet) a.styleSheet.cssText = b
|
|
62
|
+
else a.appendChild(d.createTextNode(b))
|
|
63
|
+
h.appendChild(a)
|
|
64
|
+
this.load(
|
|
65
|
+
'https://dev.visualwebsiteoptimizer.com/j.php?a=' +
|
|
66
|
+
account_id +
|
|
67
|
+
'&u=' +
|
|
68
|
+
encodeURIComponent(d.URL) +
|
|
69
|
+
'&f=' +
|
|
70
|
+
+is_spa +
|
|
71
|
+
'&r=' +
|
|
72
|
+
Math.random() +
|
|
73
|
+
'&s=segment.web'
|
|
74
|
+
)
|
|
75
|
+
return settings_timer
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
window._vwo_settings_timer = code.init()
|
|
79
|
+
return code
|
|
80
|
+
})()
|
|
81
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { Analytics, Context } from '@segment/analytics-next'
|
|
2
|
+
import { Subscription } from '@segment/browser-destination-runtime'
|
|
3
|
+
import vwoDestination, { destination } from '../../index'
|
|
4
|
+
|
|
5
|
+
const subscriptions: Subscription[] = [
|
|
6
|
+
{
|
|
7
|
+
partnerAction: 'trackEvent',
|
|
8
|
+
name: 'Show',
|
|
9
|
+
enabled: true,
|
|
10
|
+
subscribe: 'type = "track"',
|
|
11
|
+
mapping: {
|
|
12
|
+
eventName: {
|
|
13
|
+
'@path': '$.event'
|
|
14
|
+
},
|
|
15
|
+
properties: {
|
|
16
|
+
'@path': '$.properties'
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
describe('VWO.trackEvent', () => {
|
|
23
|
+
const settings = {
|
|
24
|
+
vwoAccountId: 654331
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let trackEvent: any
|
|
28
|
+
beforeEach(async () => {
|
|
29
|
+
jest.restoreAllMocks()
|
|
30
|
+
|
|
31
|
+
const [trackEventPlugin] = await vwoDestination({
|
|
32
|
+
...settings,
|
|
33
|
+
subscriptions
|
|
34
|
+
})
|
|
35
|
+
trackEvent = trackEventPlugin
|
|
36
|
+
|
|
37
|
+
jest.spyOn(destination, 'initialize').mockImplementation(() => {
|
|
38
|
+
window.VWO = {
|
|
39
|
+
push: jest.fn(),
|
|
40
|
+
event: jest.fn(),
|
|
41
|
+
visitor: jest.fn()
|
|
42
|
+
}
|
|
43
|
+
return Promise.resolve(window.VWO)
|
|
44
|
+
})
|
|
45
|
+
await trackEvent.load(Context.system(), {} as Analytics)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
test('Track call without parameters', async () => {
|
|
49
|
+
const context = new Context({
|
|
50
|
+
type: 'track',
|
|
51
|
+
event: 'ctaClick'
|
|
52
|
+
})
|
|
53
|
+
await trackEvent.track?.(context)
|
|
54
|
+
|
|
55
|
+
expect(window.VWO.event).toHaveBeenCalledWith(
|
|
56
|
+
'segment.ctaClick',
|
|
57
|
+
{},
|
|
58
|
+
{
|
|
59
|
+
source: 'segment.web',
|
|
60
|
+
ogName: 'ctaClick'
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
test('Track call with parameters', async () => {
|
|
66
|
+
const context = new Context({
|
|
67
|
+
type: 'track',
|
|
68
|
+
event: 'buyButtonClick',
|
|
69
|
+
properties: {
|
|
70
|
+
amount: 1000
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
await trackEvent.track?.(context)
|
|
74
|
+
|
|
75
|
+
expect(window.VWO.event).toHaveBeenCalledWith(
|
|
76
|
+
'segment.buyButtonClick',
|
|
77
|
+
{
|
|
78
|
+
amount: 1000
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
source: 'segment.web',
|
|
82
|
+
ogName: 'buyButtonClick'
|
|
83
|
+
}
|
|
84
|
+
)
|
|
85
|
+
})
|
|
86
|
+
})
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Generated file. DO NOT MODIFY IT BY HAND.
|
|
2
|
+
|
|
3
|
+
export interface Payload {
|
|
4
|
+
/**
|
|
5
|
+
* Name of the event.
|
|
6
|
+
*/
|
|
7
|
+
eventName: string
|
|
8
|
+
/**
|
|
9
|
+
* JSON object containing additional properties that will be associated with the event.
|
|
10
|
+
*/
|
|
11
|
+
properties?: {
|
|
12
|
+
[k: string]: unknown
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { BrowserActionDefinition } from '@segment/browser-destination-runtime/types'
|
|
2
|
+
import type { VWO } from '../types'
|
|
3
|
+
import type { Settings } from '../generated-types'
|
|
4
|
+
import type { Payload } from './generated-types'
|
|
5
|
+
import { sanitiseEventName } from '../utility'
|
|
6
|
+
|
|
7
|
+
// Change from unknown to the partner SDK types
|
|
8
|
+
const action: BrowserActionDefinition<Settings, VWO, Payload> = {
|
|
9
|
+
title: 'Track Event',
|
|
10
|
+
description: `Sends Segment's track event to VWO`,
|
|
11
|
+
platform: 'web',
|
|
12
|
+
defaultSubscription: 'type = "track"',
|
|
13
|
+
fields: {
|
|
14
|
+
eventName: {
|
|
15
|
+
description: 'Name of the event.',
|
|
16
|
+
label: 'Name',
|
|
17
|
+
required: true,
|
|
18
|
+
type: 'string',
|
|
19
|
+
default: {
|
|
20
|
+
'@path': '$.event'
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
properties: {
|
|
24
|
+
description: 'JSON object containing additional properties that will be associated with the event.',
|
|
25
|
+
label: 'Properties',
|
|
26
|
+
required: false,
|
|
27
|
+
type: 'object',
|
|
28
|
+
default: {
|
|
29
|
+
'@path': '$.properties'
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
perform: (_, event) => {
|
|
34
|
+
const { eventName, properties } = event.payload
|
|
35
|
+
const sanitisedEventName = sanitiseEventName(eventName)
|
|
36
|
+
const formattedProperties = { ...properties }
|
|
37
|
+
|
|
38
|
+
window.VWO = window.VWO || []
|
|
39
|
+
|
|
40
|
+
if (!window.VWO.event) {
|
|
41
|
+
window.VWO.event = function (...args) {
|
|
42
|
+
window.VWO.push(['event', ...args])
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
window.VWO.event(sanitisedEventName, formattedProperties, {
|
|
46
|
+
source: 'segment.web',
|
|
47
|
+
ogName: eventName
|
|
48
|
+
})
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default action
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type VWO = {
|
|
2
|
+
event: (
|
|
3
|
+
event: string,
|
|
4
|
+
properties: { [k: string]: unknown } | undefined,
|
|
5
|
+
vwoMeta: { [k: string]: unknown } | undefined
|
|
6
|
+
) => void
|
|
7
|
+
visitor: (attributes: { [k: string]: unknown }, vwoMeta: { [k: string]: unknown } | undefined) => void
|
|
8
|
+
push: (args: (string | { [k: string]: unknown } | undefined)[]) => void
|
|
9
|
+
}
|
package/src/utility.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function formatAttributes(attributes: { [k: string]: unknown }) {
|
|
2
|
+
const formattedAttributes: { [k: string]: unknown } = {}
|
|
3
|
+
for (const key in attributes) {
|
|
4
|
+
formattedAttributes[`segment.${key}`] = attributes[key]
|
|
5
|
+
}
|
|
6
|
+
return formattedAttributes
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function sanitiseEventName(name: string) {
|
|
10
|
+
return 'segment.' + name
|
|
11
|
+
}
|