From f6acfe5f969a98bf07ae9ed8d8771ca04a6fce82 Mon Sep 17 00:00:00 2001 From: Ayush Goyal Date: Wed, 16 Jul 2025 19:01:06 -0400 Subject: [PATCH 1/5] [Clay] Create page action --- .../__snapshots__/snapshot.test.ts.snap | 23 +++++ .../destinations/clay/__tests__/index.test.ts | 20 +++++ .../clay/__tests__/snapshot.test.ts | 82 ++++++++++++++++++ .../src/destinations/clay/generated-types.ts | 12 +++ .../src/destinations/clay/index.ts | 53 ++++++++++++ .../__snapshots__/snapshot.test.ts.snap | 35 ++++++++ .../clay/pageVisit/__tests__/index.test.ts | 79 +++++++++++++++++ .../clay/pageVisit/__tests__/snapshot.test.ts | 83 ++++++++++++++++++ .../clay/pageVisit/generated-types.ts | 38 ++++++++ .../src/destinations/clay/pageVisit/index.ts | 86 +++++++++++++++++++ 10 files changed, 511 insertions(+) create mode 100644 packages/destination-actions/src/destinations/clay/__tests__/__snapshots__/snapshot.test.ts.snap create mode 100644 packages/destination-actions/src/destinations/clay/__tests__/index.test.ts create mode 100644 packages/destination-actions/src/destinations/clay/__tests__/snapshot.test.ts create mode 100644 packages/destination-actions/src/destinations/clay/generated-types.ts create mode 100644 packages/destination-actions/src/destinations/clay/index.ts create mode 100644 packages/destination-actions/src/destinations/clay/pageVisit/__tests__/__snapshots__/snapshot.test.ts.snap create mode 100644 packages/destination-actions/src/destinations/clay/pageVisit/__tests__/index.test.ts create mode 100644 packages/destination-actions/src/destinations/clay/pageVisit/__tests__/snapshot.test.ts create mode 100644 packages/destination-actions/src/destinations/clay/pageVisit/generated-types.ts create mode 100644 packages/destination-actions/src/destinations/clay/pageVisit/index.ts diff --git a/packages/destination-actions/src/destinations/clay/__tests__/__snapshots__/snapshot.test.ts.snap b/packages/destination-actions/src/destinations/clay/__tests__/__snapshots__/snapshot.test.ts.snap new file mode 100644 index 0000000000..f3ad183cab --- /dev/null +++ b/packages/destination-actions/src/destinations/clay/__tests__/__snapshots__/snapshot.test.ts.snap @@ -0,0 +1,23 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Testing snapshot for actions-clay destination: pageVisit action - all fields 1`] = ` +Object { + "anonymousId": "eu76@B#kao", + "ip": "eu76@B#kao", + "messageId": Any, + "page": Object { + "testType": "eu76@B#kao", + }, + "timestamp": Any, + "url": "eu76@B#kao", + "userAgent": "eu76@B#kao", + "userId": "eu76@B#kao", +} +`; + +exports[`Testing snapshot for actions-clay destination: pageVisit action - required fields 1`] = ` +Object { + "ip": "eu76@B#kao", + "messageId": Any, +} +`; diff --git a/packages/destination-actions/src/destinations/clay/__tests__/index.test.ts b/packages/destination-actions/src/destinations/clay/__tests__/index.test.ts new file mode 100644 index 0000000000..8a545d9451 --- /dev/null +++ b/packages/destination-actions/src/destinations/clay/__tests__/index.test.ts @@ -0,0 +1,20 @@ +import nock from 'nock' +import { createTestIntegration } from '@segment/actions-core' +import Definition, { CLAY_API_BASE_URL } from '../index' + +const testDestination = createTestIntegration(Definition) + +describe('Clay', () => { + describe('testAuthentication', () => { + it('should validate authentication inputs', async () => { + nock(CLAY_API_BASE_URL).get('/segment/test_connection_key/auth').reply(200, {}) + + await expect( + testDestination.testAuthentication({ + connection_key: 'test_connection_key', + secret_key: 'test_secret_key' + }) + ).resolves.not.toThrowError() + }) + }) +}) diff --git a/packages/destination-actions/src/destinations/clay/__tests__/snapshot.test.ts b/packages/destination-actions/src/destinations/clay/__tests__/snapshot.test.ts new file mode 100644 index 0000000000..c2f1a0abb1 --- /dev/null +++ b/packages/destination-actions/src/destinations/clay/__tests__/snapshot.test.ts @@ -0,0 +1,82 @@ +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 destinationSlug = 'actions-clay' + +describe(`Testing snapshot for ${destinationSlug} destination:`, () => { + for (const actionSlug in destination.actions) { + it(`${actionSlug} action - required fields`, async () => { + const seedName = `${destinationSlug}#${actionSlug}` + const action = destination.actions[actionSlug] + const [eventData, settingsData] = generateTestData(seedName, destination, action, true) + + 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, + settings: settingsData, + auth: undefined + }) + + const request = responses[0].request + const rawBody = await request.text() + + try { + const json = JSON.parse(rawBody) + expect(json).toMatchSnapshot({ + messageId: expect.any(String) + }) + return + } catch (err) { + expect(rawBody).toMatchSnapshot() + } + + expect(request.headers).toMatchSnapshot() + }) + + it(`${actionSlug} action - all fields`, async () => { + const seedName = `${destinationSlug}#${actionSlug}` + 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, + settings: settingsData, + auth: undefined + }) + + const request = responses[0].request + const rawBody = await request.text() + + try { + const json = JSON.parse(rawBody) + expect(json).toMatchSnapshot({ + messageId: expect.any(String), + timestamp: expect.any(String) + }) + return + } catch (err) { + expect(rawBody).toMatchSnapshot() + } + }) + } +}) diff --git a/packages/destination-actions/src/destinations/clay/generated-types.ts b/packages/destination-actions/src/destinations/clay/generated-types.ts new file mode 100644 index 0000000000..a4497ff836 --- /dev/null +++ b/packages/destination-actions/src/destinations/clay/generated-types.ts @@ -0,0 +1,12 @@ +// Generated file. DO NOT MODIFY IT BY HAND. + +export interface Settings { + /** + * Your Clay connection key for page visit events + */ + connection_key: string + /** + * Your Clay secret key for page visit events + */ + secret_key: string +} diff --git a/packages/destination-actions/src/destinations/clay/index.ts b/packages/destination-actions/src/destinations/clay/index.ts new file mode 100644 index 0000000000..2d3779463b --- /dev/null +++ b/packages/destination-actions/src/destinations/clay/index.ts @@ -0,0 +1,53 @@ +import type { DestinationDefinition } from '@segment/actions-core' +import { defaultValues } from '@segment/actions-core' +import type { Settings } from './generated-types' +import pageVisit from './pageVisit' + +export const CLAY_API_BASE_URL = 'https://segment-session.clay.com' + +const presets: DestinationDefinition['presets'] = [ + { + name: 'Page Visit', + subscribe: 'type = "page"', + partnerAction: 'pageVisit', + mapping: defaultValues(pageVisit.fields), + type: 'automatic' + } +] + +const destination: DestinationDefinition = { + name: 'Clay', + slug: 'actions-clay', + mode: 'cloud', + authentication: { + scheme: 'custom', + fields: { + connection_key: { + label: 'Connection Key', + description: 'Your Clay connection key for page visit events', + type: 'string', + required: true + }, + secret_key: { + label: 'Secret Key', + description: 'Your Clay secret key for page visit events', + type: 'string', + required: true + } + }, + testAuthentication: (request, { settings }) => { + return request(`${CLAY_API_BASE_URL}/segment/${settings.connection_key}/auth`, { + method: 'GET', + headers: { + Authorization: `Bearer ${settings.secret_key}` + } + }) + } + }, + presets, + actions: { + pageVisit + } +} + +export default destination diff --git a/packages/destination-actions/src/destinations/clay/pageVisit/__tests__/__snapshots__/snapshot.test.ts.snap b/packages/destination-actions/src/destinations/clay/pageVisit/__tests__/__snapshots__/snapshot.test.ts.snap new file mode 100644 index 0000000000..cf32feae12 --- /dev/null +++ b/packages/destination-actions/src/destinations/clay/pageVisit/__tests__/__snapshots__/snapshot.test.ts.snap @@ -0,0 +1,35 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Testing snapshot for Clay's pageVisit destination action: all fields 1`] = ` +Object { + "anonymousId": "zZg8#WaG5V1[W1", + "ip": "zZg8#WaG5V1[W1", + "messageId": Any, + "page": Object { + "testType": "zZg8#WaG5V1[W1", + }, + "timestamp": Any, + "url": "zZg8#WaG5V1[W1", + "userAgent": "zZg8#WaG5V1[W1", + "userId": "zZg8#WaG5V1[W1", +} +`; + +exports[`Testing snapshot for Clay's pageVisit destination action: required fields 1`] = ` +Object { + "anonymousId": "anonId1234", + "ip": "zZg8#WaG5V1[W1", + "messageId": Any, + "page": Object { + "path": "/academy/", + "referrer": "", + "search": "", + "title": "Analytics Academy", + "url": "https://segment.com/academy/", + }, + "timestamp": Any, + "url": "https://segment.com/academy/", + "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1", + "userId": "user1234", +} +`; diff --git a/packages/destination-actions/src/destinations/clay/pageVisit/__tests__/index.test.ts b/packages/destination-actions/src/destinations/clay/pageVisit/__tests__/index.test.ts new file mode 100644 index 0000000000..5ba879f298 --- /dev/null +++ b/packages/destination-actions/src/destinations/clay/pageVisit/__tests__/index.test.ts @@ -0,0 +1,79 @@ +import { createTestIntegration } from '@segment/actions-core' +import nock from 'nock' +import Destination, { CLAY_API_BASE_URL } from '../../index' + +const testDestination = createTestIntegration(Destination) + +describe('Clay.pageVisit', () => { + it('sends page event to Clay with correct payload', async () => { + nock(CLAY_API_BASE_URL).post('/segment/test_connection_key/events').reply(200, {}) + + const responses = await testDestination.testAction('pageVisit', { + settings: { + connection_key: 'test_connection_key', + secret_key: 'test_secret_key' + }, + mapping: { + timestamp: '2023-03-03T00:00:00.000Z', + url: 'https://example.com/page', + page: { + title: 'Example Page', + url: 'https://example.com/page', + path: '/page', + referrer: 'https://google.com' + }, + ip: '192.168.0.1', + userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36', + anonymousId: 'anonymous_user_123', + userId: 'user_456', + messageId: 'segment_message_789' + } + }) + + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + expect((responses[0].options.headers as any)?.get?.('authorization')).toBe('Bearer test_secret_key') + + const payload = JSON.parse(responses[0].options.body?.toString() ?? '') + expect(payload).toMatchObject({ + timestamp: '2023-03-03T00:00:00.000Z', + url: 'https://example.com/page', + page: { + title: 'Example Page', + url: 'https://example.com/page', + path: '/page', + referrer: 'https://google.com' + }, + ip: '192.168.0.1', + userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36', + anonymousId: 'anonymous_user_123', + userId: 'user_456', + messageId: 'segment_message_789' + }) + }) + + it('handles minimal required fields', async () => { + nock(CLAY_API_BASE_URL).post('/segment/test_connection_key/events').reply(200, {}) + + const responses = await testDestination.testAction('pageVisit', { + settings: { + connection_key: 'test_connection_key', + secret_key: 'test_secret_key' + }, + mapping: { + ip: '192.168.0.1', + messageId: 'segment_message_minimal' + } + }) + + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + expect((responses[0].options.headers as any)?.get?.('authorization')).toBe('Bearer test_secret_key') + + const payload = JSON.parse(responses[0].options.body?.toString() ?? '') + expect(payload).toMatchObject({ + ip: '192.168.0.1', + messageId: 'segment_message_minimal' + }) + }) +}) diff --git a/packages/destination-actions/src/destinations/clay/pageVisit/__tests__/snapshot.test.ts b/packages/destination-actions/src/destinations/clay/pageVisit/__tests__/snapshot.test.ts new file mode 100644 index 0000000000..ead0e5d113 --- /dev/null +++ b/packages/destination-actions/src/destinations/clay/pageVisit/__tests__/snapshot.test.ts @@ -0,0 +1,83 @@ +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 = 'pageVisit' +const destinationSlug = 'Clay' +const seedName = `${destinationSlug}#${actionSlug}` + +describe(`Testing snapshot for ${destinationSlug}'s ${actionSlug} destination action:`, () => { + it('required fields', async () => { + const action = destination.actions[actionSlug] + const [eventData, settingsData] = generateTestData(seedName, destination, action, true) + + 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, + settings: settingsData, + auth: undefined, + useDefaultMappings: true + }) + + const request = responses[0].request + const rawBody = await request.text() + + try { + const json = JSON.parse(rawBody) + expect(json).toMatchSnapshot({ + timestamp: expect.any(String), + messageId: expect.any(String) + }) + return + } catch (err) { + expect(rawBody).toMatchSnapshot() + } + + expect(request.headers).toMatchSnapshot() + }) + + it('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, + settings: settingsData, + auth: undefined, + useDefaultMappings: true + }) + + const request = responses[0].request + const rawBody = await request.text() + + try { + const json = JSON.parse(rawBody) + expect(json).toMatchSnapshot({ + timestamp: expect.any(String), + messageId: expect.any(String) + }) + return + } catch (err) { + expect(rawBody).toMatchSnapshot() + } + }) +}) diff --git a/packages/destination-actions/src/destinations/clay/pageVisit/generated-types.ts b/packages/destination-actions/src/destinations/clay/pageVisit/generated-types.ts new file mode 100644 index 0000000000..a9271e98bb --- /dev/null +++ b/packages/destination-actions/src/destinations/clay/pageVisit/generated-types.ts @@ -0,0 +1,38 @@ +// Generated file. DO NOT MODIFY IT BY HAND. + +export interface Payload { + /** + * The timestamp of the page event + */ + timestamp?: string + /** + * URL of the webpage + */ + url?: string + /** + * Contains context information regarding a webpage + */ + page?: { + [k: string]: unknown + } + /** + * IP address of the user + */ + ip: string + /** + * User-Agent of the user + */ + userAgent?: string + /** + * The anonymous ID associated with the user + */ + anonymousId?: string + /** + * The ID associated with the user + */ + userId?: string + /** + * The Segment messageId + */ + messageId: string +} diff --git a/packages/destination-actions/src/destinations/clay/pageVisit/index.ts b/packages/destination-actions/src/destinations/clay/pageVisit/index.ts new file mode 100644 index 0000000000..2ac18a8212 --- /dev/null +++ b/packages/destination-actions/src/destinations/clay/pageVisit/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 { CLAY_API_BASE_URL } from '../index' + +const action: ActionDefinition = { + title: 'Page Visit', + description: 'Send a page event to Clay', + defaultSubscription: 'type = "page"', + fields: { + timestamp: { + type: 'string', + format: 'date-time', + required: false, + description: 'The timestamp of the page event', + label: 'Timestamp', + default: { '@path': '$.timestamp' } + }, + url: { + type: 'string', + required: false, + description: 'URL of the webpage', + label: 'Page URL', + default: { '@path': '$.context.page.url' } + }, + page: { + description: 'Contains context information regarding a webpage', + label: 'Page', + required: false, + type: 'object', + default: { + '@path': '$.context.page' + } + }, + ip: { + description: 'IP address of the user', + label: 'IP Address', + required: true, + type: 'string', + default: { + '@path': '$.context.ip' + } + }, + userAgent: { + description: 'User-Agent of the user', + label: 'User Agent', + required: false, + type: 'string', + default: { + '@path': '$.context.userAgent' + } + }, + anonymousId: { + type: 'string', + required: false, + description: 'The anonymous ID associated with the user', + label: 'Anonymous ID', + default: { '@path': '$.anonymousId' } + }, + userId: { + type: 'string', + required: false, + description: 'The ID associated with the user', + label: 'User ID', + default: { '@path': '$.userId' } + }, + messageId: { + type: 'string', + required: true, + description: 'The Segment messageId', + label: 'MessageId', + default: { '@path': '$.messageId' } + } + }, + perform: (request, { payload, settings }) => { + return request(`${CLAY_API_BASE_URL}/segment/${settings.connection_key}/events`, { + method: 'POST', + headers: { + Authorization: `Bearer ${settings.secret_key}` + }, + json: payload + }) + } +} + +export default action From 7e54629f0fbdcf4e414c006fdd46281a91b46cfc Mon Sep 17 00:00:00 2001 From: Ayush Goyal Date: Thu, 17 Jul 2025 10:49:11 -0400 Subject: [PATCH 2/5] [Clay] Collect page properties --- .../src/destinations/clay/pageVisit/generated-types.ts | 6 ++++++ .../src/destinations/clay/pageVisit/index.ts | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/packages/destination-actions/src/destinations/clay/pageVisit/generated-types.ts b/packages/destination-actions/src/destinations/clay/pageVisit/generated-types.ts index a9271e98bb..9cd89e27c8 100644 --- a/packages/destination-actions/src/destinations/clay/pageVisit/generated-types.ts +++ b/packages/destination-actions/src/destinations/clay/pageVisit/generated-types.ts @@ -35,4 +35,10 @@ export interface Payload { * The Segment messageId */ messageId: string + /** + * Properties to associate with the event + */ + properties?: { + [k: string]: unknown + } } diff --git a/packages/destination-actions/src/destinations/clay/pageVisit/index.ts b/packages/destination-actions/src/destinations/clay/pageVisit/index.ts index 2ac18a8212..247a0a4311 100644 --- a/packages/destination-actions/src/destinations/clay/pageVisit/index.ts +++ b/packages/destination-actions/src/destinations/clay/pageVisit/index.ts @@ -70,6 +70,12 @@ const action: ActionDefinition = { description: 'The Segment messageId', label: 'MessageId', default: { '@path': '$.messageId' } + }, + properties: { + type: 'object', + label: 'Properties', + description: 'Properties to associate with the event', + default: { '@path': '$.properties' } } }, perform: (request, { payload, settings }) => { From 02afbc1853920ba4c09370188ebdc7a24fabcc88 Mon Sep 17 00:00:00 2001 From: Ayush Goyal Date: Thu, 24 Jul 2025 10:40:45 -0400 Subject: [PATCH 3/5] Add in track event --- .../__snapshots__/snapshot.test.ts.snap | 43 +++++- .../src/destinations/clay/generated-types.ts | 4 +- .../src/destinations/clay/index.ts | 15 +- .../__snapshots__/snapshot.test.ts.snap | 17 ++- .../clay/pageVisit/__tests__/index.test.ts | 6 +- .../clay/pageVisit/generated-types.ts | 35 ++++- .../src/destinations/clay/pageVisit/index.ts | 57 ++++++-- .../__snapshots__/snapshot.test.ts.snap | 33 +++++ .../clay/track/__tests__/index.test.ts | 85 ++++++++++++ .../clay/track/__tests__/snapshot.test.ts | 75 ++++++++++ .../clay/track/generated-types.ts | 67 +++++++++ .../src/destinations/clay/track/index.ts | 131 ++++++++++++++++++ 12 files changed, 543 insertions(+), 25 deletions(-) create mode 100644 packages/destination-actions/src/destinations/clay/track/__tests__/__snapshots__/snapshot.test.ts.snap create mode 100644 packages/destination-actions/src/destinations/clay/track/__tests__/index.test.ts create mode 100644 packages/destination-actions/src/destinations/clay/track/__tests__/snapshot.test.ts create mode 100644 packages/destination-actions/src/destinations/clay/track/generated-types.ts create mode 100644 packages/destination-actions/src/destinations/clay/track/index.ts diff --git a/packages/destination-actions/src/destinations/clay/__tests__/__snapshots__/snapshot.test.ts.snap b/packages/destination-actions/src/destinations/clay/__tests__/__snapshots__/snapshot.test.ts.snap index f3ad183cab..5263f136fe 100644 --- a/packages/destination-actions/src/destinations/clay/__tests__/__snapshots__/snapshot.test.ts.snap +++ b/packages/destination-actions/src/destinations/clay/__tests__/__snapshots__/snapshot.test.ts.snap @@ -5,11 +5,19 @@ Object { "anonymousId": "eu76@B#kao", "ip": "eu76@B#kao", "messageId": Any, + "name": "eu76@B#kao", "page": Object { + "path": "eu76@B#kao", + "referrer": "eu76@B#kao", + "search": "eu76@B#kao", + "title": "eu76@B#kao", + "url": "eu76@B#kao", + }, + "properties": Object { "testType": "eu76@B#kao", }, "timestamp": Any, - "url": "eu76@B#kao", + "type": "eu76@B#kao", "userAgent": "eu76@B#kao", "userId": "eu76@B#kao", } @@ -19,5 +27,38 @@ exports[`Testing snapshot for actions-clay destination: pageVisit action - requi Object { "ip": "eu76@B#kao", "messageId": Any, + "type": "eu76@B#kao", +} +`; + +exports[`Testing snapshot for actions-clay destination: track action - all fields 1`] = ` +Object { + "anonymousId": "NHQVrUx(HtHKStZdY", + "event": "NHQVrUx(HtHKStZdY", + "ip": "NHQVrUx(HtHKStZdY", + "messageId": Any, + "page": Object { + "path": "NHQVrUx(HtHKStZdY", + "referrer": "NHQVrUx(HtHKStZdY", + "search": "NHQVrUx(HtHKStZdY", + "title": "NHQVrUx(HtHKStZdY", + "url": "NHQVrUx(HtHKStZdY", + }, + "properties": Object { + "testType": "NHQVrUx(HtHKStZdY", + }, + "timestamp": Any, + "type": "NHQVrUx(HtHKStZdY", + "userAgent": "NHQVrUx(HtHKStZdY", + "userId": "NHQVrUx(HtHKStZdY", +} +`; + +exports[`Testing snapshot for actions-clay destination: track action - required fields 1`] = ` +Object { + "event": "NHQVrUx(HtHKStZdY", + "ip": "NHQVrUx(HtHKStZdY", + "messageId": Any, + "type": "NHQVrUx(HtHKStZdY", } `; diff --git a/packages/destination-actions/src/destinations/clay/generated-types.ts b/packages/destination-actions/src/destinations/clay/generated-types.ts index a4497ff836..e4a7723b69 100644 --- a/packages/destination-actions/src/destinations/clay/generated-types.ts +++ b/packages/destination-actions/src/destinations/clay/generated-types.ts @@ -2,11 +2,11 @@ export interface Settings { /** - * Your Clay connection key for page visit events + * Your Clay connection key */ connection_key: string /** - * Your Clay secret key for page visit events + * Your Clay secret key */ secret_key: string } diff --git a/packages/destination-actions/src/destinations/clay/index.ts b/packages/destination-actions/src/destinations/clay/index.ts index 2d3779463b..481770c507 100644 --- a/packages/destination-actions/src/destinations/clay/index.ts +++ b/packages/destination-actions/src/destinations/clay/index.ts @@ -2,6 +2,7 @@ import type { DestinationDefinition } from '@segment/actions-core' import { defaultValues } from '@segment/actions-core' import type { Settings } from './generated-types' import pageVisit from './pageVisit' +import track from './track' export const CLAY_API_BASE_URL = 'https://segment-session.clay.com' @@ -12,6 +13,13 @@ const presets: DestinationDefinition['presets'] = [ partnerAction: 'pageVisit', mapping: defaultValues(pageVisit.fields), type: 'automatic' + }, + { + name: 'Track Calls', + subscribe: 'type = "track"', + partnerAction: 'track', + mapping: defaultValues(track.fields), + type: 'automatic' } ] @@ -24,13 +32,13 @@ const destination: DestinationDefinition = { fields: { connection_key: { label: 'Connection Key', - description: 'Your Clay connection key for page visit events', + description: 'Your Clay connection key', type: 'string', required: true }, secret_key: { label: 'Secret Key', - description: 'Your Clay secret key for page visit events', + description: 'Your Clay secret key', type: 'string', required: true } @@ -46,7 +54,8 @@ const destination: DestinationDefinition = { }, presets, actions: { - pageVisit + pageVisit, + track } } diff --git a/packages/destination-actions/src/destinations/clay/pageVisit/__tests__/__snapshots__/snapshot.test.ts.snap b/packages/destination-actions/src/destinations/clay/pageVisit/__tests__/__snapshots__/snapshot.test.ts.snap index cf32feae12..0a9e0d87fb 100644 --- a/packages/destination-actions/src/destinations/clay/pageVisit/__tests__/__snapshots__/snapshot.test.ts.snap +++ b/packages/destination-actions/src/destinations/clay/pageVisit/__tests__/__snapshots__/snapshot.test.ts.snap @@ -5,11 +5,19 @@ Object { "anonymousId": "zZg8#WaG5V1[W1", "ip": "zZg8#WaG5V1[W1", "messageId": Any, + "name": "zZg8#WaG5V1[W1", "page": Object { + "path": "zZg8#WaG5V1[W1", + "referrer": "zZg8#WaG5V1[W1", + "search": "zZg8#WaG5V1[W1", + "title": "zZg8#WaG5V1[W1", + "url": "zZg8#WaG5V1[W1", + }, + "properties": Object { "testType": "zZg8#WaG5V1[W1", }, "timestamp": Any, - "url": "zZg8#WaG5V1[W1", + "type": "zZg8#WaG5V1[W1", "userAgent": "zZg8#WaG5V1[W1", "userId": "zZg8#WaG5V1[W1", } @@ -27,8 +35,13 @@ Object { "title": "Analytics Academy", "url": "https://segment.com/academy/", }, + "properties": Object { + "ip": "zZg8#WaG5V1[W1", + "messageId": "zZg8#WaG5V1[W1", + "type": "zZg8#WaG5V1[W1", + }, "timestamp": Any, - "url": "https://segment.com/academy/", + "type": "zZg8#WaG5V1[W1", "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1", "userId": "user1234", } diff --git a/packages/destination-actions/src/destinations/clay/pageVisit/__tests__/index.test.ts b/packages/destination-actions/src/destinations/clay/pageVisit/__tests__/index.test.ts index 5ba879f298..716e9e65e2 100644 --- a/packages/destination-actions/src/destinations/clay/pageVisit/__tests__/index.test.ts +++ b/packages/destination-actions/src/destinations/clay/pageVisit/__tests__/index.test.ts @@ -14,8 +14,8 @@ describe('Clay.pageVisit', () => { secret_key: 'test_secret_key' }, mapping: { + type: 'page', timestamp: '2023-03-03T00:00:00.000Z', - url: 'https://example.com/page', page: { title: 'Example Page', url: 'https://example.com/page', @@ -36,8 +36,8 @@ describe('Clay.pageVisit', () => { const payload = JSON.parse(responses[0].options.body?.toString() ?? '') expect(payload).toMatchObject({ + type: 'page', timestamp: '2023-03-03T00:00:00.000Z', - url: 'https://example.com/page', page: { title: 'Example Page', url: 'https://example.com/page', @@ -61,6 +61,7 @@ describe('Clay.pageVisit', () => { secret_key: 'test_secret_key' }, mapping: { + type: 'page', ip: '192.168.0.1', messageId: 'segment_message_minimal' } @@ -72,6 +73,7 @@ describe('Clay.pageVisit', () => { const payload = JSON.parse(responses[0].options.body?.toString() ?? '') expect(payload).toMatchObject({ + type: 'page', ip: '192.168.0.1', messageId: 'segment_message_minimal' }) diff --git a/packages/destination-actions/src/destinations/clay/pageVisit/generated-types.ts b/packages/destination-actions/src/destinations/clay/pageVisit/generated-types.ts index 9cd89e27c8..20142d88a1 100644 --- a/packages/destination-actions/src/destinations/clay/pageVisit/generated-types.ts +++ b/packages/destination-actions/src/destinations/clay/pageVisit/generated-types.ts @@ -2,18 +2,41 @@ export interface Payload { /** - * The timestamp of the page event + * The name of the page */ - timestamp?: string + name?: string /** - * URL of the webpage + * The type of the event. Either "page" or "track" */ - url?: string + type: string /** - * Contains context information regarding a webpage + * The timestamp of the page event + */ + timestamp?: string + /** + * Information about the current page */ page?: { - [k: string]: unknown + /** + * Path of the webpage + */ + path?: string + /** + * Referrer of the webpage + */ + referrer?: string + /** + * Search query of the webpage + */ + search?: string + /** + * Title of the webpage + */ + title?: string + /** + * Full URL of the webpage + */ + url?: string } /** * IP address of the user diff --git a/packages/destination-actions/src/destinations/clay/pageVisit/index.ts b/packages/destination-actions/src/destinations/clay/pageVisit/index.ts index 247a0a4311..c4151091c5 100644 --- a/packages/destination-actions/src/destinations/clay/pageVisit/index.ts +++ b/packages/destination-actions/src/destinations/clay/pageVisit/index.ts @@ -8,6 +8,20 @@ const action: ActionDefinition = { description: 'Send a page event to Clay', defaultSubscription: 'type = "page"', fields: { + name: { + type: 'string', + description: 'The name of the page', + label: 'Event Name', + required: false, + default: { '@path': '$.name' } + }, + type: { + type: 'string', + description: 'The type of the event. Either "page" or "track"', + label: 'Type', + required: true, + default: { '@path': '$.type' } + }, timestamp: { type: 'string', format: 'date-time', @@ -16,20 +30,45 @@ const action: ActionDefinition = { label: 'Timestamp', default: { '@path': '$.timestamp' } }, - url: { - type: 'string', - required: false, - description: 'URL of the webpage', - label: 'Page URL', - default: { '@path': '$.context.page.url' } - }, page: { - description: 'Contains context information regarding a webpage', + description: 'Information about the current page', label: 'Page', required: false, type: 'object', + additionalProperties: false, + properties: { + path: { + type: 'string', + description: 'Path of the webpage', + label: 'Path' + }, + referrer: { + type: 'string', + description: 'Referrer of the webpage', + label: 'Referrer' + }, + search: { + type: 'string', + description: 'Search query of the webpage', + label: 'Search Query' + }, + title: { + type: 'string', + description: 'Title of the webpage', + label: 'Title' + }, + url: { + type: 'string', + description: 'Full URL of the webpage', + label: 'Full URL' + } + }, default: { - '@path': '$.context.page' + path: { '@path': '$.context.page.path' }, + referrer: { '@path': '$.context.page.referrer' }, + search: { '@path': '$.context.page.search' }, + title: { '@path': '$.context.page.title' }, + url: { '@path': '$.context.page.url' } } }, ip: { diff --git a/packages/destination-actions/src/destinations/clay/track/__tests__/__snapshots__/snapshot.test.ts.snap b/packages/destination-actions/src/destinations/clay/track/__tests__/__snapshots__/snapshot.test.ts.snap new file mode 100644 index 0000000000..ebb221608f --- /dev/null +++ b/packages/destination-actions/src/destinations/clay/track/__tests__/__snapshots__/snapshot.test.ts.snap @@ -0,0 +1,33 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Testing snapshot for Clay's track destination action: all fields 1`] = ` +Object { + "anonymousId": "s#NxR#]zhFrIncI7QBq", + "event": "s#NxR#]zhFrIncI7QBq", + "ip": "s#NxR#]zhFrIncI7QBq", + "messageId": "s#NxR#]zhFrIncI7QBq", + "page": Object { + "path": "s#NxR#]zhFrIncI7QBq", + "referrer": "s#NxR#]zhFrIncI7QBq", + "search": "s#NxR#]zhFrIncI7QBq", + "title": "s#NxR#]zhFrIncI7QBq", + "url": "s#NxR#]zhFrIncI7QBq", + }, + "properties": Object { + "testType": "s#NxR#]zhFrIncI7QBq", + }, + "timestamp": "2050-11-27T17:19:35.865Z", + "type": "s#NxR#]zhFrIncI7QBq", + "userAgent": "s#NxR#]zhFrIncI7QBq", + "userId": "s#NxR#]zhFrIncI7QBq", +} +`; + +exports[`Testing snapshot for Clay's track destination action: required fields 1`] = ` +Object { + "event": "s#NxR#]zhFrIncI7QBq", + "ip": "s#NxR#]zhFrIncI7QBq", + "messageId": "s#NxR#]zhFrIncI7QBq", + "type": "s#NxR#]zhFrIncI7QBq", +} +`; diff --git a/packages/destination-actions/src/destinations/clay/track/__tests__/index.test.ts b/packages/destination-actions/src/destinations/clay/track/__tests__/index.test.ts new file mode 100644 index 0000000000..169f313558 --- /dev/null +++ b/packages/destination-actions/src/destinations/clay/track/__tests__/index.test.ts @@ -0,0 +1,85 @@ +import nock from 'nock' +import { createTestIntegration } from '@segment/actions-core' +import Destination, { CLAY_API_BASE_URL } from '../../index' + +const testDestination = createTestIntegration(Destination) + +describe('Clay.track', () => { + it('sends track event to Clay with correct payload', async () => { + nock(CLAY_API_BASE_URL).post('/segment/test_connection_key/events').reply(200, {}) + + const responses = await testDestination.testAction('track', { + settings: { + connection_key: 'test_connection_key', + secret_key: 'test_secret_key' + }, + mapping: { + type: 'track', + timestamp: '2023-03-03T00:00:00.000Z', + event: 'Purchase Completed', + properties: { + product_id: 'prod_123', + price: 29.99, + currency: 'USD', + category: 'Electronics' + }, + userId: 'user_456', + anonymousId: 'anonymous_user_123', + ip: '192.168.0.1', + userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36', + messageId: 'segment_message_789' + } + }) + + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + expect((responses[0].options.headers as any)?.get?.('authorization')).toBe('Bearer test_secret_key') + + const payload = JSON.parse(responses[0].options.body?.toString() ?? '') + expect(payload).toMatchObject({ + type: 'track', + timestamp: '2023-03-03T00:00:00.000Z', + event: 'Purchase Completed', + properties: { + product_id: 'prod_123', + price: 29.99, + currency: 'USD', + category: 'Electronics' + }, + userId: 'user_456', + anonymousId: 'anonymous_user_123', + ip: '192.168.0.1', + userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36', + messageId: 'segment_message_789' + }) + }) + + it('handles minimal required fields', async () => { + nock(CLAY_API_BASE_URL).post('/segment/test_connection_key/events').reply(200, {}) + + const responses = await testDestination.testAction('track', { + settings: { + connection_key: 'test_connection_key', + secret_key: 'test_secret_key' + }, + mapping: { + type: 'track', + event: 'Button Click', + ip: '192.168.0.1', + messageId: 'segment_message_minimal' + } + }) + + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + expect((responses[0].options.headers as any)?.get?.('authorization')).toBe('Bearer test_secret_key') + + const payload = JSON.parse(responses[0].options.body?.toString() ?? '') + expect(payload).toMatchObject({ + type: 'track', + event: 'Button Click', + ip: '192.168.0.1', + messageId: 'segment_message_minimal' + }) + }) +}) diff --git a/packages/destination-actions/src/destinations/clay/track/__tests__/snapshot.test.ts b/packages/destination-actions/src/destinations/clay/track/__tests__/snapshot.test.ts new file mode 100644 index 0000000000..9de9a20675 --- /dev/null +++ b/packages/destination-actions/src/destinations/clay/track/__tests__/snapshot.test.ts @@ -0,0 +1,75 @@ +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 = 'track' +const destinationSlug = 'Clay' +const seedName = `${destinationSlug}#${actionSlug}` + +describe(`Testing snapshot for ${destinationSlug}'s ${actionSlug} destination action:`, () => { + it('required fields', async () => { + const action = destination.actions[actionSlug] + const [eventData, settingsData] = generateTestData(seedName, destination, action, true) + + 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, + 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() + } + + expect(request.headers).toMatchSnapshot() + }) + + it('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, + 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() + } + }) +}) diff --git a/packages/destination-actions/src/destinations/clay/track/generated-types.ts b/packages/destination-actions/src/destinations/clay/track/generated-types.ts new file mode 100644 index 0000000000..b41fc77ff5 --- /dev/null +++ b/packages/destination-actions/src/destinations/clay/track/generated-types.ts @@ -0,0 +1,67 @@ +// Generated file. DO NOT MODIFY IT BY HAND. + +export interface Payload { + /** + * The name of the event + */ + event: string + /** + * The type of the event. Either "page" or "track" + */ + type: string + /** + * The timestamp of the track event + */ + timestamp?: string + /** + * Information about the current page + */ + page?: { + /** + * Path of the webpage + */ + path?: string + /** + * Referrer of the webpage + */ + referrer?: string + /** + * Search query of the webpage + */ + search?: string + /** + * Title of the webpage + */ + title?: string + /** + * Full URL of the webpage + */ + url?: string + } + /** + * IP address of the user + */ + ip: string + /** + * User-Agent of the user + */ + userAgent?: string + /** + * The anonymous ID associated with the user + */ + anonymousId?: string + /** + * The ID associated with the user + */ + userId?: string + /** + * The Segment messageId + */ + messageId: string + /** + * Properties to associate with the event + */ + properties?: { + [k: string]: unknown + } +} diff --git a/packages/destination-actions/src/destinations/clay/track/index.ts b/packages/destination-actions/src/destinations/clay/track/index.ts new file mode 100644 index 0000000000..29384b3adf --- /dev/null +++ b/packages/destination-actions/src/destinations/clay/track/index.ts @@ -0,0 +1,131 @@ +import type { ActionDefinition } from '@segment/actions-core' +import type { Settings } from '../generated-types' +import type { Payload } from './generated-types' +import { CLAY_API_BASE_URL } from '../index' + +const action: ActionDefinition = { + title: 'Track', + description: 'Send a track event to Clay', + defaultSubscription: 'type = "track"', + fields: { + event: { + type: 'string', + required: true, + description: 'The name of the event', + label: 'Event Name', + default: { '@path': '$.event' } + }, + type: { + type: 'string', + description: 'The type of the event. Either "page" or "track"', + label: 'Type', + required: true, + default: { '@path': '$.type' } + }, + timestamp: { + type: 'string', + format: 'date-time', + required: false, + description: 'The timestamp of the track event', + label: 'Timestamp', + default: { '@path': '$.timestamp' } + }, + page: { + description: 'Information about the current page', + label: 'Page', + required: false, + type: 'object', + additionalProperties: false, + properties: { + path: { + type: 'string', + description: 'Path of the webpage', + label: 'Path' + }, + referrer: { + type: 'string', + description: 'Referrer of the webpage', + label: 'Referrer' + }, + search: { + type: 'string', + description: 'Search query of the webpage', + label: 'Search Query' + }, + title: { + type: 'string', + description: 'Title of the webpage', + label: 'Title' + }, + url: { + type: 'string', + description: 'Full URL of the webpage', + label: 'Full URL' + } + }, + default: { + path: { '@path': '$.context.page.path' }, + referrer: { '@path': '$.context.page.referrer' }, + search: { '@path': '$.context.page.search' }, + title: { '@path': '$.context.page.title' }, + url: { '@path': '$.context.page.url' } + } + }, + ip: { + description: 'IP address of the user', + label: 'IP Address', + required: true, + type: 'string', + default: { + '@path': '$.context.ip' + } + }, + userAgent: { + description: 'User-Agent of the user', + label: 'User Agent', + required: false, + type: 'string', + default: { + '@path': '$.context.userAgent' + } + }, + anonymousId: { + type: 'string', + required: false, + description: 'The anonymous ID associated with the user', + label: 'Anonymous ID', + default: { '@path': '$.anonymousId' } + }, + userId: { + type: 'string', + required: false, + description: 'The ID associated with the user', + label: 'User ID', + default: { '@path': '$.userId' } + }, + messageId: { + type: 'string', + required: true, + description: 'The Segment messageId', + label: 'MessageId', + default: { '@path': '$.messageId' } + }, + properties: { + type: 'object', + label: 'Properties', + description: 'Properties to associate with the event', + default: { '@path': '$.properties' } + } + }, + perform: (request, { payload, settings }) => { + return request(`${CLAY_API_BASE_URL}/segment/${settings.connection_key}/events`, { + method: 'POST', + headers: { + Authorization: `Bearer ${settings.secret_key}` + }, + json: payload + }) + } +} + +export default action From ef2223c5d7f72ff762052313b3c57b7270209932 Mon Sep 17 00:00:00 2001 From: Ayush Goyal Date: Fri, 25 Jul 2025 17:54:23 -0400 Subject: [PATCH 4/5] Remove type from fields and hardcode --- .../__tests__/__snapshots__/snapshot.test.ts.snap | 8 ++++---- .../__tests__/__snapshots__/snapshot.test.ts.snap | 5 ++--- .../destinations/clay/pageVisit/generated-types.ts | 4 ---- .../src/destinations/clay/pageVisit/index.ts | 12 ++++-------- .../__tests__/__snapshots__/snapshot.test.ts.snap | 4 ++-- .../src/destinations/clay/track/generated-types.ts | 4 ---- .../src/destinations/clay/track/index.ts | 12 ++++-------- 7 files changed, 16 insertions(+), 33 deletions(-) diff --git a/packages/destination-actions/src/destinations/clay/__tests__/__snapshots__/snapshot.test.ts.snap b/packages/destination-actions/src/destinations/clay/__tests__/__snapshots__/snapshot.test.ts.snap index 5263f136fe..4950511b40 100644 --- a/packages/destination-actions/src/destinations/clay/__tests__/__snapshots__/snapshot.test.ts.snap +++ b/packages/destination-actions/src/destinations/clay/__tests__/__snapshots__/snapshot.test.ts.snap @@ -17,7 +17,7 @@ Object { "testType": "eu76@B#kao", }, "timestamp": Any, - "type": "eu76@B#kao", + "type": "page", "userAgent": "eu76@B#kao", "userId": "eu76@B#kao", } @@ -27,7 +27,7 @@ exports[`Testing snapshot for actions-clay destination: pageVisit action - requi Object { "ip": "eu76@B#kao", "messageId": Any, - "type": "eu76@B#kao", + "type": "page", } `; @@ -48,7 +48,7 @@ Object { "testType": "NHQVrUx(HtHKStZdY", }, "timestamp": Any, - "type": "NHQVrUx(HtHKStZdY", + "type": "track", "userAgent": "NHQVrUx(HtHKStZdY", "userId": "NHQVrUx(HtHKStZdY", } @@ -59,6 +59,6 @@ Object { "event": "NHQVrUx(HtHKStZdY", "ip": "NHQVrUx(HtHKStZdY", "messageId": Any, - "type": "NHQVrUx(HtHKStZdY", + "type": "track", } `; diff --git a/packages/destination-actions/src/destinations/clay/pageVisit/__tests__/__snapshots__/snapshot.test.ts.snap b/packages/destination-actions/src/destinations/clay/pageVisit/__tests__/__snapshots__/snapshot.test.ts.snap index 0a9e0d87fb..49fae819a4 100644 --- a/packages/destination-actions/src/destinations/clay/pageVisit/__tests__/__snapshots__/snapshot.test.ts.snap +++ b/packages/destination-actions/src/destinations/clay/pageVisit/__tests__/__snapshots__/snapshot.test.ts.snap @@ -17,7 +17,7 @@ Object { "testType": "zZg8#WaG5V1[W1", }, "timestamp": Any, - "type": "zZg8#WaG5V1[W1", + "type": "page", "userAgent": "zZg8#WaG5V1[W1", "userId": "zZg8#WaG5V1[W1", } @@ -38,10 +38,9 @@ Object { "properties": Object { "ip": "zZg8#WaG5V1[W1", "messageId": "zZg8#WaG5V1[W1", - "type": "zZg8#WaG5V1[W1", }, "timestamp": Any, - "type": "zZg8#WaG5V1[W1", + "type": "page", "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1", "userId": "user1234", } diff --git a/packages/destination-actions/src/destinations/clay/pageVisit/generated-types.ts b/packages/destination-actions/src/destinations/clay/pageVisit/generated-types.ts index 20142d88a1..fc04431645 100644 --- a/packages/destination-actions/src/destinations/clay/pageVisit/generated-types.ts +++ b/packages/destination-actions/src/destinations/clay/pageVisit/generated-types.ts @@ -5,10 +5,6 @@ export interface Payload { * The name of the page */ name?: string - /** - * The type of the event. Either "page" or "track" - */ - type: string /** * The timestamp of the page event */ diff --git a/packages/destination-actions/src/destinations/clay/pageVisit/index.ts b/packages/destination-actions/src/destinations/clay/pageVisit/index.ts index c4151091c5..129c40773b 100644 --- a/packages/destination-actions/src/destinations/clay/pageVisit/index.ts +++ b/packages/destination-actions/src/destinations/clay/pageVisit/index.ts @@ -15,13 +15,6 @@ const action: ActionDefinition = { required: false, default: { '@path': '$.name' } }, - type: { - type: 'string', - description: 'The type of the event. Either "page" or "track"', - label: 'Type', - required: true, - default: { '@path': '$.type' } - }, timestamp: { type: 'string', format: 'date-time', @@ -123,7 +116,10 @@ const action: ActionDefinition = { headers: { Authorization: `Bearer ${settings.secret_key}` }, - json: payload + json: { + ...payload, + type: 'page' + } }) } } diff --git a/packages/destination-actions/src/destinations/clay/track/__tests__/__snapshots__/snapshot.test.ts.snap b/packages/destination-actions/src/destinations/clay/track/__tests__/__snapshots__/snapshot.test.ts.snap index ebb221608f..12515c0b44 100644 --- a/packages/destination-actions/src/destinations/clay/track/__tests__/__snapshots__/snapshot.test.ts.snap +++ b/packages/destination-actions/src/destinations/clay/track/__tests__/__snapshots__/snapshot.test.ts.snap @@ -17,7 +17,7 @@ Object { "testType": "s#NxR#]zhFrIncI7QBq", }, "timestamp": "2050-11-27T17:19:35.865Z", - "type": "s#NxR#]zhFrIncI7QBq", + "type": "track", "userAgent": "s#NxR#]zhFrIncI7QBq", "userId": "s#NxR#]zhFrIncI7QBq", } @@ -28,6 +28,6 @@ Object { "event": "s#NxR#]zhFrIncI7QBq", "ip": "s#NxR#]zhFrIncI7QBq", "messageId": "s#NxR#]zhFrIncI7QBq", - "type": "s#NxR#]zhFrIncI7QBq", + "type": "track", } `; diff --git a/packages/destination-actions/src/destinations/clay/track/generated-types.ts b/packages/destination-actions/src/destinations/clay/track/generated-types.ts index b41fc77ff5..62e9f83f68 100644 --- a/packages/destination-actions/src/destinations/clay/track/generated-types.ts +++ b/packages/destination-actions/src/destinations/clay/track/generated-types.ts @@ -5,10 +5,6 @@ export interface Payload { * The name of the event */ event: string - /** - * The type of the event. Either "page" or "track" - */ - type: string /** * The timestamp of the track event */ diff --git a/packages/destination-actions/src/destinations/clay/track/index.ts b/packages/destination-actions/src/destinations/clay/track/index.ts index 29384b3adf..80f52e32aa 100644 --- a/packages/destination-actions/src/destinations/clay/track/index.ts +++ b/packages/destination-actions/src/destinations/clay/track/index.ts @@ -15,13 +15,6 @@ const action: ActionDefinition = { label: 'Event Name', default: { '@path': '$.event' } }, - type: { - type: 'string', - description: 'The type of the event. Either "page" or "track"', - label: 'Type', - required: true, - default: { '@path': '$.type' } - }, timestamp: { type: 'string', format: 'date-time', @@ -123,7 +116,10 @@ const action: ActionDefinition = { headers: { Authorization: `Bearer ${settings.secret_key}` }, - json: payload + json: { + ...payload, + type: 'track' + } }) } } From 4c1fa1e8a3ed5f49f6b75021644f382cba301a3a Mon Sep 17 00:00:00 2001 From: Ayush Goyal Date: Mon, 28 Jul 2025 07:34:11 -0400 Subject: [PATCH 5/5] Fix snapshot test --- .../__snapshots__/snapshot.test.ts.snap | 22 ++++++++++++++++--- .../clay/track/__tests__/snapshot.test.ts | 16 ++++++++++---- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/packages/destination-actions/src/destinations/clay/track/__tests__/__snapshots__/snapshot.test.ts.snap b/packages/destination-actions/src/destinations/clay/track/__tests__/__snapshots__/snapshot.test.ts.snap index 12515c0b44..b74be80fbb 100644 --- a/packages/destination-actions/src/destinations/clay/track/__tests__/__snapshots__/snapshot.test.ts.snap +++ b/packages/destination-actions/src/destinations/clay/track/__tests__/__snapshots__/snapshot.test.ts.snap @@ -5,7 +5,7 @@ Object { "anonymousId": "s#NxR#]zhFrIncI7QBq", "event": "s#NxR#]zhFrIncI7QBq", "ip": "s#NxR#]zhFrIncI7QBq", - "messageId": "s#NxR#]zhFrIncI7QBq", + "messageId": Any, "page": Object { "path": "s#NxR#]zhFrIncI7QBq", "referrer": "s#NxR#]zhFrIncI7QBq", @@ -16,7 +16,7 @@ Object { "properties": Object { "testType": "s#NxR#]zhFrIncI7QBq", }, - "timestamp": "2050-11-27T17:19:35.865Z", + "timestamp": Any, "type": "track", "userAgent": "s#NxR#]zhFrIncI7QBq", "userId": "s#NxR#]zhFrIncI7QBq", @@ -25,9 +25,25 @@ Object { exports[`Testing snapshot for Clay's track destination action: required fields 1`] = ` Object { + "anonymousId": "anonId1234", "event": "s#NxR#]zhFrIncI7QBq", "ip": "s#NxR#]zhFrIncI7QBq", - "messageId": "s#NxR#]zhFrIncI7QBq", + "messageId": Any, + "page": Object { + "path": "/academy/", + "referrer": "", + "search": "", + "title": "Analytics Academy", + "url": "https://segment.com/academy/", + }, + "properties": Object { + "event": "s#NxR#]zhFrIncI7QBq", + "ip": "s#NxR#]zhFrIncI7QBq", + "messageId": "s#NxR#]zhFrIncI7QBq", + }, + "timestamp": Any, "type": "track", + "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1", + "userId": "user1234", } `; diff --git a/packages/destination-actions/src/destinations/clay/track/__tests__/snapshot.test.ts b/packages/destination-actions/src/destinations/clay/track/__tests__/snapshot.test.ts index 9de9a20675..56d90973d3 100644 --- a/packages/destination-actions/src/destinations/clay/track/__tests__/snapshot.test.ts +++ b/packages/destination-actions/src/destinations/clay/track/__tests__/snapshot.test.ts @@ -25,7 +25,8 @@ describe(`Testing snapshot for ${destinationSlug}'s ${actionSlug} destination ac event: event, mapping: event.properties, settings: settingsData, - auth: undefined + auth: undefined, + useDefaultMappings: true }) const request = responses[0].request @@ -33,7 +34,10 @@ describe(`Testing snapshot for ${destinationSlug}'s ${actionSlug} destination ac try { const json = JSON.parse(rawBody) - expect(json).toMatchSnapshot() + expect(json).toMatchSnapshot({ + timestamp: expect.any(String), + messageId: expect.any(String) + }) return } catch (err) { expect(rawBody).toMatchSnapshot() @@ -58,7 +62,8 @@ describe(`Testing snapshot for ${destinationSlug}'s ${actionSlug} destination ac event: event, mapping: event.properties, settings: settingsData, - auth: undefined + auth: undefined, + useDefaultMappings: true }) const request = responses[0].request @@ -66,7 +71,10 @@ describe(`Testing snapshot for ${destinationSlug}'s ${actionSlug} destination ac try { const json = JSON.parse(rawBody) - expect(json).toMatchSnapshot() + expect(json).toMatchSnapshot({ + timestamp: expect.any(String), + messageId: expect.any(String) + }) return } catch (err) { expect(rawBody).toMatchSnapshot()