Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[Snap Audiences] Add error tracking for create audience #2565

Merged
merged 4 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ const createAudienceInput = {

describe('Snap Audiences', () => {
describe('createAudience', () => {
beforeEach(() => {
// Catch all Segment API requests and return 200
nock('https://api.segment.io').persist().post('/v1/track').reply(200)
})

afterEach(() => {
nock.cleanAll()
})

it('should fail if Segment audience name is available', async () => {
createAudienceInput.audienceName = ''
await expect(testDestination.createAudience(createAudienceInput)).rejects.toThrowError(IntegrationError)
Expand Down
128 changes: 110 additions & 18 deletions packages/destination-actions/src/destinations/snap-audiences/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AudienceDestinationDefinition, defaultValues, IntegrationError } from '@segment/actions-core'
import { AudienceDestinationDefinition, defaultValues, IntegrationError, RequestClient } from '@segment/actions-core'
import type { Settings, AudienceSettings } from './generated-types'
import syncAudience from './syncAudience'
const ACCESS_TOKEN_URL = 'https://accounts.snapchat.com/login/oauth2/access_token'
Expand Down Expand Up @@ -116,29 +116,101 @@ const destination: AudienceDestinationDefinition<Settings, AudienceSettings> = {
const ad_account_id = createAudienceInput.settings.ad_account_id
const { customAudienceName, description, retention_in_days } = createAudienceInput.audienceSettings || {}

// Track input values
await sendToSegment(
'jsYMXBFcHxTHnNfZfwQo5FsL8jVRrjAu',
'Create Audience Input',
ad_account_id,
{
rawInput: createAudienceInput,
extractedValues: {
audienceName,
ad_account_id,
customAudienceName,
description,
retention_in_days
}
},
request
)

if (!audienceName) {
throw new IntegrationError('Missing audience name value', 'MISSING_REQUIRED_FIELD', 400)
}

const response = await request(`https://adsapi.snapchat.com/v1/adaccounts/${ad_account_id}/segments`, {
method: 'POST',
json: {
segments: [
{
name: customAudienceName !== '' ? customAudienceName : audienceName,
source_type: 'FIRST_PARTY',
ad_account_id,
description,
retention_in_days
}
]
} as CreateAudienceReq
})
const requestBody = {
segments: [
{
name: customAudienceName !== '' ? customAudienceName : audienceName,
source_type: 'FIRST_PARTY',
ad_account_id,
description,
retention_in_days
}
]
}

const data: SnapAudienceResponse = await response.json()
const snapAudienceId = data.segments[0].segment.id
// Track request details
await sendToSegment(
'jsYMXBFcHxTHnNfZfwQo5FsL8jVRrjAu',
'Create Audience Request Details',
ad_account_id,
{
url: `https://adsapi.snapchat.com/v1/adaccounts/${ad_account_id}/segments`,
headers: {
Authorization: 'Bearer [TOKEN HIDDEN]',
'Content-Type': 'application/json'
},
requestBody
},
request
)

return { externalId: snapAudienceId }
try {
const response = await request(`https://adsapi.snapchat.com/v1/adaccounts/${ad_account_id}/segments`, {
method: 'POST',
json: {
segments: [
{
name: customAudienceName !== '' ? customAudienceName : audienceName,
source_type: 'FIRST_PARTY',
ad_account_id,
description,
retention_in_days
}
]
} as CreateAudienceReq
})
const data: SnapAudienceResponse = await response.json()
const snapAudienceId = data.segments[0].segment.id

// Track response
await sendToSegment(
'jsYMXBFcHxTHnNfZfwQo5FsL8jVRrjAu',
'Create Audience Response',
ad_account_id,
{
status: response.status,
responseData: data,
extractedAudienceId: snapAudienceId
},
request
)

return { externalId: snapAudienceId }
} catch (error) {
// Error response
await sendToSegment(
'jsYMXBFcHxTHnNfZfwQo5FsL8jVRrjAu',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the linter might be complaining about error.response.data

image

'Create Audience Error',
ad_account_id,
{
error: error.response.data
},
request
)
}
return { externalId: '1234' }
},

getAudience: async (request, { externalId }) => {
Expand All @@ -157,4 +229,24 @@ const destination: AudienceDestinationDefinition<Settings, AudienceSettings> = {
}
}

async function sendToSegment(writeKey: any, event: string, userId: string, properties: any, request: RequestClient) {
const response = await request('https://api.segment.io/v1/track', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Basic ${Buffer.from(writeKey).toString('base64')}`
},
json: {
event,
userId,
properties
}
})

if (!response.ok) {
throw new Error(`Failed to send event to Segment: ${response.statusText}`)
}

return response
}
export default destination
Loading