Skip to content

Commit

Permalink
Squashed commit of the following:
Browse files Browse the repository at this point in the history
commit c37259c
Author: Harsh Joshi <[email protected]>
Date:   Wed Jun 5 16:05:46 2024 +0530

    Update test cases

commit 6ab6d57
Author: Harsh Joshi <[email protected]>
Date:   Tue Jun 4 15:15:20 2024 +0530

    Add profile properties in Add profilr to ost event

commit 524fc6c
Author: Varadarajan V <[email protected]>
Date:   Wed May 29 17:41:51 2024 +0530

    Remove build-experience-team from pr labeler as internal team (#2060)

commit 72adc64
Author: Joe Ayoub <[email protected]>
Date:   Tue May 28 11:04:54 2024 +0100

    Publish

     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]
     - @segment/[email protected]

commit e4bb620
Author: Prayansh Srivastava <[email protected]>
Date:   Tue May 28 02:25:29 2024 -0700

    add new excludeWhenNull directive and update tests (#2040)

    * add new excludeWhenNull directive and update tests

    * add readme docs

    * fix replace test case

commit e7b424a
Author: harsh-joshi99 <[email protected]>
Date:   Tue May 28 14:53:39 2024 +0530

    Add override_list_id mapping in upsert Profile (#2046)

    * Add override_list_id mapping in upsert Profile, add function to group profiles based on list ID

    * fix payload

    * Fix payload condition

    * Refactor profile filter

commit 6170334
Author: Joe Ayoub <[email protected]>
Date:   Tue May 28 10:18:32 2024 +0100

    updating field description and updating generated types

commit 1107970
Author: Alice Mackel <[email protected]>
Date:   Tue May 28 05:07:52 2024 -0400

    Change StackAdapt destination name (#2055)

commit 76c733d
Author: Leonel Sanches <[email protected]>
Date:   Tue May 28 02:07:21 2024 -0700

    Preventing double-hashing for TikTok Offline Conversions. (#2034)

commit a621179
Author: Nuno Sousa <[email protected]>
Date:   Tue May 28 10:07:09 2024 +0100

    Fix customer.io timestamp issue (#2054)

commit 1c71987
Author: Leonel Sanches <[email protected]>
Date:   Tue May 28 02:06:52 2024 -0700

    Preventing double-hashing for TikTok Conversions. (#2033)

commit 4b27451
Author: Nick Campbell <[email protected]>
Date:   Tue May 28 10:06:28 2024 +0100

    Implement batch support for Attio Actions (#2057)

    * Implement batch APIs for Attio

    * Make received_at parameter optional and gracefully handle it

    * Make "enable_batching" parameter viewable, optional, default false

    There are tradeoffs associated with Segment event batching - there is no
    realtime feedback if the request was invalid, for example - so we should
    make it opt-in and controllable by the user.

commit 0fd6c22
Author: Innovative-GauravKochar <[email protected]>
Date:   Tue May 28 14:33:36 2024 +0530

    [STRATCONN-3468] | Introduce 'Amazon AMC' Audience Destination (#2036)

    * Updated the code for amazon ads syncaudience action

    * Fix the build failing

    * Updated the getAudience and createAudience

    * Code to update the value to hashed

    * Added the advertiserId field in audienceSetting

    * Added check for advertiserid

    * Fixing External Id issue , replace with quoted string

    * Resolve Conflicts

    * Resolve Conflicts

    * Resolve Conflicts

    * Worked on unit test case for createAUdience and syncAudience

    * Code cleaning

    * removed stats

    * Updated Snapshots

    * added headers in refresh Access token

    * Fix refresh access token API

    * Worked on handling cpmCents and ttl

    * Fixed Pr Comments

    * Rename destination slug nad action name

    * removed amazon-ads as we are changing action destination slug

    * Validate Schema in createAudience

    * registered amazon-amc and updated destination id

    * will handle this in seperate PR

    ---------

    Co-authored-by: Harsh Vardhan <[email protected]>
    Co-authored-by: Gaurav Kochar <[email protected]>

commit 2fc41f9
Author: Varadarajan V <[email protected]>
Date:   Fri May 24 11:49:25 2024 +0530

    [snyk] bump jscodeshift from 0.13.0 to 0.14.0 (#2056)

commit e790949
Author: alfrimpong <[email protected]>
Date:   Wed May 22 00:59:22 2024 -0500

    feat: add script for action-cli shared (#2050)
  • Loading branch information
harsh-joshi99 committed Jun 5, 2024
1 parent af3265c commit 74ec16c
Show file tree
Hide file tree
Showing 6 changed files with 293 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,16 @@ const importJobPayload = {
}
}

const profileProperties = {
first_name: 'John',
last_name: 'Doe',
image: 'http://example.com/image.jpg',
title: 'Developer',
organization: 'Segment',
location: { city: 'San Francisco' },
properties: { key: 'value' }
}

describe('Add List To Profile', () => {
it('should throw error if no email or External Id is provided', async () => {
const event = createTestEvent({
Expand Down Expand Up @@ -189,6 +199,55 @@ describe('Add List To Profile', () => {
testDestination.testAction('addProfileToList', { event, mapping, settings })
).resolves.not.toThrowError()
})

it('should add profile to list if successful with email, external id and profile properties', async () => {
nock(`${API_URL}`)
.post('/profiles/', {
data: {
type: 'profile',
attributes: { email: '[email protected]', external_id: 'testing_123', ...profileProperties }
}
})
.reply(200, {
data: {
id: 'XYZABC'
}
})

nock(`${API_URL}/lists/${listId}`)
.post('/relationships/profiles/', requestBody)
.reply(
200,
JSON.stringify({
content: requestBody
})
)

const event = createTestEvent({
type: 'track',
userId: '123',
properties: {
external_id: 'testing_123'
},
context: {
traits: {
email: '[email protected]',
...profileProperties
}
}
})
const mapping = {
list_id: listId,
email: '[email protected]',
external_id: 'testing_123',
...profileProperties
}

await expect(
testDestination.testAction('addProfileToList', { event, mapping, settings })
).resolves.not.toThrowError()
})

it('should add to list if profile is already created', async () => {
nock(`${API_URL}`)
.post('/profiles/', profileData)
Expand Down Expand Up @@ -272,7 +331,9 @@ describe('Add Profile To List Batch', () => {
batch_size: 10000,
list_id: listId,
email: '[email protected]',
enable_batching: true
enable_batching: true,
location: {},
properties: {}
}
],
listId
Expand Down Expand Up @@ -314,6 +375,44 @@ describe('Add Profile To List Batch', () => {
)
})

it('should send an import job request with the generated payload and profile properties', async () => {
const events = [
createTestEvent({
context: { personas: { list_id: listId }, traits: { email: '[email protected]' } }
})
]
const mapping = {
list_id: listId,
external_id: 'fake-external-id',
email: {
'@path': '$.context.traits.email'
},
...profileProperties
}

nock(API_URL).post('/profile-bulk-import-jobs/', importJobPayload).reply(200, { success: true })

await testDestination.testBatchAction('addProfileToList', {
events,
settings,
mapping,
useDefaultMappings: true
})
expect(Functions.createImportJobPayload).toBeCalledWith(
[
{
batch_size: 10000,
email: '[email protected]',
enable_batching: true,
external_id: 'fake-external-id',
list_id: listId,
...profileProperties
}
],
listId
)
})

it('should send an import job request with the generated payload', async () => {
const events = [
createTestEvent({
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 @@ -2,7 +2,20 @@ import { ActionDefinition, PayloadValidationError } from '@segment/actions-core'
import type { Settings } from '../generated-types'
import { Payload } from './generated-types'
import { createProfile, addProfileToList, createImportJobPayload, sendImportJobRequest } from '../functions'
import { email, external_id, list_id, enable_batching, batch_size } from '../properties'
import {
email,
external_id,
list_id,
enable_batching,
batch_size,
first_name,
last_name,
organization,
title,
image,
location,
properties
} from '../properties'

const action: ActionDefinition<Settings, Payload> = {
title: 'Add Profile to List (Engage)',
Expand All @@ -13,14 +26,21 @@ const action: ActionDefinition<Settings, Payload> = {
list_id: { ...list_id },
external_id: { ...external_id },
enable_batching: { ...enable_batching },
batch_size: { ...batch_size }
batch_size: { ...batch_size },
first_name: { ...first_name },
last_name: { ...last_name },
image: { ...image },
title: { ...title },
organization: { ...organization },
location: { ...location },
properties: { ...properties }
},
perform: async (request, { payload }) => {
const { email, list_id, external_id } = payload
const { email, list_id, external_id, enable_batching, batch_size, ...additionalAttributes } = payload
if (!email && !external_id) {
throw new PayloadValidationError('One of Email or External Id is required')
}
const profileId = await createProfile(request, email, external_id)
const profileId = await createProfile(request, email, external_id, additionalAttributes)
return await addProfileToList(request, profileId, list_id)
},
performBatch: async (request, { payload }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,17 @@ export async function removeProfileFromList(request: RequestClient, ids: string[
export async function createProfile(
request: RequestClient,
email: string | undefined,
external_id: string | undefined
external_id: string | undefined,
additionalAttributes: Record<string, string | object>
) {
try {
const profileData: ProfileData = {
data: {
type: 'profile',
attributes: {
email,
external_id
external_id,
...additionalAttributes
}
}
}
Expand All @@ -92,7 +94,7 @@ export async function createProfile(
return rs.data.id
} catch (error) {
const { response } = error as KlaviyoAPIError
if (response.status == 409) {
if (response?.status == 409) {
const rs = await response.json()
return rs.errors[0].meta.duplicate_profile_id
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,100 @@ export const batch_size: InputField = {
unsafe_hidden: true,
default: 10000
}

export const first_name: InputField = {
label: 'First Name',
description: `Individual's first name.`,
type: 'string',
default: { '@path': '$.context.traits.firstName' }
}

export const last_name: InputField = {
label: 'Last Name',
description: `Individual's last name.`,
type: 'string',
default: { '@path': '$.context.traits.lastName' }
}

export const organization: InputField = {
label: 'Organization',
description: `Name of the company or organization within the company for whom the individual works.`,
type: 'string',
default: { '@path': '$.context.traits.company.name' }
}

export const title: InputField = {
label: 'Title',
description: `Individual's job title.`,
type: 'string',
default: { '@path': '$.context.traits.title' }
}

export const image: InputField = {
label: 'Image',
description: `URL pointing to the location of a profile image.`,
type: 'string',
default: { '@path': '$.context.traits.avatar' }
}

export const location: InputField = {
label: 'Location',
description: `Individual's address.`,
type: 'object',
properties: {
address1: {
label: 'Address 1',
type: 'string',
allowNull: true
},
address2: {
label: 'Address 2',
type: 'string',
allowNull: true
},
city: {
label: 'City',
type: 'string',
allowNull: true
},
region: {
label: 'Region',
type: 'string',
allowNull: true
},
zip: {
label: 'ZIP',
type: 'string',
allowNull: true
},
latitude: {
label: 'Latitude',
type: 'string',
allowNull: true
},
longitude: {
label: 'Longitide',
type: 'string',
allowNull: true
},
country: {
label: 'Country',
type: 'string',
allowNull: true
}
},
default: {
city: { '@path': '$.context.traits.address.city' },
region: { '@path': '$.context.traits.address.state' },
zip: { '@path': '$.context.traits.address.postal_code' },
address1: { '@path': '$.context.traits.address.street' },
country: { '@path': '$.context.traits.address.country' }
}
}

export const properties: InputField = {
description: 'An object containing key/value pairs for any custom properties assigned to this profile.',
label: 'Properties',
type: 'object',
default: { '@path': '$.context.properties' }
}
Loading

0 comments on commit 74ec16c

Please sign in to comment.