Skip to content

Commit

Permalink
[Braze Cloud] Adds sync mode to new identifyUser V2 action (#2386)
Browse files Browse the repository at this point in the history
* Braze syncmode for identifyUser action

* Fixes a build error

* Generates types

* Splits off V2 action into it's own directory

* Manyally updates updateUserProfile snapshot test to hopefully pass?

* Removes unneeded git diffs

* Updates unit test with better test names and a check for the expected error message when testing if syncMode != add or upsert

---------

Co-authored-by: Joe Ayoub <[email protected]>
  • Loading branch information
nick-Ag and joe-ayoub-segment authored Sep 24, 2024
1 parent c38b360 commit 2172e30
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Testing snapshot for Braze's identifyUser2 destination V2 action: snapshot with all fields 1`] = `
Object {
"aliases_to_identify": Array [
Object {
"external_id": "O$J@g9^nDz",
"user_alias": Object {
"alias_label": "O$J@g9^nDz",
"alias_name": "O$J@g9^nDz",
},
},
],
"merge_behavior": "none",
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { createTestEvent, createTestIntegration } from '@segment/actions-core'
import { generateTestData } from '../../../../lib/test-data'
import destination from '../../index'
import nock from 'nock'

const testDestination = createTestIntegration(destination)
const actionSlug = 'identifyUser2'
const destinationSlug = 'Braze'
const seedName = `${destinationSlug}#${actionSlug}`

describe(`Testing snapshot for ${destinationSlug}'s ${actionSlug} destination V2 action:`, () => {
it('fails if sync mode is delete', async () => {
const action = destination.actions[actionSlug]
const [eventData, settingsData] = generateTestData(seedName, destination, action, false)

const event = createTestEvent({
properties: eventData
})

await expect(
testDestination.testAction(actionSlug, {
event: event,
mapping: { ...event.properties, __segment_internal_sync_mode: 'delete' },
settings: settingsData,
auth: undefined
})
).rejects.toThrowError('syncMode must be "add" or "upsert"')
})

it('fails if sync mode is update', async () => {
const action = destination.actions[actionSlug]
const [eventData, settingsData] = generateTestData(seedName, destination, action, false)

const event = createTestEvent({
properties: eventData
})

await expect(
testDestination.testAction(actionSlug, {
event: event,
mapping: { ...event.properties, __segment_internal_sync_mode: 'update' },
settings: settingsData,
auth: undefined
})
).rejects.toThrowError('syncMode must be "add" or "upsert"')
})

it('snapshot with all fields', async () => {
const action = destination.actions[actionSlug]
const [eventData, settingsData] = generateTestData(seedName, destination, action, false)

nock(/.*/).persist().get(/.*/).reply(200)
nock(/.*/).persist().post(/.*/).reply(200)
nock(/.*/).persist().put(/.*/).reply(200)

const event = createTestEvent({
properties: eventData
})

const responses = await testDestination.testAction(actionSlug, {
event: event,
mapping: { ...event.properties, __segment_internal_sync_mode: 'add' },
settings: settingsData,
auth: undefined
})

const request = responses[0].request
const rawBody = await request.text()

try {
const json = JSON.parse(rawBody)
expect(json).toMatchSnapshot()
return
} catch (err) {
expect(rawBody).toMatchSnapshot()
}
})
})

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
@@ -0,0 +1,76 @@
import type { ActionDefinition } from '@segment/actions-core'
import { IntegrationError } from '@segment/actions-core'
import type { Settings } from '../generated-types'
import type { Payload } from './generated-types'

const action: ActionDefinition<Settings, Payload> = {
title: 'Identify User V2',
description:
'Identifies an unidentified (alias-only) user. Use alongside the Create Alias action, or with user aliases you have already defined.',
fields: {
external_id: {
label: 'External ID',
description: 'The external ID of the user to identify.',
type: 'string',
required: true
},
user_alias: {
label: 'User Alias Object',
description:
'A user alias object. See [the docs](https://www.braze.com/docs/api/objects_filters/user_alias_object/).',
type: 'object',
required: true,
properties: {
alias_name: {
label: 'Alias Name',
type: 'string',
required: true
},
alias_label: {
label: 'Alias Label',
type: 'string',
required: true
}
}
},
merge_behavior: {
label: 'Merge Behavior',
description:
'Sets the endpoint to merge some fields found exclusively on the anonymous user to the identified user. See [the docs](https://www.braze.com/docs/api/endpoints/user_data/post_user_identify/#request-parameters).',
type: 'string',
choices: [
{ value: 'none', label: 'None' },
{ value: 'merge', label: 'Merge' }
]
}
},
syncMode: {
description: 'Define how the records from your destination will be synced.',
label: 'How to identify Users',
default: 'add',
choices: [
{ label: 'Insert User', value: 'add' },
{ label: 'Upsert User', value: 'upsert' }
]
},
perform: (request, { settings, payload, syncMode }) => {
if (syncMode === 'add' || syncMode === 'upsert') {
return request(`${settings.endpoint}/users/identify`, {
method: 'post',
json: {
aliases_to_identify: [
{
external_id: payload.external_id,
user_alias: payload.user_alias
}
],
...(payload.merge_behavior !== undefined && { merge_behavior: payload.merge_behavior })
}
})
}

throw new IntegrationError('syncMode must be "add" or "upsert"', 'Invalid syncMode', 400)
}
}

export default action
2 changes: 2 additions & 0 deletions packages/destination-actions/src/destinations/braze/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { DEFAULT_REQUEST_TIMEOUT, defaultValues } from '@segment/actions-core'
import createAlias from './createAlias'
import createAlias2 from './createAlias2'
import identifyUser from './identifyUser'
import identifyUser2 from './identifyUser2'
import trackEvent from './trackEvent'
import trackPurchase from './trackPurchase'
import updateUserProfile from './updateUserProfile'
Expand Down Expand Up @@ -77,6 +78,7 @@ const destination: DestinationDefinition<Settings> = {
trackPurchase,
createAlias,
identifyUser,
identifyUser2,
trackEvent2,
trackPurchase2,
updateUserProfile2,
Expand Down

0 comments on commit 2172e30

Please sign in to comment.