@segment/analytics-browser-actions-friendbuy 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 ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "@segment/analytics-browser-actions-friendbuy",
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/actions-shared": "^1.53.0",
16
+ "@segment/browser-destination-runtime": "^1.0.0"
17
+ },
18
+ "peerDependencies": {
19
+ "@segment/analytics-next": "*"
20
+ }
21
+ }
@@ -0,0 +1,38 @@
1
+ import { Analytics, Context } from '@segment/analytics-next'
2
+ import friendbuyDestination, { destination } from '../index'
3
+ import nock from 'nock'
4
+
5
+ const subscriptions = [
6
+ {
7
+ partnerAction: 'trackCustomer',
8
+ name: 'Track Customer',
9
+ enabled: true,
10
+ subscribe: 'type = "identify"',
11
+ mapping: {}
12
+ }
13
+ ]
14
+
15
+ describe('Friendbuy', () => {
16
+ const merchantId = '0ebece2e-b04c-4504-97f2-16cd9f423612'
17
+
18
+ test('loading', async () => {
19
+ jest.spyOn(destination, 'initialize')
20
+
21
+ nock('https://static.fbot.me').get('/friendbuy.js').reply(200, {})
22
+ nock('https://campaign.fbot.me')
23
+ .get(/^\/[^/]*\/campaigns.js$/)
24
+ .reply(200, {})
25
+
26
+ const [event] = await friendbuyDestination({
27
+ merchantId,
28
+ subscriptions
29
+ })
30
+
31
+ await event.load(Context.system(), {} as Analytics)
32
+ expect(destination.initialize).toHaveBeenCalled()
33
+
34
+ const expectedFriendbuyAPI = [['merchant', merchantId]] as any
35
+ expectedFriendbuyAPI.merchantId = merchantId
36
+ expect(window.friendbuyAPI).toEqual(expectedFriendbuyAPI)
37
+ })
38
+ })
@@ -0,0 +1,8 @@
1
+ // Generated file. DO NOT MODIFY IT BY HAND.
2
+
3
+ export interface Settings {
4
+ /**
5
+ * Find your Friendbuy Merchant ID by logging in to your [Friendbuy account](https://retailer.friendbuy.io/) and going to Developer Center > Friendbuy Code.
6
+ */
7
+ merchantId: string
8
+ }
package/src/index.ts ADDED
@@ -0,0 +1,91 @@
1
+ import type { BrowserDestinationDefinition } from '@segment/browser-destination-runtime/types'
2
+ import type { DestinationDefinition } from '@segment/actions-core'
3
+ import { browserDestination } from '@segment/browser-destination-runtime/shim'
4
+ import { defaultValues } from '@segment/actions-core'
5
+
6
+ import type { Settings } from './generated-types'
7
+ import type { FriendbuyAPI } from './types'
8
+ import trackCustomer, { trackCustomerDefaultSubscription } from './trackCustomer'
9
+ import trackPurchase, { browserTrackPurchaseFields, trackPurchaseDefaultSubscription } from './trackPurchase'
10
+ import trackSignUp, { browserTrackSignUpFields, trackSignUpDefaultSubscription } from './trackSignUp'
11
+ import trackPage, { trackPageDefaultSubscription, trackPageFields } from './trackPage'
12
+ import trackCustomEvent from './trackCustomEvent'
13
+ import { trackCustomerFields } from '@segment/actions-shared'
14
+
15
+ declare global {
16
+ interface Window {
17
+ friendbuyAPI?: FriendbuyAPI
18
+ friendbuyBaseHost?: string
19
+ }
20
+ }
21
+
22
+ // Presets are shown in Segment configuration flow as "Pre-Built Subscriptions".
23
+ const presets: DestinationDefinition['presets'] = [
24
+ {
25
+ name: 'Track Customer',
26
+ subscribe: trackCustomerDefaultSubscription,
27
+ partnerAction: 'trackCustomer',
28
+ mapping: defaultValues(trackCustomerFields)
29
+ },
30
+ {
31
+ name: 'Track Purchase',
32
+ subscribe: trackPurchaseDefaultSubscription,
33
+ partnerAction: 'trackPurchase',
34
+ mapping: defaultValues(browserTrackPurchaseFields)
35
+ },
36
+ {
37
+ name: 'Track Sign Up',
38
+ subscribe: trackSignUpDefaultSubscription,
39
+ partnerAction: 'trackSignUp',
40
+ mapping: defaultValues(browserTrackSignUpFields)
41
+ },
42
+ {
43
+ name: 'Track Page',
44
+ subscribe: trackPageDefaultSubscription,
45
+ partnerAction: 'trackPage',
46
+ mapping: defaultValues(trackPageFields)
47
+ }
48
+ ]
49
+
50
+ export const destination: BrowserDestinationDefinition<Settings, FriendbuyAPI> = {
51
+ name: 'Friendbuy (Actions)',
52
+ slug: 'actions-friendbuy',
53
+ mode: 'device',
54
+
55
+ settings: {
56
+ merchantId: {
57
+ label: 'Friendbuy Merchant ID',
58
+ description:
59
+ 'Find your Friendbuy Merchant ID by logging in to your [Friendbuy account](https://retailer.friendbuy.io/) and going to Developer Center > Friendbuy Code.',
60
+ type: 'string',
61
+ format: 'uuid',
62
+ required: true
63
+ }
64
+ },
65
+
66
+ initialize: async ({ settings /* , analytics */ }, dependencies) => {
67
+ let friendbuyAPI: FriendbuyAPI
68
+ window.friendbuyAPI = friendbuyAPI = window.friendbuyAPI || ([] as unknown as FriendbuyAPI)
69
+ const friendbuyBaseHost = window.friendbuyBaseHost ?? 'fbot.me'
70
+
71
+ friendbuyAPI.merchantId = settings.merchantId
72
+ friendbuyAPI.push(['merchant', settings.merchantId])
73
+
74
+ // The Friendbuy JavaScript can be loaded asynchronously.
75
+ void dependencies.loadScript(`https://static.${friendbuyBaseHost}/friendbuy.js`)
76
+ void dependencies.loadScript(`https://campaign.${friendbuyBaseHost}/${settings.merchantId}/campaigns.js`)
77
+
78
+ return friendbuyAPI
79
+ },
80
+
81
+ presets,
82
+ actions: {
83
+ trackCustomer,
84
+ trackPurchase,
85
+ trackSignUp,
86
+ trackPage,
87
+ trackCustomEvent
88
+ }
89
+ }
90
+
91
+ export default browserDestination(destination)
@@ -0,0 +1,98 @@
1
+ import { Analytics, Context } from '@segment/analytics-next'
2
+ import friendbuyDestination from '../../index'
3
+ import trackCustomEventObject, { browserTrackCustomEventFields } from '../index'
4
+
5
+ import { loadScript } from '@segment/browser-destination-runtime/load-script'
6
+ jest.mock('@segment/browser-destination-runtime/load-script')
7
+ beforeEach(async () => {
8
+ // Prevent friendbuy.js and campaigns.js from being loaded.
9
+ ;(loadScript as jest.Mock).mockResolvedValue(true)
10
+ })
11
+
12
+ describe('Friendbuy.trackCustomEvent', () => {
13
+ const subscriptions = [
14
+ {
15
+ partnerAction: 'trackCustomEvent',
16
+ name: trackCustomEventObject.title,
17
+ enabled: true,
18
+ subscribe: 'type = "track" and event = "download"',
19
+ mapping: Object.fromEntries(
20
+ Object.entries(browserTrackCustomEventFields).map(([name, value]) => [name, value.default])
21
+ )
22
+ }
23
+ ]
24
+
25
+ test('all fields', async () => {
26
+ const merchantId = '1993d0f1-8206-4336-8c88-64e170f2419e'
27
+
28
+ const [trackCustomEvent] = await friendbuyDestination({
29
+ merchantId,
30
+ subscriptions
31
+ })
32
+ // console.log('trackCustomEvent', JSON.stringify(trackCustomEvent, null, 2), trackCustomEvent)
33
+ expect(trackCustomEvent).toBeDefined()
34
+
35
+ await trackCustomEvent.load(Context.system(), {} as Analytics)
36
+
37
+ // console.log(window.friendbuyAPI)
38
+ jest.spyOn(window.friendbuyAPI as any, 'push')
39
+
40
+ {
41
+ // Non-download events are not sent.
42
+ const context1 = new Context({
43
+ type: 'track',
44
+ event: 'upload',
45
+ properties: { type: 'application', fileId: 'MyApp', deduplicationId: '1234' }
46
+ })
47
+
48
+ trackCustomEvent.track?.(context1)
49
+
50
+ expect(window.friendbuyAPI?.push).not.toHaveBeenCalled()
51
+ }
52
+
53
+ {
54
+ // Download events are sent.
55
+ const context2 = new Context({
56
+ type: 'track',
57
+ event: 'download',
58
+ properties: { type: 'application', fileId: 'MyApp', deduplicationId: '1234' }
59
+ })
60
+
61
+ trackCustomEvent.track?.(context2)
62
+
63
+ expect(window.friendbuyAPI?.push).toHaveBeenNthCalledWith(1, [
64
+ 'track',
65
+ 'download',
66
+ { type: 'application', fileId: 'MyApp', deduplicationId: '1234' }
67
+ ])
68
+ }
69
+
70
+ {
71
+ // Customer is sent if customer fields are present.
72
+ const userId = 'john-doe-1234'
73
+ const anonymousId = '960efa33-6d3b-4eb9-a4e7-d95412d9829e'
74
+ const email = 'john.doe@example.com'
75
+ const firstName = 'John'
76
+ const lastName = 'Doe'
77
+ const context3 = new Context({
78
+ type: 'track',
79
+ event: 'download',
80
+ userId,
81
+ anonymousId,
82
+ properties: { type: 'application', fileId: 'MyApp', email, firstName, lastName }
83
+ })
84
+
85
+ trackCustomEvent.track?.(context3)
86
+
87
+ expect(window.friendbuyAPI?.push).toHaveBeenNthCalledWith(2, [
88
+ 'track',
89
+ 'download',
90
+ {
91
+ type: 'application',
92
+ fileId: 'MyApp',
93
+ customer: { id: userId, anonymousId, email, firstName, lastName, name: `${firstName} ${lastName}` }
94
+ }
95
+ ])
96
+ }
97
+ })
98
+ })
@@ -0,0 +1,30 @@
1
+ // Generated file. DO NOT MODIFY IT BY HAND.
2
+
3
+ export interface Payload {
4
+ /**
5
+ * The type of the event to track.
6
+ */
7
+ eventType: string
8
+ /**
9
+ * Object containing the properties for the event being tracked. All of the fields in this object will be sent in the root of the Friendbuy track event.
10
+ */
11
+ eventProperties: {
12
+ [k: string]: unknown
13
+ }
14
+ /**
15
+ * An identifier for the event being tracked to prevent the same event from being rewarded more than once.
16
+ */
17
+ deduplicationId?: string
18
+ /**
19
+ * The user's customer ID.
20
+ */
21
+ customerId: string
22
+ /**
23
+ * The user's anonymous id
24
+ */
25
+ anonymousId?: string
26
+ /**
27
+ * The user's email address.
28
+ */
29
+ email?: string
30
+ }
@@ -0,0 +1,49 @@
1
+ import type { BrowserActionDefinition } from '@segment/browser-destination-runtime/types'
2
+
3
+ import type { FriendbuyAPI } from '../types'
4
+ import type { Settings } from '../generated-types'
5
+ import type { Payload } from './generated-types'
6
+ import type { ConvertFun, EventMap } from '@segment/actions-shared'
7
+
8
+ import { AnalyticsPayload, COPY, DROP, ROOT, mapEvent } from '@segment/actions-shared'
9
+ import { trackCustomEventFields } from '@segment/actions-shared'
10
+ import { addName, enjoinInteger, enjoinString, moveEventPropertiesToRoot, parseDate } from '@segment/actions-shared'
11
+
12
+ export const browserTrackCustomEventFields = trackCustomEventFields({}) // @@ email required?
13
+
14
+ const trackCustomEventPub: EventMap = {
15
+ fields: {
16
+ eventType: DROP,
17
+ deduplicationId: COPY,
18
+
19
+ // CUSTOMER FIELDS
20
+ customerId: { name: ['customer', 'id'], convert: enjoinString as ConvertFun },
21
+ anonymousId: { name: ['customer', 'anonymousId'] },
22
+ email: { name: ['customer', 'email'] },
23
+ isNewCustomer: { name: ['customer', 'isNewCustomer'] },
24
+ loyaltyStatus: { name: ['customer', 'loyaltyStatus'] },
25
+ firstName: { name: ['customer', 'firstName'] },
26
+ lastName: { name: ['customer', 'lastName'] },
27
+ name: { name: ['customer', 'name'] },
28
+ age: { name: ['customer', 'age'], convert: enjoinInteger as ConvertFun },
29
+ birthday: { name: ['customer', 'birthday'], convert: parseDate as ConvertFun }
30
+ },
31
+ unmappedFieldObject: ROOT
32
+ }
33
+
34
+ const action: BrowserActionDefinition<Settings, FriendbuyAPI, Payload> = {
35
+ title: 'Track Custom Event',
36
+ description: 'Record when a customer completes any custom event that you define.',
37
+ // trackCustomEvent has no default subscription.
38
+ platform: 'web',
39
+ fields: browserTrackCustomEventFields,
40
+
41
+ perform: (friendbuyAPI, { payload }) => {
42
+ const analyticsPayload = moveEventPropertiesToRoot(payload as unknown as AnalyticsPayload)
43
+ addName(analyticsPayload)
44
+ const friendbuyPayload = mapEvent(trackCustomEventPub, analyticsPayload)
45
+ friendbuyAPI.push(['track', payload.eventType, friendbuyPayload])
46
+ }
47
+ }
48
+
49
+ export default action
@@ -0,0 +1,196 @@
1
+ import { Analytics, Context } from '@segment/analytics-next'
2
+ import friendbuyDestination from '../../index'
3
+ import trackCustomerObject, { trackCustomerDefaultSubscription } from '../index'
4
+ import { trackCustomerFields } from '@segment/actions-shared'
5
+
6
+ import { loadScript } from '@segment/browser-destination-runtime/load-script'
7
+ jest.mock('@segment/browser-destination-runtime/load-script')
8
+ beforeEach(async () => {
9
+ // Prevent friendbuy.js and campaigns.js from being loaded.
10
+ ;(loadScript as jest.Mock).mockResolvedValue(true)
11
+ })
12
+
13
+ describe('Friendbuy.trackCustomer', () => {
14
+ // console.log('trackCustomer', JSON.stringify(trackCustomer, null, 2))
15
+
16
+ const subscriptions = [
17
+ {
18
+ partnerAction: 'trackCustomer',
19
+ name: trackCustomerObject.title,
20
+ enabled: true,
21
+ subscribe: trackCustomerDefaultSubscription,
22
+ mapping: Object.fromEntries(
23
+ Object.entries(trackCustomerFields)
24
+ .map(([name, value]) => [name, value.default])
25
+ .concat(
26
+ ['customerSince', 'loyaltyStatus', 'isNewCustomer'].map((name) => [name, { '@path': `$.traits.${name}` }])
27
+ )
28
+ )
29
+ }
30
+ ]
31
+
32
+ // console.log('subscriptions', JSON.stringify(subscriptions, null, 2))
33
+
34
+ test('all fields', async () => {
35
+ const merchantId = '1993d0f1-8206-4336-8c88-64e170f2419e'
36
+ const userId = 'john-doe-12345'
37
+ const anonymousId = '18aedb99-e756-40fa-8e83-d35f90998fb4'
38
+ const customerSince = '2021-10-20T14:20:15Z'
39
+ const isNewCustomer = false
40
+ const loyaltyStatus = 'in'
41
+ const firstName = 'John'
42
+ const lastName = 'Doe'
43
+ const name = `${firstName} ${lastName}`
44
+ const email = 'john.doe@example.com'
45
+ const age = 25
46
+ const birthday = '1996-02-29'
47
+ const language = 'en-US'
48
+ const country = 'US'
49
+ const state = 'CA'
50
+ const city = 'Beverly Hills'
51
+ const zipCode = '90210'
52
+ const friendbuyAttributes = { custom1: 'custom1', custom2: 'custom2' }
53
+
54
+ const [trackCustomer] = await friendbuyDestination({
55
+ merchantId,
56
+ subscriptions
57
+ })
58
+ // console.log('trackCustomer', JSON.stringify(trackCustomer, null, 2), trackCustomer)
59
+ expect(trackCustomer).toBeDefined()
60
+
61
+ await trackCustomer.load(Context.system(), {} as Analytics)
62
+
63
+ // console.log(window.friendbuyAPI)
64
+ jest.spyOn(window.friendbuyAPI as any, 'push')
65
+
66
+ {
67
+ // all fields
68
+ const context1 = new Context({
69
+ type: 'identify',
70
+ userId,
71
+ anonymousId,
72
+ traits: {
73
+ email,
74
+ customerSince,
75
+ isNewCustomer,
76
+ loyaltyStatus,
77
+ firstName,
78
+ lastName,
79
+ name,
80
+ age,
81
+ birthday,
82
+ language,
83
+ address: { country, state, city, postalCode: zipCode },
84
+ friendbuyAttributes
85
+ }
86
+ })
87
+ // console.log('context1', JSON.stringify(context1, null, 2))
88
+
89
+ trackCustomer.identify?.(context1)
90
+
91
+ // console.log('trackCustomer request', JSON.stringify(window.friendbuyAPI.push.mock.calls[0], null, 2))
92
+ expect(window.friendbuyAPI?.push).toHaveBeenNthCalledWith(1, [
93
+ 'track',
94
+ 'customer',
95
+ {
96
+ id: userId,
97
+ email,
98
+ customerSince,
99
+ isNewCustomer,
100
+ loyaltyStatus,
101
+ firstName,
102
+ lastName,
103
+ name,
104
+ age,
105
+ birthday: { year: 1996, month: 2, day: 29 },
106
+ language,
107
+ country,
108
+ state,
109
+ city,
110
+ zipCode,
111
+ anonymousId,
112
+ ...friendbuyAttributes
113
+ },
114
+ true
115
+ ])
116
+ }
117
+
118
+ {
119
+ // name derived from firstName and lastName
120
+ const context2 = new Context({
121
+ type: 'identify',
122
+ userId,
123
+ traits: {
124
+ firstName,
125
+ lastName
126
+ }
127
+ })
128
+
129
+ trackCustomer.identify?.(context2)
130
+
131
+ expect(window.friendbuyAPI?.push).toHaveBeenNthCalledWith(2, [
132
+ 'track',
133
+ 'customer',
134
+ {
135
+ id: userId,
136
+ firstName,
137
+ lastName,
138
+ name
139
+ },
140
+ true
141
+ ])
142
+ }
143
+
144
+ {
145
+ // name without firstName and lastName
146
+ const context3 = new Context({
147
+ type: 'identify',
148
+ userId,
149
+ traits: {
150
+ email,
151
+ name
152
+ }
153
+ })
154
+
155
+ trackCustomer.identify?.(context3)
156
+
157
+ expect(window.friendbuyAPI?.push).toHaveBeenNthCalledWith(3, [
158
+ 'track',
159
+ 'customer',
160
+ {
161
+ id: userId,
162
+ email,
163
+ name
164
+ },
165
+ true
166
+ ])
167
+ }
168
+
169
+ {
170
+ // enjoined fields are converted
171
+ const context4 = new Context({
172
+ type: 'identify',
173
+ userId: 12345,
174
+ traits: {
175
+ email,
176
+ age: '44',
177
+ address: { postalCode: 90210 }
178
+ }
179
+ })
180
+
181
+ trackCustomer.identify?.(context4)
182
+
183
+ expect(window.friendbuyAPI?.push).toHaveBeenNthCalledWith(4, [
184
+ 'track',
185
+ 'customer',
186
+ {
187
+ id: '12345',
188
+ email,
189
+ age: 44,
190
+ zipCode: '90210'
191
+ },
192
+ true
193
+ ])
194
+ }
195
+ })
196
+ })
@@ -0,0 +1,74 @@
1
+ // Generated file. DO NOT MODIFY IT BY HAND.
2
+
3
+ export interface Payload {
4
+ /**
5
+ * The user's customer ID.
6
+ */
7
+ customerId: string
8
+ /**
9
+ * The user's anonymous id.
10
+ */
11
+ anonymousId?: string
12
+ /**
13
+ * The user's email address.
14
+ */
15
+ email: string
16
+ /**
17
+ * The user's given name.
18
+ */
19
+ firstName?: string
20
+ /**
21
+ * The user's surname.
22
+ */
23
+ lastName?: string
24
+ /**
25
+ * The user's full name. If the name trait doesn't exist then it will be automatically derived from the firstName and lastName traits if they are defined.
26
+ */
27
+ name?: string
28
+ /**
29
+ * The user's age.
30
+ */
31
+ age?: number
32
+ /**
33
+ * The user's birthday in the format "YYYY-MM-DD", or "0000-MM-DD" to omit the year.
34
+ */
35
+ birthday?: string
36
+ /**
37
+ * The user's language.
38
+ */
39
+ language?: string
40
+ /**
41
+ * The user's country.
42
+ */
43
+ addressCountry?: string
44
+ /**
45
+ * The user's state.
46
+ */
47
+ addressState?: string
48
+ /**
49
+ * The user's city.
50
+ */
51
+ addressCity?: string
52
+ /**
53
+ * The user's postal code.
54
+ */
55
+ addressPostalCode?: string
56
+ /**
57
+ * The date the user became a customer.
58
+ */
59
+ customerSince?: string
60
+ /**
61
+ * The status of the user in your loyalty program. Valid values are "in", "out", or "blocked".
62
+ */
63
+ loyaltyStatus?: string
64
+ /**
65
+ * Flag to indicate whether the user is a new customer.
66
+ */
67
+ isNewCustomer?: boolean
68
+ /**
69
+ * Custom attributes to send to Friendbuy. You should pass an object whose keys are the names of the custom attributes and whose values are strings. Non-string-valued attributes will be dropped.
70
+ */
71
+ friendbuyAttributes?: {
72
+ [k: string]: unknown
73
+ }
74
+ }
@@ -0,0 +1,51 @@
1
+ import type { BrowserActionDefinition } from '@segment/browser-destination-runtime/types'
2
+
3
+ import type { FriendbuyAPI } from '../types'
4
+ import type { Settings } from '../generated-types'
5
+ import type { Payload } from './generated-types'
6
+ import type { AnalyticsPayload, ConvertFun, EventMap } from '@segment/actions-shared'
7
+
8
+ import { COPY, ROOT, mapEvent } from '@segment/actions-shared'
9
+ import { trackCustomerFields } from '@segment/actions-shared'
10
+ import { addName, enjoinInteger, enjoinString, parseDate } from '@segment/actions-shared'
11
+
12
+ // see https://segment.com/docs/config-api/fql/
13
+ export const trackCustomerDefaultSubscription = 'type = "identify"'
14
+
15
+ const trackCustomerPub: EventMap = {
16
+ fields: {
17
+ customerId: { name: 'id', convert: enjoinString as ConvertFun },
18
+ anonymousID: COPY,
19
+ email: COPY,
20
+ isNewCustomer: COPY,
21
+ loyaltyStatus: COPY,
22
+ firstName: COPY,
23
+ lastName: COPY,
24
+ name: COPY,
25
+ age: { convert: enjoinInteger as ConvertFun },
26
+ // fbt-merchant-api complains about birthday being an object but passes it anyway.
27
+ birthday: { convert: parseDate as ConvertFun },
28
+ language: COPY,
29
+ addressCountry: { name: 'country' },
30
+ addressState: { name: 'state' },
31
+ addressCity: { name: 'city' },
32
+ addressPostalCode: { name: 'zipCode', convert: enjoinString as ConvertFun }
33
+ },
34
+ unmappedFieldObject: ROOT
35
+ }
36
+
37
+ const action: BrowserActionDefinition<Settings, FriendbuyAPI, Payload> = {
38
+ title: 'Track Customer',
39
+ description: 'Create a new customer profile or update an existing customer profile.',
40
+ defaultSubscription: trackCustomerDefaultSubscription,
41
+ platform: 'web',
42
+ fields: trackCustomerFields,
43
+
44
+ perform: (friendbuyAPI, { payload }) => {
45
+ addName(payload)
46
+ const friendbuyPayload = mapEvent(trackCustomerPub, payload as unknown as AnalyticsPayload)
47
+ friendbuyAPI.push(['track', 'customer', friendbuyPayload, true])
48
+ }
49
+ }
50
+
51
+ export default action