Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Responsys new Action: Send to PET + Adjustments in Send Audience as PET #2615

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c4905b6
- New Action for Responsys: Send to PET, creating the PET if it doesn…
seg-leonelsanches Nov 23, 2024
d6e6526
PET fields can't have more than 30 characteres in their names.
seg-leonelsanches Nov 23, 2024
d128133
New Action for Responsys: Send to PET.
seg-leonelsanches Nov 26, 2024
bf51760
- Having truly work with sync/async endpoints;\n- For async requests…
seg-leonelsanches Nov 28, 2024
6d85f7a
Adding unit tests for action.
seg-leonelsanches Dec 3, 2024
16ca25d
Adding rate limits to all actions that are not marked as legacy.
seg-leonelsanches Dec 3, 2024
57dd550
With rate limits, 'sendToPet' doesn't require a retry mechanism per p…
seg-leonelsanches Dec 3, 2024
dcd827b
Adding default permission status to Responsys mappings;\nRate limits …
seg-leonelsanches Dec 4, 2024
7d8306e
Additional generations.
seg-leonelsanches Dec 4, 2024
994ded9
Making 'sendAudienceAsPet' to work with async endpoints.
seg-leonelsanches Dec 4, 2024
abda658
Unit Tests adjustments.
seg-leonelsanches Dec 4, 2024
5976c03
Merge remote-tracking branch 'origin/main' into responsys-custom-trai…
seg-leonelsanches Dec 4, 2024
b47cac1
Splitting requests in batches of 200 records. Updating unit tests.
seg-leonelsanches Dec 4, 2024
590f32e
Implementing batches of 200 records for upsertListMember.
seg-leonelsanches Dec 4, 2024
037863a
Reversing 'Legacy' naming for 'sendCustomTraits'.
seg-leonelsanches Dec 6, 2024
939b99e
Merge remote-tracking branch 'origin/main' into responsys-custom-trai…
seg-leonelsanches Dec 12, 2024
7a3169f
- Adding verification when PET exists in another folder;
seg-leonelsanches Dec 13, 2024
2bd1a53
On profile list update, splitting batch into multiple record sets, to…
seg-leonelsanches Dec 13, 2024
f60809d
Updating unit tests for Responsys.
seg-leonelsanches Dec 13, 2024
2dad7e0
Updating geerated types.
seg-leonelsanches Dec 13, 2024
c735dc6
Fixing issue with .
seg-leonelsanches Dec 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

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 @@ -5,6 +5,7 @@ import sendAudience from './sendAudience'
import upsertListMember from './upsertListMember'

import sendAudienceAsPet from './sendAudienceAsPet'
import sendToPet from './sendToPet'

interface RefreshTokenResponse {
authToken: string
Expand Down Expand Up @@ -45,7 +46,7 @@ const destination: DestinationDefinition<Settings> = {
userPassword: {
label: 'Password',
description: 'Responsys password',
type: 'string',
type: 'password',
required: true
},
baseUrl: {
Expand All @@ -56,15 +57,22 @@ const destination: DestinationDefinition<Settings> = {
format: 'uri',
required: true
},
defaultFolderName: {
label: 'Default Folder Name',
description: 'Name of the folder where the Profile Extension Table is located.',
type: 'string',
required: false
},
profileListName: {
label: 'List Name',
label: 'Default Profile List Name',
description: "Name of the Profile Extension Table's Contact List.",
type: 'string',
required: true
required: false
},
profileExtensionTable: {
label: 'PET Name',
description: 'Profile Extension Table (PET) Name. Required if using the "Send Custom Traits" Action.',
label: 'Default PET Name',
description:
'Default Profile Extension Table (PET) Name. Required if using the "Send Custom Traits" Action. Can be overridden in the mapping.',
type: 'string',
required: false
},
Expand Down Expand Up @@ -150,7 +158,8 @@ const destination: DestinationDefinition<Settings> = {
},
defaultPermissionStatus: {
label: 'Default Permission Status',
description: 'This value must be specified as either OPTIN or OPTOUT. defaults to OPTOUT.',
description:
'This value must be specified as either OPTIN or OPTOUT. Defaults to OPTOUT. Can be overridden in the mapping.',
type: 'string',
required: true,
choices: [
Expand Down Expand Up @@ -220,7 +229,8 @@ const destination: DestinationDefinition<Settings> = {
sendAudience,
sendAudienceAsPet,
sendCustomTraits,
upsertListMember
upsertListMember,
sendToPet
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { ActionDefinition } from '@segment/actions-core'
import type { Settings } from '../generated-types'
import type { Payload } from './generated-types'
import { enable_batching, batch_size } from '../shared-properties'
import { sendCustomTraits, getUserDataFieldNames, validateCustomTraits, validateListMemberPayload } from '../utils'
import { use_responsys_async_api, batch_size } from '../shared-properties'
import { sendCustomTraits, getUserDataFieldNames, testConditionsToRetry, validateListMemberPayload } from '../utils'
import { Data } from '../types'

const action: ActionDefinition<Settings, Payload> = {
Expand Down Expand Up @@ -75,7 +75,7 @@ const action: ActionDefinition<Settings, Payload> = {
default: { '@path': '$.context.personas.computation_class' },
choices: [{ label: 'Audience', value: 'audience' }]
},
enable_batching: enable_batching,
enable_batching: use_responsys_async_api,
batch_size: batch_size,
stringify: {
label: 'Stringify Recipient Data',
Expand Down Expand Up @@ -116,7 +116,7 @@ const action: ActionDefinition<Settings, Payload> = {
perform: async (request, data) => {
const { payload, settings, statsContext } = data
const userDataFieldNames: string[] = getUserDataFieldNames(data as unknown as Data)
validateCustomTraits({
testConditionsToRetry({
profileExtensionTable: settings.profileExtensionTable,
timestamp: payload.timestamp,
statsContext: statsContext,
Expand All @@ -130,7 +130,7 @@ const action: ActionDefinition<Settings, Payload> = {
performBatch: async (request, data) => {
const { payload, settings, statsContext } = data
const userDataFieldNames = getUserDataFieldNames(data as unknown as Data)
validateCustomTraits({
testConditionsToRetry({
profileExtensionTable: settings.profileExtensionTable,
timestamp: payload[0].timestamp,
statsContext: statsContext,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const responsysHost = 'https://123456-api.responsys.ocs.oraclecloud.com'
const profileListName = 'TEST_PROFILE_LIST'
const folderName = 'TEST_FOLDER'

jest.setTimeout(10000)

describe('Responsys.sendAudienceAsPet', () => {
describe('Successful scenarios', () => {
describe('Single event', () => {
Expand Down Expand Up @@ -55,23 +57,30 @@ describe('Responsys.sendAudienceAsPet', () => {
updateOnMatch: 'REPLACE_ALL',
defaultPermissionStatus: 'OPTOUT',
profileListName
},
auth: {
accessToken: 'abcd1234',
refreshToken: 'efgh5678'
}
}

it('sends an event with default mappings + default settings, PET does not exist yet', async () => {
nock(responsysHost).get(`/rest/api/v1.3/lists/${profileListName}/listExtensions`).reply(200, [])

nock(responsysHost)
.post(`/rest/api/v1.3/lists/${profileListName}/listExtensions`)
.reply(200, { results: [{}] })
nock(responsysHost).post(`/rest/api/v1.3/lists/${profileListName}/listExtensions`).reply(200, {})

nock(responsysHost)
.post(`/rest/asyncApi/v1.3/lists/${profileListName}/members`)
.reply(200, { results: [{}] })
nock(responsysHost).post(`/rest/asyncApi/v1.3/lists/${profileListName}/members`).reply(200, {
requestId: '23456'
})

nock(responsysHost)
.post(`/rest/api/v1.3/lists/${profileListName}/listExtensions/${audienceKey}/members`)
.reply(200, { results: [{}] })
.post(`/rest/asyncApi/v1.3/lists/${profileListName}/listExtensions/${audienceKey}/members`)
.reply(200, {
requestId: '34567'
})

nock(responsysHost).get(`/rest/asyncApi/v1.3/requests/23456`).reply(200, {})
nock(responsysHost).get(`/rest/asyncApi/v1.3/requests/34567`).reply(200, {})

const responses = await testDestination.testAction('sendAudienceAsPet', actionPayload)

Expand All @@ -91,13 +100,18 @@ describe('Responsys.sendAudienceAsPet', () => {
}
])

nock(responsysHost)
.post(`/rest/asyncApi/v1.3/lists/${profileListName}/members`)
.reply(200, { results: [{}] })
nock(responsysHost).post(`/rest/asyncApi/v1.3/lists/${profileListName}/members`).reply(200, {
requestId: '23456'
})

nock(responsysHost)
.post(`/rest/api/v1.3/lists/${profileListName}/listExtensions/${audienceKey}/members`)
.reply(200, { results: [{}] })
.post(`/rest/asyncApi/v1.3/lists/${profileListName}/listExtensions/${audienceKey}/members`)
.reply(200, {
requestId: '34567'
})

nock(responsysHost).get(`/rest/asyncApi/v1.3/requests/23456`).reply(200, {})
nock(responsysHost).get(`/rest/asyncApi/v1.3/requests/34567`).reply(200, {})

const responses = await testDestination.testAction('sendAudienceAsPet', actionPayload)

Expand Down Expand Up @@ -186,30 +200,30 @@ describe('Responsys.sendAudienceAsPet', () => {
updateOnMatch: 'REPLACE_ALL',
defaultPermissionStatus: 'OPTOUT',
profileListName
},
auth: {
accessToken: 'abcd1234',
refreshToken: 'efgh5678'
}
}

nock(responsysHost).get(`/rest/api/v1.3/lists/${profileListName}/listExtensions`).reply(200, [])

nock(responsysHost)
.post(`/rest/api/v1.3/lists/${profileListName}/listExtensions`)
.reply(200, { results: [{}] })
nock(responsysHost).post(`/rest/api/v1.3/lists/${profileListName}/listExtensions`).reply(200, {})

nock(responsysHost)
.post(`/rest/asyncApi/v1.3/lists/${profileListName}/members`)
.reply(200, { results: [{}] })
nock(responsysHost).post(`/rest/asyncApi/v1.3/lists/${profileListName}/members`).reply(200, {
requestId: '23456'
})

nock(responsysHost)
.post(`/rest/api/v1.3/lists/${profileListName}/listExtensions/looney_tunes_audience/members`)
.post(`/rest/asyncApi/v1.3/lists/${profileListName}/listExtensions/looney_tunes_audience/members`)
.times(3)
.reply(200, { results: [{}] })
.reply(200, {
requestId: '34567'
})

/* for (const event of events) {
;(event.context as any).personas.audience_settings = {
computation_key: 'looney_tunes_audience',
external_audience_id: '12345'
}
} */
nock(responsysHost).persist().get(`/rest/asyncApi/v1.3/requests/23456`).reply(200, {})
nock(responsysHost).persist().get(`/rest/asyncApi/v1.3/requests/34567`).reply(200, {})

const responses = await testDestination.executeBatch('sendAudienceAsPet', actionPayload)

Expand Down
Loading
Loading