-
Notifications
You must be signed in to change notification settings - Fork 255
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
add Report Content Event
to customerio destination
#2650
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import { createTestEvent, createTestIntegration } from '@segment/actions-core' | ||
import CustomerIO from '../index' | ||
import dayjs from '../../../lib/dayjs' | ||
import { AccountRegion } from '../utils' | ||
import { nockTrackInternalEndpoint } from '../test-helper' | ||
|
||
const trackService = nockTrackInternalEndpoint(AccountRegion.US) | ||
|
||
describe('CustomerIO', () => { | ||
describe('reportContentEvent', () => { | ||
const testDestination = createTestIntegration(CustomerIO) | ||
|
||
type testCase = { | ||
name: string | ||
anonymousId: string | ||
properties: { [key: string]: any } | ||
expected: { [key: string]: any } | ||
} | ||
|
||
const testCases: testCase[] = [ | ||
{ | ||
name: 'should work with viewed', | ||
anonymousId: 'abc123', | ||
properties: { | ||
actionType: 'viewed_content', | ||
contentType: 'ctype', | ||
contentId: 1, | ||
templateId: 1 | ||
}, | ||
expected: { | ||
action: 'viewed_content', | ||
attributes: { | ||
contentType: 'ctype', | ||
contentId: 1, | ||
templateId: 1 | ||
}, | ||
identifiers: { | ||
anonymous_id: 'abc123' | ||
}, | ||
name: 'viewed_content', | ||
type: 'person' | ||
} | ||
}, | ||
{ | ||
name: 'should work with clicked', | ||
anonymousId: 'abc123', | ||
properties: { | ||
actionType: 'clicked_content', | ||
contentType: 'ctype', | ||
contentId: 1, | ||
templateId: 1, | ||
actionName: 'aname', | ||
actionValue: 'avalue' | ||
}, | ||
expected: { | ||
action: 'clicked_content', | ||
attributes: { | ||
contentType: 'ctype', | ||
contentId: 1, | ||
templateId: 1, | ||
actionName: 'aname', | ||
actionValue: 'avalue' | ||
}, | ||
identifiers: { | ||
anonymous_id: 'abc123' | ||
}, | ||
name: 'clicked_content', | ||
type: 'person' | ||
} | ||
} | ||
] | ||
|
||
testCases.forEach((testCase) => { | ||
it(testCase.name, async () => { | ||
trackService.post(`/api/v2/entity`).reply(200, {}, { 'x-customerio-region': 'US' }) | ||
|
||
const now = dayjs.utc() | ||
const event = createTestEvent({ | ||
anonymousId: testCase.anonymousId, | ||
timestamp: now.toISOString(), | ||
type: 'track', | ||
event: 'Report Content Event', | ||
properties: testCase.properties | ||
}) | ||
const responses = await testDestination.testAction('reportContentEvent', { | ||
event, | ||
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).toEqual({ | ||
...testCase.expected, | ||
timestamp: now.unix() | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) |
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,81 @@ | ||
import type { ActionDefinition } from '@segment/actions-core' | ||
import type { Settings } from '../generated-types' | ||
import type { Payload } from './generated-types' | ||
import { sendBatch, sendSingle } from '../utils' | ||
|
||
const action: ActionDefinition<Settings, Payload> = { | ||
title: 'Report Content Event', | ||
description: 'Report a Viewed or Clicked Content event.', | ||
defaultSubscription: 'event = "Report Content Event"', | ||
fields: { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hi @karngyan I just a had a quick look at some of the other Actions for this Destination.
I don't know anything about Customer.io, but would like to ensure that changes to the Integration are done in a consistent way. Should this new Action also have the aforementioned fields? Best regards, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi Joe Here's more info about Report Content Event: https://docs.customer.io/api/cdp/#section/Semantic-events/Report-content-event-(anonymous-in-app-activity) |
||
anonymous_id: { | ||
label: 'Anonymous ID', | ||
description: 'ID for the anonymous user.', | ||
type: 'string', | ||
default: { | ||
'@path': '$.anonymousId' | ||
} | ||
}, | ||
actionType: { | ||
label: 'Action Type', | ||
description: 'The type of content event.', | ||
type: 'string', | ||
required: true, | ||
default: { | ||
'@path': '$.properties.actionType' | ||
}, | ||
choices: [ | ||
{ label: 'Viewed', value: 'viewed_content' }, | ||
{ label: 'Clicked', value: 'clicked_content' } | ||
] | ||
}, | ||
timestamp: { | ||
label: 'Timestamp', | ||
description: 'A timestamp of when the event took place. Default is current date and time.', | ||
type: 'string', | ||
default: { | ||
'@path': '$.timestamp' | ||
} | ||
}, | ||
data: { | ||
label: 'Event Attributes', | ||
description: 'Optional data to include with the event.', | ||
type: 'object', | ||
default: { | ||
'@path': '$.properties' | ||
} | ||
}, | ||
convert_timestamp: { | ||
label: 'Convert Timestamps', | ||
description: 'Convert dates to Unix timestamps (seconds since Epoch).', | ||
type: 'boolean', | ||
default: true | ||
}, | ||
}, | ||
performBatch: (request, { payload: payloads, ...rest }) => { | ||
return sendBatch( | ||
request, | ||
payloads.map((payload) => ({ ...rest, action: payload.actionType, payload: mapPayload(payload), type: 'person' })) | ||
) | ||
}, | ||
|
||
perform: (request, { payload, ...rest }) => { | ||
return sendSingle(request, { ...rest, action: payload.actionType, payload: mapPayload(payload), type: 'person' }) | ||
} | ||
} | ||
|
||
function mapPayload(payload: Payload) { | ||
const { actionType, data, ...rest } = payload | ||
|
||
if (data?.actionType) { | ||
delete data.actionType | ||
} | ||
|
||
return { | ||
...rest, | ||
name: actionType, | ||
attributes: data | ||
} | ||
} | ||
|
||
export default action |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be worth having 2 separate Presets, one for viewed_content and one for clicked_content.
Each preset would need to set the value of the 'Action Type' field accordingly.