Skip to content

Commit

Permalink
Changes implemented following call with Joe
Browse files Browse the repository at this point in the history
Track()

[x] Explicitly indicate which fields are required or optional
[x] Look for traits and if not context.traits
[x] Need description for the Action
[x] Make Timestamp field required
[x] Make messageId required. It will always be there.
[x] getEventProperties: This line looks incorrect: id: payload.event,
[x] source mapping looks incorrect: source: integration?.name == 'Iterable' ? 'Iterable' : 'segment',

Identify()

[x] Description should be updated.
[x] identify() calls are often fired when a trait is collected, or when a userId is collected.
[x] Maybe use wording: “Creates or updates a user profile, and adds or updates trait values on the user profile…”
[x] Refactor the perform() function

group()

[x] Group Key - Amend description to better explain that group key is a way to connect multiple organizations together
[x] groupId field - Should be updated
[x] Consider adding anonymousId as a field
[x] Handle when there are no traits.
  • Loading branch information
SSabev committed Feb 3, 2023
1 parent 1089f28 commit 349aad0
Show file tree
Hide file tree
Showing 14 changed files with 132 additions and 164 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Object {
"group_id": "$WBBWnR",
"group_testType": "$WBBWnR",
},
"api_key": "$WBBWnR",
"distinct_id": "$WBBWnR",
"event": "$identify",
"type": "screen",
Expand All @@ -16,8 +17,8 @@ exports[`Testing snapshot for Launchpad's groupIdentifyUser destination action:
Object {
"$set": Object {
"group_id": "$WBBWnR",
"group_testType": "$WBBWnR",
},
"api_key": "$WBBWnR",
"event": "$identify",
"type": "screen",
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import nock from 'nock'
import { createTestIntegration } from '@segment/actions-core'
import Destination from '../../index'
import { SegmentEvent } from '@segment/actions-core'
import { IntegrationError } from '@segment/actions-core'

const launchpadAPISecret = 'lp-api-key'
const timestamp = '2023-01-28T15:21:15.449Z'
Expand Down Expand Up @@ -32,15 +31,6 @@ const testGroupIdentify: SegmentEvent = {
}
}

const testGroupIdentifyNoTraits: SegmentEvent = {
messageId: 'test-message-t73406chv4',
timestamp: timestamp,
type: 'group',
groupId: '12381923812',
userId: '[email protected]',
traits: {}
}

describe('Launchpad.groupIdentifyUser', () => {
it('should convert the type and event name', async () => {
nock('https://data.launchpad.pm').post('/capture').reply(200, {})
Expand All @@ -62,23 +52,4 @@ describe('Launchpad.groupIdentifyUser', () => {
$set: expect.objectContaining(expectedTraits)
})
})

describe('Launchpad.groupIdentifyUser', () => {
it('when no traits it should give a 400 back', async () => {
nock('https://data.launchpad.pm').post('/capture').reply(400, {})

try {
await testDestination.testAction('groupIdentifyUser', {
event: testGroupIdentifyNoTraits,
useDefaultMappings: true,
settings: {
apiSecret: launchpadAPISecret,
sourceName: 'example segment source name'
}
})
} catch (error) {
expect(error).toBeInstanceOf(IntegrationError)
}
})
})
})

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ActionDefinition, IntegrationError } from '@segment/actions-core'
import { ActionDefinition } from '@segment/actions-core'
import type { Settings } from '../generated-types'
import { getApiServerUrl } from '../utils'
import type { Payload } from './generated-types'
Expand All @@ -12,8 +12,9 @@ const groupIdentifyUser: ActionDefinition<Settings, Payload> = {
groupKey: {
label: 'Group Key',
type: 'string',
required: false,
description:
'The group key you specified in Launchpad under Project settings. If this is not specified, it will be defaulted to "$group_id".'
'The group key you specified in Launchpad under the company corresponding to the group. If this is not specified, it will be defaulted to "$group_id". This is helpful when you have a group of companies that should be joined together as in when you have a multinational.'
},
groupId: {
label: 'Group ID',
Expand All @@ -29,7 +30,7 @@ const groupIdentifyUser: ActionDefinition<Settings, Payload> = {
label: 'Group Properties',
type: 'object',
description: 'The properties to set on the group profile.',
required: true,
required: false,
default: {
'@path': '$.traits'
}
Expand All @@ -42,28 +43,36 @@ const groupIdentifyUser: ActionDefinition<Settings, Payload> = {
default: {
'@path': '$.userId'
}
},
anonymousId: {
label: 'Anonymous ID',
type: 'string',
allowNull: true,
description: 'The generated anonymous ID for the user',
default: {
'@path': '$.anonymousId'
}
}
},

perform: async (request, { payload, settings }) => {
if (!payload.traits || Object.keys(payload.traits).length === 0) {
throw new IntegrationError('"traits" is a required field', 'Missing required fields', 400)
}
const groupId = payload.groupId
const apiServerUrl = getApiServerUrl(settings.apiRegion)
let transformed_traits

const transformed_traits = {
...Object.fromEntries(Object.entries(payload.traits).map(([k, v]) => [`group_${k}`, v]))
if (payload.traits) {
transformed_traits = {
...Object.fromEntries(Object.entries(payload.traits).map(([k, v]) => [`group_${k}`, v]))
}
}

const groupIdentifyEvent = {
event: '$identify',
type: 'screen',
$set: {
group_id: groupId,
...transformed_traits
},
distinct_id: payload.userId,
distinct_id: payload.userId ? payload.userId : payload.anonymousId,
api_key: settings.apiSecret
}
const groupIdentifyResponse = await request(`${apiServerUrl}capture`, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Object {
"$set": Object {
"testType": "5SpoCjYek1jtNwUC",
},
"api_key": "5SpoCjYek1jtNwUC",
"distinct_id": "5SpoCjYek1jtNwUC",
"event": "$identify",
"type": "screen",
Expand All @@ -17,6 +18,7 @@ Object {
"$set": Object {
"testType": "5SpoCjYek1jtNwUC",
},
"api_key": "5SpoCjYek1jtNwUC",
"event": "$identify",
"type": "screen",
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { getApiServerUrl, getConcatenatedName } from '../utils'

const identifyUser: ActionDefinition<Settings, Payload> = {
title: 'Identify User',
description: 'Set the user ID for a particular device ID or update user properties.',
description:
'“Creates or updates a user profile, and adds or updates trait values on the user profile that you can use for segmentation within the Launchpad platform.',
defaultSubscription: 'type = "identify"',
fields: {
ip: {
Expand All @@ -21,7 +22,7 @@ const identifyUser: ActionDefinition<Settings, Payload> = {
label: 'User ID',
type: 'string',
allowNull: true,
description: 'The unique user identifier set by you',
description: 'The unique user identifier set by you.',
default: {
'@path': '$.userId'
}
Expand All @@ -30,7 +31,7 @@ const identifyUser: ActionDefinition<Settings, Payload> = {
label: 'Anonymous ID',
type: 'string',
allowNull: true,
description: 'The generated anonymous ID for the user',
description: 'The generated anonymous ID for the user.',
default: {
'@path': '$.anonymousId'
}
Expand All @@ -39,7 +40,7 @@ const identifyUser: ActionDefinition<Settings, Payload> = {
label: 'User Properties',
type: 'object',
required: true,
description: 'Properties to set on the user profile',
description: 'Properties that you want to set on the user profile and you would want to segment by later.',
default: {
'@path': '$.traits'
}
Expand All @@ -48,34 +49,15 @@ const identifyUser: ActionDefinition<Settings, Payload> = {

perform: async (request, { payload, settings }) => {
const apiServerUrl = getApiServerUrl(settings.apiRegion)

if (payload.anonymousId && !payload.traits) {
const identifyEvent = {
event: '$identify',
type: 'screen',
$set: {
$distinct_id: payload.userId,
$anonymous_id: payload.anonymousId,
segment_source_name: settings.sourceName
},
distinct_id: payload.anonymousId,
api_key: settings.apiSecret
}
const identifyResponse = await request(`${apiServerUrl}capture`, {
method: 'post',
json: identifyEvent
})

return identifyResponse
}
let traits

if (payload.traits && Object.keys(payload.traits).length > 0) {
const concatenatedName = getConcatenatedName(
payload.traits.firstName,
payload.traits.lastName,
payload.traits.name
)
const traits = {
traits = {
...omit(payload.traits, ['created', 'email', 'firstName', 'lastName', 'name', 'username', 'phone']),
// to fit the Launchpad expectations, transform the special traits to Launchpad reserved property
$created: payload.traits.created,
Expand All @@ -87,20 +69,21 @@ const identifyUser: ActionDefinition<Settings, Payload> = {
$phone: payload.traits.phone,
...payload.traits
}
const data = {
distinct_id: payload.userId,
$ip: payload.ip,
$set: traits,
event: '$identify',
type: 'screen',
api_key: settings.apiSecret
}
const identifyResponse = request(`${apiServerUrl}capture`, {
method: 'post',
json: data
})
return identifyResponse
}

const data = {
distinct_id: payload.userId ? payload.userId : payload.anonymousId,
$ip: payload.ip,
$set: traits ? traits : {},
event: '$identify',
type: 'screen',
api_key: settings.apiSecret
}
const identifyResponse = request(`${apiServerUrl}capture`, {
method: 'post',
json: data
})
return identifyResponse
}
}

Expand Down
Loading

0 comments on commit 349aad0

Please sign in to comment.