From d26fde4ce4d3328cc32710ca72e69edcb3bf93c7 Mon Sep 17 00:00:00 2001 From: kishoredevarasettyn Date: Thu, 8 Dec 2022 17:11:54 +0530 Subject: [PATCH 1/8] Initial commit for objects --- .../createUpdateObject/generated-types.ts | 26 ++++++ .../customerio/createUpdateObject/index.ts | 86 +++++++++++++++++++ .../src/destinations/customerio/index.ts | 11 ++- 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 packages/destination-actions/src/destinations/customerio/createUpdateObject/generated-types.ts create mode 100644 packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts diff --git a/packages/destination-actions/src/destinations/customerio/createUpdateObject/generated-types.ts b/packages/destination-actions/src/destinations/customerio/createUpdateObject/generated-types.ts new file mode 100644 index 0000000000..08995f480d --- /dev/null +++ b/packages/destination-actions/src/destinations/customerio/createUpdateObject/generated-types.ts @@ -0,0 +1,26 @@ +// Generated file. DO NOT MODIFY IT BY HAND. + +export interface Payload { + /** + * The ID used to uniquely identify an object in Customer.io. + */ + id: string + /** + * A timestamp of when the person was created. + */ + created_at?: string + /** + * Optional attributes for the object. When updating an object, attributes are added or updated, not removed. + */ + custom_attributes?: { + [k: string]: unknown + } + /** + * The ID used to relate user to an object in Customer.io. + */ + user_id?: string + /** + * Convert dates to Unix timestamps (seconds since Epoch). + */ + convert_timestamp?: boolean +} diff --git a/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts b/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts new file mode 100644 index 0000000000..0c27e5fcc2 --- /dev/null +++ b/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts @@ -0,0 +1,86 @@ +import type { ActionDefinition } from '@segment/actions-core' +import type { Settings } from '../generated-types' +import type { Payload } from './generated-types' +import { convertAttributeTimestamps, convertValidTimestamp, trackApiEndpoint } from '../utils' + +const action: ActionDefinition = { + title: 'Create or Update Object', + description: 'Create an object in Customer.io or update them if they exist.', + defaultSubscription: 'type = "object"', + fields: { + id: { + label: 'Object ID', + description: 'The ID used to uniquely identify an object in Customer.io.', + type: 'string', + required: true, + default: { + '@path': '$.groupId' + } + }, + created_at: { + label: 'Created At', + description: 'A timestamp of when the person was created.', + type: 'string', + default: { + '@template': '{{traits.created_at}}' + } + }, + custom_attributes: { + label: 'Object Attributes', + description: + 'Optional attributes for the object. When updating an object, attributes are added or updated, not removed.', + type: 'object', + default: { + '@path': '$.traits' + } + }, + user_id: { + label: 'User ID', + description: 'The ID used to relate user to an object in Customer.io.', + type: 'string', + default: { + '@path': '$.userId' + } + }, + convert_timestamp: { + label: 'Convert Timestamps', + description: 'Convert dates to Unix timestamps (seconds since Epoch).', + type: 'boolean', + default: true + } + }, + perform: (request, { settings, payload }) => { + let createdAt: string | number | undefined = payload.created_at + let customAttributes = payload.custom_attributes + const userID = payload.user_id + const objectID = payload.id + if (payload.convert_timestamp !== false) { + if (createdAt) { + createdAt = convertValidTimestamp(createdAt) + } + + if (customAttributes) { + customAttributes = convertAttributeTimestamps(customAttributes) + } + } + + const body: Record = { + ...customAttributes + } + + if (createdAt) { + body.created_at = createdAt + } + body.type = 'object' + body.action = 'identify' + body.identifiers = { type_id: '1', id: objectID } + body.cio_relationships = [{ identifiers: { id: userID } }] + + return request(`${trackApiEndpoint(settings.accountRegion)}/alpha-api/v2/profile`, { + method: 'post', + json: body + }) + } +} + +export default action diff --git a/packages/destination-actions/src/destinations/customerio/index.ts b/packages/destination-actions/src/destinations/customerio/index.ts index b57de0cf32..8403165793 100644 --- a/packages/destination-actions/src/destinations/customerio/index.ts +++ b/packages/destination-actions/src/destinations/customerio/index.ts @@ -9,6 +9,8 @@ import type { DestinationDefinition } from '@segment/actions-core' import type { Settings } from './generated-types' import { AccountRegion, trackApiEndpoint } from './utils' +import createUpdateObject from './createUpdateObject' + const destination: DestinationDefinition = { name: 'Actions Customerio', mode: 'cloud', @@ -55,7 +57,8 @@ const destination: DestinationDefinition = { createUpdatePerson, trackEvent, trackPageView, - trackScreenView + trackScreenView, + createUpdateObject }, presets: [ @@ -94,6 +97,12 @@ const destination: DestinationDefinition = { subscribe: 'type = "screen"', partnerAction: 'trackScreenView', mapping: defaultValues(trackScreenView.fields) + }, + { + name: 'Create or Update Object', + subscribe: 'type = "group"', + partnerAction: 'createUpdateObject', + mapping: defaultValues(createUpdateObject.fields) } ], From a738143958cb1408738efac74edaa942c145ba8d Mon Sep 17 00:00:00 2001 From: kishoredevarasettyn Date: Wed, 14 Dec 2022 17:17:47 +0530 Subject: [PATCH 2/8] Added Test cases --- .../__tests__/createUpdateObject.test.ts | 235 ++++++++++++++++++ .../createUpdateObject/generated-types.ts | 8 +- .../customerio/createUpdateObject/index.ts | 34 ++- 3 files changed, 269 insertions(+), 8 deletions(-) create mode 100644 packages/destination-actions/src/destinations/customerio/__tests__/createUpdateObject.test.ts diff --git a/packages/destination-actions/src/destinations/customerio/__tests__/createUpdateObject.test.ts b/packages/destination-actions/src/destinations/customerio/__tests__/createUpdateObject.test.ts new file mode 100644 index 0000000000..aca02264fb --- /dev/null +++ b/packages/destination-actions/src/destinations/customerio/__tests__/createUpdateObject.test.ts @@ -0,0 +1,235 @@ +import nock from 'nock' +import { createTestEvent, createTestIntegration } from '@segment/actions-core' +import CustomerIO from '../index' +import { Settings } from '../generated-types' +import dayjs from '../../../lib/dayjs' +import { AccountRegion } from '../utils' + +const testDestination = createTestIntegration(CustomerIO) +const trackObjectService = nock('https://track.customer.io') + +describe('CustomerIO', () => { + describe('createUpdateObject', () => { + it('should work with default mappings when userId is supplied', async () => { + const settings: Settings = { + siteId: '12345', + apiKey: 'abcde', + accountRegion: AccountRegion.US + } + const userId = 'abc123' + const anonymousId = 'unknown_123' + const timestamp = dayjs.utc().toISOString() + const groupId = 'grp123' + const traits = { + name: 'Sales', + created_at: timestamp, + object_type_id: '1' + } + trackObjectService.post(`/api/v2/profile`).reply(200, {}, { 'x-customerio-region': 'US' }) + const event = createTestEvent({ + userId, + anonymousId, + timestamp, + traits, + groupId + }) + const responses = await testDestination.testAction('createUpdateObject', { + event, + settings, + useDefaultMappings: true + }) + + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + expect(responses[0].headers.toJSON()).toMatchObject({ + 'x-customerio-region': 'US', + 'content-type': 'application/json' + }) + expect(responses[0].data).toMatchObject({}) + }) + + it('should work with the EU account region', async () => { + const trackEUObjectService = nock('https://track-eu.customer.io') + const settings: Settings = { + siteId: '12345', + apiKey: 'abcde', + accountRegion: AccountRegion.EU + } + const userId = 'abc123' + const anonymousId = 'unknown_123' + const timestamp = dayjs.utc().toISOString() + const groupId = 'grp123' + const traits = { + name: 'Sales', + created_at: timestamp, + object_type_id: '1' + } + trackEUObjectService.post(`/api/v2/profile`).reply(200, {}, { 'x-customerio-region': 'EU' }) + const event = createTestEvent({ + userId, + anonymousId, + timestamp, + traits, + groupId + }) + const responses = await testDestination.testAction('createUpdateObject', { + event, + settings, + useDefaultMappings: true + }) + + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + expect(responses[0].headers.toJSON()).toMatchObject({ + 'x-customerio-region': 'EU', + 'content-type': 'application/json' + }) + expect(responses[0].data).toMatchObject({}) + }) + + it('should fall back to the US account region', async () => { + const settings: Settings = { + siteId: '12345', + apiKey: 'abcde' + } + const userId = 'abc123' + const anonymousId = 'unknown_123' + const timestamp = dayjs.utc().toISOString() + const groupId = 'grp123' + const traits = { + name: 'Sales', + created_at: timestamp, + object_type_id: '1' + } + trackObjectService.post(`/api/v2/profile`).reply(200, {}, { 'x-customerio-region': 'US-fallback' }) + const event = createTestEvent({ + userId, + anonymousId, + timestamp, + traits, + groupId + }) + const responses = await testDestination.testAction('createUpdateObject', { + event, + settings, + useDefaultMappings: true + }) + + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + expect(responses[0].headers.toJSON()).toMatchObject({ + 'x-customerio-region': 'US-fallback', + 'content-type': 'application/json' + }) + expect(responses[0].data).toMatchObject({}) + }) + + it('should work with anonymous id when userId is not supplied', async () => { + const settings: Settings = { + siteId: '12345', + apiKey: 'abcde', + accountRegion: AccountRegion.US + } + const anonymousId = 'unknown_123' + const timestamp = dayjs.utc().toISOString() + const groupId = 'grp123' + const traits = { + name: 'Sales', + created_at: timestamp, + object_type_id: '1' + } + trackObjectService.post(`/api/v2/profile`).reply(200, {}, { 'x-customerio-region': 'US' }) + const event = createTestEvent({ + userId: undefined, + anonymousId, + timestamp, + traits, + groupId + }) + const responses = await testDestination.testAction('createUpdateObject', { + event, + settings, + useDefaultMappings: true + }) + + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + expect(responses[0].headers.toJSON()).toMatchObject({ + 'x-customerio-region': 'US', + 'content-type': 'application/json' + }) + expect(responses[0].data).toMatchObject({}) + }) + + it('should work with default object_type_id when object_type_id is not supplied', async () => { + const settings: Settings = { + siteId: '12345', + apiKey: 'abcde', + accountRegion: AccountRegion.US + } + const anonymousId = 'unknown_123' + const timestamp = dayjs.utc().toISOString() + const groupId = 'grp123' + const traits = { + name: 'Sales', + created_at: timestamp + } + trackObjectService.post(`/api/v2/profile`).reply(200, {}, { 'x-customerio-region': 'US' }) + const event = createTestEvent({ + userId: undefined, + anonymousId, + timestamp, + traits, + groupId + }) + const responses = await testDestination.testAction('createUpdateObject', { + event, + settings, + useDefaultMappings: true + }) + + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + expect(responses[0].headers.toJSON()).toMatchObject({ + 'x-customerio-region': 'US', + 'content-type': 'application/json' + }) + expect(responses[0].data).toMatchObject({}) + }) + + it('should work when no created_at is given', async () => { + const settings: Settings = { + siteId: '12345', + apiKey: 'abcde', + accountRegion: AccountRegion.US + } + const anonymousId = 'unknown_123' + const timestamp = dayjs.utc().toISOString() + const groupId = 'grp123' + const traits = { + name: 'Sales' + } + trackObjectService.post(`/api/v2/profile`).reply(200, {}, { 'x-customerio-region': 'US' }) + const event = createTestEvent({ + userId: undefined, + anonymousId, + timestamp, + traits, + groupId + }) + const responses = await testDestination.testAction('createUpdateObject', { + event, + settings, + useDefaultMappings: true + }) + + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + expect(responses[0].headers.toJSON()).toMatchObject({ + 'x-customerio-region': 'US', + 'content-type': 'application/json' + }) + expect(responses[0].data).toMatchObject({}) + }) + }) +}) diff --git a/packages/destination-actions/src/destinations/customerio/createUpdateObject/generated-types.ts b/packages/destination-actions/src/destinations/customerio/createUpdateObject/generated-types.ts index 08995f480d..aeaabb3699 100644 --- a/packages/destination-actions/src/destinations/customerio/createUpdateObject/generated-types.ts +++ b/packages/destination-actions/src/destinations/customerio/createUpdateObject/generated-types.ts @@ -2,7 +2,7 @@ export interface Payload { /** - * The ID used to uniquely identify an object in Customer.io. + * The ID used to uniquely identify an object in Customer.io. [Learn more](https://customer.io/docs/object-relationships). */ id: string /** @@ -16,9 +16,13 @@ export interface Payload { [k: string]: unknown } /** - * The ID used to relate user to an object in Customer.io. + * The ID used to relate user to an object in Customer.io. [Learn more](https://customer.io/docs/identifying-people/#identifiers). */ user_id?: string + /** + * An anonymous ID for when no Person ID exists. [Learn more](https://customer.io/docs/anonymous-events/). + */ + anonymous_id?: string /** * Convert dates to Unix timestamps (seconds since Epoch). */ diff --git a/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts b/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts index 0c27e5fcc2..f6aeebdb58 100644 --- a/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts +++ b/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts @@ -10,7 +10,8 @@ const action: ActionDefinition = { fields: { id: { label: 'Object ID', - description: 'The ID used to uniquely identify an object in Customer.io.', + description: + 'The ID used to uniquely identify an object in Customer.io. [Learn more](https://customer.io/docs/object-relationships).', type: 'string', required: true, default: { @@ -36,12 +37,22 @@ const action: ActionDefinition = { }, user_id: { label: 'User ID', - description: 'The ID used to relate user to an object in Customer.io.', + description: + 'The ID used to relate user to an object in Customer.io. [Learn more](https://customer.io/docs/identifying-people/#identifiers).', type: 'string', default: { '@path': '$.userId' } }, + anonymous_id: { + label: 'Anonymous ID', + description: + 'An anonymous ID for when no Person ID exists. [Learn more](https://customer.io/docs/anonymous-events/).', + type: 'string', + default: { + '@path': '$.anonymousId' + } + }, convert_timestamp: { label: 'Convert Timestamps', description: 'Convert dates to Unix timestamps (seconds since Epoch).', @@ -54,6 +65,7 @@ const action: ActionDefinition = { let customAttributes = payload.custom_attributes const userID = payload.user_id const objectID = payload.id + const anonymousId = payload.anonymous_id if (payload.convert_timestamp !== false) { if (createdAt) { createdAt = convertValidTimestamp(createdAt) @@ -67,16 +79,26 @@ const action: ActionDefinition = { const body: Record = { ...customAttributes } + let typeID + if (customAttributes) { + typeID = customAttributes.object_type_id + } if (createdAt) { body.created_at = createdAt } body.type = 'object' - body.action = 'identify' - body.identifiers = { type_id: '1', id: objectID } - body.cio_relationships = [{ identifiers: { id: userID } }] + body.identifiers = { type_id: typeID ?? '1', id: objectID } + + if (userID) { + body.action = 'identify' + body.cio_relationships = [{ identifiers: { id: userID } }] + } else { + body.action = 'identify_anonymous' + body.cio_relationships = [{ identifiers: { anonymous_id: anonymousId } }] + } - return request(`${trackApiEndpoint(settings.accountRegion)}/alpha-api/v2/profile`, { + return request(`${trackApiEndpoint(settings.accountRegion)}/api/v2/profile`, { method: 'post', json: body }) From 77d21076fbe0c485b551ecfd4f222ec5f96d0283 Mon Sep 17 00:00:00 2001 From: kishoredevarasettyn Date: Wed, 14 Dec 2022 23:01:06 +0530 Subject: [PATCH 3/8] Adding Tests validation for the payload --- .../__tests__/createUpdateObject.test.ts | 77 ++++++++++++++++++- .../customerio/createUpdateObject/index.ts | 6 +- .../src/destinations/customerio/index.ts | 3 +- 3 files changed, 78 insertions(+), 8 deletions(-) diff --git a/packages/destination-actions/src/destinations/customerio/__tests__/createUpdateObject.test.ts b/packages/destination-actions/src/destinations/customerio/__tests__/createUpdateObject.test.ts index aca02264fb..f74e78514d 100644 --- a/packages/destination-actions/src/destinations/customerio/__tests__/createUpdateObject.test.ts +++ b/packages/destination-actions/src/destinations/customerio/__tests__/createUpdateObject.test.ts @@ -22,6 +22,7 @@ describe('CustomerIO', () => { const groupId = 'grp123' const traits = { name: 'Sales', + industry: 'Technology', created_at: timestamp, object_type_id: '1' } @@ -46,6 +47,17 @@ describe('CustomerIO', () => { 'content-type': 'application/json' }) expect(responses[0].data).toMatchObject({}) + expect(responses[0].options.json).toMatchObject({ + ...traits, + created_at: dayjs.utc(timestamp).unix(), + type: 'object', + action: 'identify', + identifiers: { + type_id: traits.object_type_id, + id: groupId + }, + cio_relationships: [{ identifiers: { id: userId } }] + }) }) it('should work with the EU account region', async () => { @@ -61,6 +73,7 @@ describe('CustomerIO', () => { const groupId = 'grp123' const traits = { name: 'Sales', + industry: 'Technology', created_at: timestamp, object_type_id: '1' } @@ -85,6 +98,17 @@ describe('CustomerIO', () => { 'content-type': 'application/json' }) expect(responses[0].data).toMatchObject({}) + expect(responses[0].options.json).toMatchObject({ + ...traits, + created_at: dayjs.utc(timestamp).unix(), + type: 'object', + action: 'identify', + identifiers: { + type_id: traits.object_type_id, + id: groupId + }, + cio_relationships: [{ identifiers: { id: userId } }] + }) }) it('should fall back to the US account region', async () => { @@ -98,6 +122,7 @@ describe('CustomerIO', () => { const groupId = 'grp123' const traits = { name: 'Sales', + industry: 'Technology', created_at: timestamp, object_type_id: '1' } @@ -122,6 +147,17 @@ describe('CustomerIO', () => { 'content-type': 'application/json' }) expect(responses[0].data).toMatchObject({}) + expect(responses[0].options.json).toMatchObject({ + ...traits, + created_at: dayjs.utc(timestamp).unix(), + type: 'object', + action: 'identify', + identifiers: { + type_id: traits.object_type_id, + id: groupId + }, + cio_relationships: [{ identifiers: { id: userId } }] + }) }) it('should work with anonymous id when userId is not supplied', async () => { @@ -159,6 +195,17 @@ describe('CustomerIO', () => { 'content-type': 'application/json' }) expect(responses[0].data).toMatchObject({}) + expect(responses[0].options.json).toMatchObject({ + ...traits, + created_at: dayjs.utc(timestamp).unix(), + type: 'object', + action: 'identify_anonymous', + identifiers: { + type_id: traits.object_type_id, + id: groupId + }, + cio_relationships: [{ identifiers: { anonymous_id: anonymousId } }] + }) }) it('should work with default object_type_id when object_type_id is not supplied', async () => { @@ -167,6 +214,7 @@ describe('CustomerIO', () => { apiKey: 'abcde', accountRegion: AccountRegion.US } + const userId = 'abc123' const anonymousId = 'unknown_123' const timestamp = dayjs.utc().toISOString() const groupId = 'grp123' @@ -176,7 +224,7 @@ describe('CustomerIO', () => { } trackObjectService.post(`/api/v2/profile`).reply(200, {}, { 'x-customerio-region': 'US' }) const event = createTestEvent({ - userId: undefined, + userId, anonymousId, timestamp, traits, @@ -195,6 +243,17 @@ describe('CustomerIO', () => { 'content-type': 'application/json' }) expect(responses[0].data).toMatchObject({}) + expect(responses[0].options.json).toMatchObject({ + ...traits, + created_at: dayjs.utc(timestamp).unix(), + type: 'object', + action: 'identify', + identifiers: { + type_id: '1', + id: groupId + }, + cio_relationships: [{ identifiers: { id: userId } }] + }) }) it('should work when no created_at is given', async () => { @@ -203,15 +262,17 @@ describe('CustomerIO', () => { apiKey: 'abcde', accountRegion: AccountRegion.US } + const userId = 'abc123' const anonymousId = 'unknown_123' const timestamp = dayjs.utc().toISOString() const groupId = 'grp123' const traits = { - name: 'Sales' + name: 'Sales', + object_type_id: '1' } trackObjectService.post(`/api/v2/profile`).reply(200, {}, { 'x-customerio-region': 'US' }) const event = createTestEvent({ - userId: undefined, + userId, anonymousId, timestamp, traits, @@ -230,6 +291,16 @@ describe('CustomerIO', () => { 'content-type': 'application/json' }) expect(responses[0].data).toMatchObject({}) + expect(responses[0].options.json).toMatchObject({ + ...traits, + type: 'object', + action: 'identify', + identifiers: { + type_id: traits.object_type_id, + id: groupId + }, + cio_relationships: [{ identifiers: { id: userId } }] + }) }) }) }) diff --git a/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts b/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts index f6aeebdb58..03cc84f0aa 100644 --- a/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts +++ b/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts @@ -20,7 +20,7 @@ const action: ActionDefinition = { }, created_at: { label: 'Created At', - description: 'A timestamp of when the person was created.', + description: 'A timestamp of when the object was created.', type: 'string', default: { '@template': '{{traits.created_at}}' @@ -38,7 +38,7 @@ const action: ActionDefinition = { user_id: { label: 'User ID', description: - 'The ID used to relate user to an object in Customer.io. [Learn more](https://customer.io/docs/identifying-people/#identifiers).', + 'The ID used to relate a user to an object in Customer.io. [Learn more](https://customer.io/docs/identifying-people/#identifiers).', type: 'string', default: { '@path': '$.userId' @@ -47,7 +47,7 @@ const action: ActionDefinition = { anonymous_id: { label: 'Anonymous ID', description: - 'An anonymous ID for when no Person ID exists. [Learn more](https://customer.io/docs/anonymous-events/).', + 'An anonymous ID to relate to an object when no Person ID exists. [Learn more](https://customer.io/docs/anonymous-events/).', type: 'string', default: { '@path': '$.anonymousId' diff --git a/packages/destination-actions/src/destinations/customerio/index.ts b/packages/destination-actions/src/destinations/customerio/index.ts index 8403165793..e8e38d4538 100644 --- a/packages/destination-actions/src/destinations/customerio/index.ts +++ b/packages/destination-actions/src/destinations/customerio/index.ts @@ -5,12 +5,11 @@ import createUpdatePerson from './createUpdatePerson' import trackEvent from './trackEvent' import trackPageView from './trackPageView' import trackScreenView from './trackScreenView' +import createUpdateObject from './createUpdateObject' import type { DestinationDefinition } from '@segment/actions-core' import type { Settings } from './generated-types' import { AccountRegion, trackApiEndpoint } from './utils' -import createUpdateObject from './createUpdateObject' - const destination: DestinationDefinition = { name: 'Actions Customerio', mode: 'cloud', From 943658baad2a54c114f8afb7a35077dcc47165a8 Mon Sep 17 00:00:00 2001 From: kishoredevarasettyn Date: Wed, 14 Dec 2022 23:34:25 +0530 Subject: [PATCH 4/8] committing generate type file --- .../customerio/createUpdateObject/generated-types.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/destination-actions/src/destinations/customerio/createUpdateObject/generated-types.ts b/packages/destination-actions/src/destinations/customerio/createUpdateObject/generated-types.ts index aeaabb3699..0a301f3d79 100644 --- a/packages/destination-actions/src/destinations/customerio/createUpdateObject/generated-types.ts +++ b/packages/destination-actions/src/destinations/customerio/createUpdateObject/generated-types.ts @@ -6,7 +6,7 @@ export interface Payload { */ id: string /** - * A timestamp of when the person was created. + * A timestamp of when the object was created. */ created_at?: string /** @@ -16,11 +16,11 @@ export interface Payload { [k: string]: unknown } /** - * The ID used to relate user to an object in Customer.io. [Learn more](https://customer.io/docs/identifying-people/#identifiers). + * The ID used to relate a user to an object in Customer.io. [Learn more](https://customer.io/docs/identifying-people/#identifiers). */ user_id?: string /** - * An anonymous ID for when no Person ID exists. [Learn more](https://customer.io/docs/anonymous-events/). + * An anonymous ID to relate to an object when no Person ID exists. [Learn more](https://customer.io/docs/anonymous-events/). */ anonymous_id?: string /** From 94aec879492a0928b9ab8670019fdda4f8c23fe1 Mon Sep 17 00:00:00 2001 From: kishoredevarasettyn Date: Mon, 19 Dec 2022 20:59:28 +0530 Subject: [PATCH 5/8] Adding group support from identify --- .../__tests__/createUpdateObject.test.ts | 15 ++--- .../__tests__/createUpdatePerson.test.ts | 59 +++++++++++++++++++ .../createUpdateObject/generated-types.ts | 4 ++ .../customerio/createUpdateObject/index.ts | 17 ++++-- .../createUpdatePerson/generated-types.ts | 8 +++ .../customerio/createUpdatePerson/index.ts | 28 +++++++++ 6 files changed, 118 insertions(+), 13 deletions(-) diff --git a/packages/destination-actions/src/destinations/customerio/__tests__/createUpdateObject.test.ts b/packages/destination-actions/src/destinations/customerio/__tests__/createUpdateObject.test.ts index f74e78514d..0d14e57ac3 100644 --- a/packages/destination-actions/src/destinations/customerio/__tests__/createUpdateObject.test.ts +++ b/packages/destination-actions/src/destinations/customerio/__tests__/createUpdateObject.test.ts @@ -26,7 +26,7 @@ describe('CustomerIO', () => { created_at: timestamp, object_type_id: '1' } - trackObjectService.post(`/api/v2/profile`).reply(200, {}, { 'x-customerio-region': 'US' }) + trackObjectService.post(`/api/v2/entity`).reply(200, {}, { 'x-customerio-region': 'US' }) const event = createTestEvent({ userId, anonymousId, @@ -77,7 +77,7 @@ describe('CustomerIO', () => { created_at: timestamp, object_type_id: '1' } - trackEUObjectService.post(`/api/v2/profile`).reply(200, {}, { 'x-customerio-region': 'EU' }) + trackEUObjectService.post(`/api/v2/entity`).reply(200, {}, { 'x-customerio-region': 'EU' }) const event = createTestEvent({ userId, anonymousId, @@ -126,7 +126,7 @@ describe('CustomerIO', () => { created_at: timestamp, object_type_id: '1' } - trackObjectService.post(`/api/v2/profile`).reply(200, {}, { 'x-customerio-region': 'US-fallback' }) + trackObjectService.post(`/api/v2/entity`).reply(200, {}, { 'x-customerio-region': 'US-fallback' }) const event = createTestEvent({ userId, anonymousId, @@ -174,7 +174,7 @@ describe('CustomerIO', () => { created_at: timestamp, object_type_id: '1' } - trackObjectService.post(`/api/v2/profile`).reply(200, {}, { 'x-customerio-region': 'US' }) + trackObjectService.post(`/api/v2/entity`).reply(200, {}, { 'x-customerio-region': 'US' }) const event = createTestEvent({ userId: undefined, anonymousId, @@ -222,7 +222,7 @@ describe('CustomerIO', () => { name: 'Sales', created_at: timestamp } - trackObjectService.post(`/api/v2/profile`).reply(200, {}, { 'x-customerio-region': 'US' }) + trackObjectService.post(`/api/v2/entity`).reply(200, {}, { 'x-customerio-region': 'US' }) const event = createTestEvent({ userId, anonymousId, @@ -266,11 +266,12 @@ describe('CustomerIO', () => { const anonymousId = 'unknown_123' const timestamp = dayjs.utc().toISOString() const groupId = 'grp123' + const typeId = '1' const traits = { name: 'Sales', object_type_id: '1' } - trackObjectService.post(`/api/v2/profile`).reply(200, {}, { 'x-customerio-region': 'US' }) + trackObjectService.post(`/api/v2/entity`).reply(200, {}, { 'x-customerio-region': 'US' }) const event = createTestEvent({ userId, anonymousId, @@ -296,7 +297,7 @@ describe('CustomerIO', () => { type: 'object', action: 'identify', identifiers: { - type_id: traits.object_type_id, + type_id: typeId, id: groupId }, cio_relationships: [{ identifiers: { id: userId } }] diff --git a/packages/destination-actions/src/destinations/customerio/__tests__/createUpdatePerson.test.ts b/packages/destination-actions/src/destinations/customerio/__tests__/createUpdatePerson.test.ts index 8feb3549f9..1bd3bc7e49 100644 --- a/packages/destination-actions/src/destinations/customerio/__tests__/createUpdatePerson.test.ts +++ b/packages/destination-actions/src/destinations/customerio/__tests__/createUpdatePerson.test.ts @@ -61,7 +61,66 @@ describe('CustomerIO', () => { } }) }) + it('should work with default mappings when userId and groupId are supplied', async () => { + const settings: Settings = { + siteId: '12345', + apiKey: 'abcde', + accountRegion: AccountRegion.US + } + const userId = 'abc123' + const anonymousId = 'unknown_123' + const timestamp = dayjs.utc().toISOString() + const birthdate = dayjs.utc('1990-01-01T00:00:00Z').toISOString() + const groupId = 'g12345' + const traits = { + full_name: 'Test User', + email: 'test@example.com', + created_at: timestamp, + person: { + over18: true, + identification: 'valid', + birthdate + } + } + const context = { + groupId: groupId + } + trackDeviceService.put(`/customers/${userId}`).reply(200, {}, { 'x-customerio-region': 'US' }) + const event = createTestEvent({ + userId, + anonymousId, + timestamp, + traits, + context + }) + const responses = await testDestination.testAction('createUpdatePerson', { + event, + settings, + useDefaultMappings: true + }) + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + expect(responses[0].headers.toJSON()).toMatchObject({ + 'x-customerio-region': 'US', + 'content-type': 'application/json' + }) + expect(responses[0].data).toMatchObject({}) + expect(responses[0].options.json).toMatchObject({ + ...traits, + email: traits.email, + created_at: dayjs.utc(timestamp).unix(), + anonymous_id: anonymousId, + person: { + ...traits.person, + birthdate: dayjs.utc(birthdate).unix() + }, + cio_relationships: { + action: 'add_relationships', + relationships: [{ identifiers: { type_id: '1', id: groupId } }] + } + }) + }) it('should convert only ISO-8601 strings', async () => { const settings: Settings = { siteId: '12345', diff --git a/packages/destination-actions/src/destinations/customerio/createUpdateObject/generated-types.ts b/packages/destination-actions/src/destinations/customerio/createUpdateObject/generated-types.ts index 0a301f3d79..d18aeb3f35 100644 --- a/packages/destination-actions/src/destinations/customerio/createUpdateObject/generated-types.ts +++ b/packages/destination-actions/src/destinations/customerio/createUpdateObject/generated-types.ts @@ -23,6 +23,10 @@ export interface Payload { * An anonymous ID to relate to an object when no Person ID exists. [Learn more](https://customer.io/docs/anonymous-events/). */ anonymous_id?: string + /** + * The ID used to uniquely identify a custom object type in Customer.io. [Learn more](https://customer.io/docs/object-relationships). + */ + type_id?: string /** * Convert dates to Unix timestamps (seconds since Epoch). */ diff --git a/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts b/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts index 03cc84f0aa..e105acd218 100644 --- a/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts +++ b/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts @@ -53,6 +53,15 @@ const action: ActionDefinition = { '@path': '$.anonymousId' } }, + type_id: { + label: 'Object Type Id', + description: + 'The ID used to uniquely identify a custom object type in Customer.io. [Learn more](https://customer.io/docs/object-relationships).', + type: 'string', + default: { + '@path': '$.typeId' + } + }, convert_timestamp: { label: 'Convert Timestamps', description: 'Convert dates to Unix timestamps (seconds since Epoch).', @@ -63,6 +72,7 @@ const action: ActionDefinition = { perform: (request, { settings, payload }) => { let createdAt: string | number | undefined = payload.created_at let customAttributes = payload.custom_attributes + const typeID = payload.type_id const userID = payload.user_id const objectID = payload.id const anonymousId = payload.anonymous_id @@ -79,11 +89,6 @@ const action: ActionDefinition = { const body: Record = { ...customAttributes } - let typeID - if (customAttributes) { - typeID = customAttributes.object_type_id - } - if (createdAt) { body.created_at = createdAt } @@ -98,7 +103,7 @@ const action: ActionDefinition = { body.cio_relationships = [{ identifiers: { anonymous_id: anonymousId } }] } - return request(`${trackApiEndpoint(settings.accountRegion)}/api/v2/profile`, { + return request(`${trackApiEndpoint(settings.accountRegion)}/api/v2/entity`, { method: 'post', json: body }) diff --git a/packages/destination-actions/src/destinations/customerio/createUpdatePerson/generated-types.ts b/packages/destination-actions/src/destinations/customerio/createUpdatePerson/generated-types.ts index 8a7eced3fa..878b24dc01 100644 --- a/packages/destination-actions/src/destinations/customerio/createUpdatePerson/generated-types.ts +++ b/packages/destination-actions/src/destinations/customerio/createUpdatePerson/generated-types.ts @@ -17,6 +17,10 @@ export interface Payload { * A timestamp of when the person was created. */ created_at?: string + /** + * The ID used to uniquely identify an object in Customer.io. [Learn more](https://customer.io/docs/object-relationships). + */ + group_id?: string /** * Optional attributes for the person. When updating a person, attributes are added or updated, not removed. */ @@ -27,4 +31,8 @@ export interface Payload { * Convert dates to Unix timestamps (seconds since Epoch). */ convert_timestamp?: boolean + /** + * The ID used to uniquely identify a custom object type in Customer.io. [Learn more](https://customer.io/docs/object-relationships). + */ + object_type_id?: string } diff --git a/packages/destination-actions/src/destinations/customerio/createUpdatePerson/index.ts b/packages/destination-actions/src/destinations/customerio/createUpdatePerson/index.ts index 3d7f13eb9e..0b7b4234d8 100644 --- a/packages/destination-actions/src/destinations/customerio/createUpdatePerson/index.ts +++ b/packages/destination-actions/src/destinations/customerio/createUpdatePerson/index.ts @@ -43,6 +43,15 @@ const action: ActionDefinition = { '@template': '{{traits.created_at}}' } }, + group_id: { + label: 'Object ID', + description: + 'The ID used to uniquely identify an object in Customer.io. [Learn more](https://customer.io/docs/object-relationships).', + type: 'string', + default: { + '@template': '{{context.groupId}}' + } + }, custom_attributes: { label: 'Person Attributes', description: @@ -57,12 +66,23 @@ const action: ActionDefinition = { description: 'Convert dates to Unix timestamps (seconds since Epoch).', type: 'boolean', default: true + }, + object_type_id: { + label: 'Object Type Id', + description: + 'The ID used to uniquely identify a custom object type in Customer.io. [Learn more](https://customer.io/docs/object-relationships).', + type: 'string', + default: { + '@path': '$.objectTypeId' + } } }, perform: (request, { settings, payload }) => { let createdAt: string | number | undefined = payload.created_at let customAttributes = payload.custom_attributes + const objectId = payload.group_id + const objectTypeId = payload.object_type_id if (payload.convert_timestamp !== false) { if (createdAt) { @@ -84,6 +104,14 @@ const action: ActionDefinition = { body.created_at = createdAt } + // Adding Object Person relationship if group_id exists in the call. If the object_type_id is not given, default it to "1" + if (objectId) { + body.cio_relationships = { + action: 'add_relationships', + relationships: [{ identifiers: { type_id: objectTypeId ?? '1', id: objectId } }] + } + } + return request(`${trackApiEndpoint(settings.accountRegion)}/api/v1/customers/${payload.id}`, { method: 'put', json: body From cb8bdb2323428d16ead78e67bee8e77a7be74dea Mon Sep 17 00:00:00 2001 From: kishoredevarasettyn Date: Mon, 19 Dec 2022 22:13:52 +0530 Subject: [PATCH 6/8] Fixing conflicts --- .../__tests__/createUpdatePerson.test.ts | 81 +++++++++-- .../customerio/__tests__/delete.test.ts | 132 ++++++++++++++---- .../customerio/createUpdatePerson/index.ts | 6 +- .../src/destinations/customerio/index.ts | 1 + 4 files changed, 175 insertions(+), 45 deletions(-) diff --git a/packages/destination-actions/src/destinations/customerio/__tests__/createUpdatePerson.test.ts b/packages/destination-actions/src/destinations/customerio/__tests__/createUpdatePerson.test.ts index 1bd3bc7e49..a89b4207f8 100644 --- a/packages/destination-actions/src/destinations/customerio/__tests__/createUpdatePerson.test.ts +++ b/packages/destination-actions/src/destinations/customerio/__tests__/createUpdatePerson.test.ts @@ -61,17 +61,16 @@ describe('CustomerIO', () => { } }) }) - it('should work with default mappings when userId and groupId are supplied', async () => { + + it('should use email as the identifier if userId is not present', async () => { const settings: Settings = { siteId: '12345', apiKey: 'abcde', accountRegion: AccountRegion.US } - const userId = 'abc123' const anonymousId = 'unknown_123' const timestamp = dayjs.utc().toISOString() const birthdate = dayjs.utc('1990-01-01T00:00:00Z').toISOString() - const groupId = 'g12345' const traits = { full_name: 'Test User', email: 'test@example.com', @@ -82,16 +81,12 @@ describe('CustomerIO', () => { birthdate } } - const context = { - groupId: groupId - } - trackDeviceService.put(`/customers/${userId}`).reply(200, {}, { 'x-customerio-region': 'US' }) + trackDeviceService.put(`/customers/${traits.email}`).reply(200, {}, { 'x-customerio-region': 'US' }) const event = createTestEvent({ - userId, + userId: null, anonymousId, timestamp, - traits, - context + traits }) const responses = await testDestination.testAction('createUpdatePerson', { event, @@ -114,13 +109,10 @@ describe('CustomerIO', () => { person: { ...traits.person, birthdate: dayjs.utc(birthdate).unix() - }, - cio_relationships: { - action: 'add_relationships', - relationships: [{ identifiers: { type_id: '1', id: groupId } }] } }) }) + it('should convert only ISO-8601 strings', async () => { const settings: Settings = { siteId: '12345', @@ -414,5 +406,66 @@ describe('CustomerIO', () => { anonymous_id: anonymousId }) }) + + it('should work with default mappings when userId and groupId are supplied', async () => { + const settings: Settings = { + siteId: '12345', + apiKey: 'abcde', + accountRegion: AccountRegion.US + } + const userId = 'abc123' + const anonymousId = 'unknown_123' + const timestamp = dayjs.utc().toISOString() + const birthdate = dayjs.utc('1990-01-01T00:00:00Z').toISOString() + const groupId = 'g12345' + const traits = { + full_name: 'Test User', + email: 'test@example.com', + created_at: timestamp, + person: { + over18: true, + identification: 'valid', + birthdate + } + } + const context = { + groupId: groupId + } + trackDeviceService.put(`/customers/${userId}`).reply(200, {}, { 'x-customerio-region': 'US' }) + const event = createTestEvent({ + userId, + anonymousId, + timestamp, + traits, + context + }) + const responses = await testDestination.testAction('createUpdatePerson', { + event, + settings, + useDefaultMappings: true + }) + + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + expect(responses[0].headers.toJSON()).toMatchObject({ + 'x-customerio-region': 'US', + 'content-type': 'application/json' + }) + expect(responses[0].data).toMatchObject({}) + expect(responses[0].options.json).toMatchObject({ + ...traits, + email: traits.email, + created_at: dayjs.utc(timestamp).unix(), + anonymous_id: anonymousId, + person: { + ...traits.person, + birthdate: dayjs.utc(birthdate).unix() + }, + cio_relationships: { + action: 'add_relationships', + relationships: [{ identifiers: { type_id: '1', id: groupId } }] + } + }) + }) }) }) diff --git a/packages/destination-actions/src/destinations/customerio/__tests__/delete.test.ts b/packages/destination-actions/src/destinations/customerio/__tests__/delete.test.ts index c180627787..1e41cac701 100644 --- a/packages/destination-actions/src/destinations/customerio/__tests__/delete.test.ts +++ b/packages/destination-actions/src/destinations/customerio/__tests__/delete.test.ts @@ -1,41 +1,113 @@ import nock from 'nock' -import { createTestIntegration } from '@segment/actions-core' +import { createTestEvent, createTestIntegration } from '@segment/actions-core' import CustomerIO from '../index' -import { DecoratedResponse } from '@segment/actions-core' +import { Settings } from '../generated-types' import { AccountRegion } from '../utils' const testDestination = createTestIntegration(CustomerIO) +const trackService = nock('https://track.customer.io/api/v1') -describe('Customer.io', () => { - describe('onDelete', () => { - it('should support user deletions, defaulting to the US', async () => { - nock('https://track.customer.io').delete('/api/v1/customers/sloth@segment.com').reply(200, {}) - expect(testDestination.onDelete).toBeDefined() +describe('CustomerIO', () => { + describe('deleteDevice', () => { + it('should work with default mappings when userId is supplied', async () => { + const settings: Settings = { + siteId: '12345', + apiKey: 'abcde', + accountRegion: AccountRegion.US + } + const userId = 'abc123' + const deviceId = 'device_123' + trackService.delete(`/customers/${userId}/devices/${deviceId}`).reply(200, {}, { 'x-customerio-region': 'US' }) + const event = createTestEvent({ + userId, + context: { + device: { + token: deviceId + } + } + }) + const responses = await testDestination.testAction('deleteDevice', { + event, + settings, + useDefaultMappings: true + }) - if (testDestination.onDelete) { - const response = await testDestination?.onDelete( - { type: 'track', userId: 'sloth@segment.com' }, - { siteId: 'foo', apiKey: 'bar' } - ) - const resp = response as DecoratedResponse - expect(resp.status).toBe(200) - expect(resp.data).toMatchObject({}) - } - }) + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + expect(responses[0].headers.toJSON()).toMatchObject({ + 'x-customerio-region': 'US', + 'content-type': 'application/json' + }) + expect(responses[0].data).toMatchObject({}) + expect(responses[0].options.json).toBeUndefined() + }) + + it('should work with the EU account region', async () => { + const trackEUService = nock('https://track-eu.customer.io/api/v1') + const settings: Settings = { + siteId: '12345', + apiKey: 'abcde', + accountRegion: AccountRegion.EU + } + const userId = 'abc123' + const deviceId = 'device_123' + trackEUService.delete(`/customers/${userId}/devices/${deviceId}`).reply(200, {}, { 'x-customerio-region': 'EU' }) + const event = createTestEvent({ + userId, + context: { + device: { + token: deviceId + } + } + }) + const responses = await testDestination.testAction('deleteDevice', { + event, + settings, + useDefaultMappings: true + }) + + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + expect(responses[0].headers.toJSON()).toMatchObject({ + 'x-customerio-region': 'EU', + 'content-type': 'application/json' + }) + expect(responses[0].data).toMatchObject({}) + expect(responses[0].options.json).toBeUndefined() + }) - it('should support regional user deletions', async () => { - nock('https://track-eu.customer.io').delete('/api/v1/customers/sloth@segment.com').reply(200, {}) - expect(testDestination.onDelete).toBeDefined() + it('should fall back to the US account region', async () => { + const settings: Settings = { + siteId: '12345', + apiKey: 'abcde' + } + const userId = 'abc123' + const deviceId = 'device_123' + trackService + .delete(`/customers/${userId}/devices/${deviceId}`) + .reply(200, {}, { 'x-customerio-region': 'US-fallback' }) + const event = createTestEvent({ + userId, + context: { + device: { + token: deviceId + } + } + }) + const responses = await testDestination.testAction('deleteDevice', { + event, + settings, + useDefaultMappings: true + }) - if (testDestination.onDelete) { - const response = await testDestination?.onDelete( - { type: 'track', userId: 'sloth@segment.com' }, - { siteId: 'foo', apiKey: 'bar', accountRegion: AccountRegion.EU } - ) - const resp = response as DecoratedResponse - expect(resp.status).toBe(200) - expect(resp.data).toMatchObject({}) - } - }) + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + expect(responses[0].headers.toJSON()).toMatchObject({ + 'x-customerio-region': 'US-fallback', + 'content-type': 'application/json' + }) + expect(responses[0].data).toMatchObject({}) + expect(responses[0].options.json).toBeUndefined() }) + }) }) diff --git a/packages/destination-actions/src/destinations/customerio/createUpdatePerson/index.ts b/packages/destination-actions/src/destinations/customerio/createUpdatePerson/index.ts index 0b7b4234d8..67b6585c24 100644 --- a/packages/destination-actions/src/destinations/customerio/createUpdatePerson/index.ts +++ b/packages/destination-actions/src/destinations/customerio/createUpdatePerson/index.ts @@ -15,7 +15,11 @@ const action: ActionDefinition = { type: 'string', required: true, default: { - '@path': '$.userId' + '@if': { + exists: { '@path': '$.userId' }, + then: { '@path': '$.userId' }, + else: { '@path': '$.traits.email' } + } } }, anonymous_id: { diff --git a/packages/destination-actions/src/destinations/customerio/index.ts b/packages/destination-actions/src/destinations/customerio/index.ts index e8e38d4538..dd63c71e7a 100644 --- a/packages/destination-actions/src/destinations/customerio/index.ts +++ b/packages/destination-actions/src/destinations/customerio/index.ts @@ -12,6 +12,7 @@ import { AccountRegion, trackApiEndpoint } from './utils' const destination: DestinationDefinition = { name: 'Actions Customerio', + slug: 'actions-customerio', mode: 'cloud', authentication: { scheme: 'basic', From fb25c68d1831cae96d6038b4e226928fa2d13f46 Mon Sep 17 00:00:00 2001 From: kishoredevarasettyn Date: Thu, 29 Dec 2022 02:06:47 +0530 Subject: [PATCH 7/8] Adding traits to attributes property for createUpdateObject action --- .../__tests__/createUpdateObject.test.ts | 42 ++++++++++++++++--- .../customerio/createUpdateObject/index.ts | 5 +-- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/packages/destination-actions/src/destinations/customerio/__tests__/createUpdateObject.test.ts b/packages/destination-actions/src/destinations/customerio/__tests__/createUpdateObject.test.ts index 0d14e57ac3..07637936fd 100644 --- a/packages/destination-actions/src/destinations/customerio/__tests__/createUpdateObject.test.ts +++ b/packages/destination-actions/src/destinations/customerio/__tests__/createUpdateObject.test.ts @@ -26,6 +26,13 @@ describe('CustomerIO', () => { created_at: timestamp, object_type_id: '1' } + + const attributes = { + name: 'Sales', + industry: 'Technology', + created_at: dayjs.utc(timestamp).unix(), + object_type_id: '1' + } trackObjectService.post(`/api/v2/entity`).reply(200, {}, { 'x-customerio-region': 'US' }) const event = createTestEvent({ userId, @@ -48,7 +55,7 @@ describe('CustomerIO', () => { }) expect(responses[0].data).toMatchObject({}) expect(responses[0].options.json).toMatchObject({ - ...traits, + attributes: attributes, created_at: dayjs.utc(timestamp).unix(), type: 'object', action: 'identify', @@ -77,6 +84,12 @@ describe('CustomerIO', () => { created_at: timestamp, object_type_id: '1' } + const attributes = { + name: 'Sales', + industry: 'Technology', + created_at: dayjs.utc(timestamp).unix(), + object_type_id: '1' + } trackEUObjectService.post(`/api/v2/entity`).reply(200, {}, { 'x-customerio-region': 'EU' }) const event = createTestEvent({ userId, @@ -99,7 +112,7 @@ describe('CustomerIO', () => { }) expect(responses[0].data).toMatchObject({}) expect(responses[0].options.json).toMatchObject({ - ...traits, + attributes: attributes, created_at: dayjs.utc(timestamp).unix(), type: 'object', action: 'identify', @@ -126,6 +139,12 @@ describe('CustomerIO', () => { created_at: timestamp, object_type_id: '1' } + const attributes = { + name: 'Sales', + industry: 'Technology', + created_at: dayjs.utc(timestamp).unix(), + object_type_id: '1' + } trackObjectService.post(`/api/v2/entity`).reply(200, {}, { 'x-customerio-region': 'US-fallback' }) const event = createTestEvent({ userId, @@ -148,7 +167,7 @@ describe('CustomerIO', () => { }) expect(responses[0].data).toMatchObject({}) expect(responses[0].options.json).toMatchObject({ - ...traits, + attributes: attributes, created_at: dayjs.utc(timestamp).unix(), type: 'object', action: 'identify', @@ -174,6 +193,12 @@ describe('CustomerIO', () => { created_at: timestamp, object_type_id: '1' } + + const attributes = { + name: 'Sales', + created_at: dayjs.utc(timestamp).unix(), + object_type_id: '1' + } trackObjectService.post(`/api/v2/entity`).reply(200, {}, { 'x-customerio-region': 'US' }) const event = createTestEvent({ userId: undefined, @@ -196,7 +221,7 @@ describe('CustomerIO', () => { }) expect(responses[0].data).toMatchObject({}) expect(responses[0].options.json).toMatchObject({ - ...traits, + attributes: attributes, created_at: dayjs.utc(timestamp).unix(), type: 'object', action: 'identify_anonymous', @@ -222,6 +247,11 @@ describe('CustomerIO', () => { name: 'Sales', created_at: timestamp } + + const attributes = { + name: 'Sales', + created_at: dayjs.utc(timestamp).unix() + } trackObjectService.post(`/api/v2/entity`).reply(200, {}, { 'x-customerio-region': 'US' }) const event = createTestEvent({ userId, @@ -244,7 +274,7 @@ describe('CustomerIO', () => { }) expect(responses[0].data).toMatchObject({}) expect(responses[0].options.json).toMatchObject({ - ...traits, + attributes: attributes, created_at: dayjs.utc(timestamp).unix(), type: 'object', action: 'identify', @@ -293,7 +323,7 @@ describe('CustomerIO', () => { }) expect(responses[0].data).toMatchObject({}) expect(responses[0].options.json).toMatchObject({ - ...traits, + attributes: traits, type: 'object', action: 'identify', identifiers: { diff --git a/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts b/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts index e105acd218..2bde18c7fd 100644 --- a/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts +++ b/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts @@ -86,9 +86,8 @@ const action: ActionDefinition = { } } - const body: Record = { - ...customAttributes - } + const body: Record = {} + body.attributes = customAttributes if (createdAt) { body.created_at = createdAt } From 92b0e50413ed4804c7b121e4f26142dd545b2324 Mon Sep 17 00:00:00 2001 From: kishoredevarasettyn Date: Mon, 16 Jan 2023 14:16:02 +0530 Subject: [PATCH 8/8] renaming id and type_id to object_id and object_type_id --- .../__tests__/createUpdateObject.test.ts | 24 +++++++++---------- .../__tests__/createUpdatePerson.test.ts | 2 +- .../customerio/createUpdateObject/index.ts | 2 +- .../customerio/createUpdatePerson/index.ts | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/destination-actions/src/destinations/customerio/__tests__/createUpdateObject.test.ts b/packages/destination-actions/src/destinations/customerio/__tests__/createUpdateObject.test.ts index 07637936fd..0524402d25 100644 --- a/packages/destination-actions/src/destinations/customerio/__tests__/createUpdateObject.test.ts +++ b/packages/destination-actions/src/destinations/customerio/__tests__/createUpdateObject.test.ts @@ -60,8 +60,8 @@ describe('CustomerIO', () => { type: 'object', action: 'identify', identifiers: { - type_id: traits.object_type_id, - id: groupId + object_type_id: traits.object_type_id, + object_id: groupId }, cio_relationships: [{ identifiers: { id: userId } }] }) @@ -117,8 +117,8 @@ describe('CustomerIO', () => { type: 'object', action: 'identify', identifiers: { - type_id: traits.object_type_id, - id: groupId + object_type_id: traits.object_type_id, + object_id: groupId }, cio_relationships: [{ identifiers: { id: userId } }] }) @@ -172,8 +172,8 @@ describe('CustomerIO', () => { type: 'object', action: 'identify', identifiers: { - type_id: traits.object_type_id, - id: groupId + object_type_id: traits.object_type_id, + object_id: groupId }, cio_relationships: [{ identifiers: { id: userId } }] }) @@ -226,8 +226,8 @@ describe('CustomerIO', () => { type: 'object', action: 'identify_anonymous', identifiers: { - type_id: traits.object_type_id, - id: groupId + object_type_id: traits.object_type_id, + object_id: groupId }, cio_relationships: [{ identifiers: { anonymous_id: anonymousId } }] }) @@ -279,8 +279,8 @@ describe('CustomerIO', () => { type: 'object', action: 'identify', identifiers: { - type_id: '1', - id: groupId + object_type_id: '1', + object_id: groupId }, cio_relationships: [{ identifiers: { id: userId } }] }) @@ -327,8 +327,8 @@ describe('CustomerIO', () => { type: 'object', action: 'identify', identifiers: { - type_id: typeId, - id: groupId + object_type_id: typeId, + object_id: groupId }, cio_relationships: [{ identifiers: { id: userId } }] }) diff --git a/packages/destination-actions/src/destinations/customerio/__tests__/createUpdatePerson.test.ts b/packages/destination-actions/src/destinations/customerio/__tests__/createUpdatePerson.test.ts index a89b4207f8..08ae92f62a 100644 --- a/packages/destination-actions/src/destinations/customerio/__tests__/createUpdatePerson.test.ts +++ b/packages/destination-actions/src/destinations/customerio/__tests__/createUpdatePerson.test.ts @@ -463,7 +463,7 @@ describe('CustomerIO', () => { }, cio_relationships: { action: 'add_relationships', - relationships: [{ identifiers: { type_id: '1', id: groupId } }] + relationships: [{ identifiers: { object_type_id: '1', object_id: groupId } }] } }) }) diff --git a/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts b/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts index 2bde18c7fd..f6229eb4ca 100644 --- a/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts +++ b/packages/destination-actions/src/destinations/customerio/createUpdateObject/index.ts @@ -92,7 +92,7 @@ const action: ActionDefinition = { body.created_at = createdAt } body.type = 'object' - body.identifiers = { type_id: typeID ?? '1', id: objectID } + body.identifiers = { object_type_id: typeID ?? '1', object_id: objectID } if (userID) { body.action = 'identify' diff --git a/packages/destination-actions/src/destinations/customerio/createUpdatePerson/index.ts b/packages/destination-actions/src/destinations/customerio/createUpdatePerson/index.ts index 67b6585c24..3bef0873a6 100644 --- a/packages/destination-actions/src/destinations/customerio/createUpdatePerson/index.ts +++ b/packages/destination-actions/src/destinations/customerio/createUpdatePerson/index.ts @@ -112,7 +112,7 @@ const action: ActionDefinition = { if (objectId) { body.cio_relationships = { action: 'add_relationships', - relationships: [{ identifiers: { type_id: objectTypeId ?? '1', id: objectId } }] + relationships: [{ identifiers: { object_type_id: objectTypeId ?? '1', object_id: objectId } }] } }