11import { AudienceDestinationDefinition , defaultValues , IntegrationError } from '@segment/actions-core'
22import type { Settings , AudienceSettings } from './generated-types'
33import syncAudience from './syncAudience'
4- const ACCESS_TOKEN_URL = 'https://accounts.snapchat.com/login/oauth2/access_token'
5-
6- interface RefreshTokenResponse {
7- access_token : string
8- }
9- interface SnapAudienceResponse {
10- segments : {
11- segment : {
12- id : string
13- }
14- } [ ]
15- }
16- interface CreateAudienceReq {
17- segments : {
18- name : string
19- source_type : string
20- ad_account_id : string
21- description : string
22- retention_in_days : number
23- } [ ]
24- }
4+ import { CreateAudienceReq , RefreshTokenResponse , SnapAudienceResponse } from './types'
5+ import { ACCESS_TOKEN_URL , DEFAULT_RETENTION_DAYS } from './constants'
256
267const destination : AudienceDestinationDefinition < Settings , AudienceSettings > = {
278 name : 'Snap Audiences (Actions)' ,
@@ -93,33 +74,18 @@ const destination: AudienceDestinationDefinition<Settings, AudienceSettings> = {
9374 eventSlug : 'journeys_step_entered_track'
9475 } ,
9576 {
96- name : 'Sync Audience with Email ' ,
97- subscribe : 'type = "track" and context.traits.email exists ' ,
77+ name : 'Sync Engage Audience ' ,
78+ subscribe : 'type = "track" or type = "identify" ' ,
9879 partnerAction : 'syncAudience' ,
99- mapping : { ...defaultValues ( syncAudience . fields ) , schema_type : 'EMAIL_SHA256' } ,
100- type : 'automatic'
101- } ,
102- {
103- name : 'Sync Audience with Phone' ,
104- subscribe : 'type = "track" and properties.phone exists' ,
105- partnerAction : 'syncAudience' ,
106- mapping : { ...defaultValues ( syncAudience . fields ) , schema_type : 'PHONE_SHA256' } ,
107- type : 'automatic'
108- } ,
109- {
110- name : 'Sync Audience with Mobile AD ID' ,
111- subscribe : 'type = "track" and context.device.advertisingId exists' ,
112- partnerAction : 'syncAudience' ,
113- mapping : { ...defaultValues ( syncAudience . fields ) , schema_type : 'MOBILE_AD_ID_SHA256' } ,
80+ mapping : { ...defaultValues ( syncAudience . fields ) } ,
11481 type : 'automatic'
11582 }
11683 ] ,
11784 audienceFields : {
11885 customAudienceName : {
11986 type : 'string' ,
12087 label : 'Audience Name' ,
121- description :
122- 'Name for the audience that will be created in Snap. Defaults to the snake_cased Segment audience name if left blank.' ,
88+ description : 'Name for the audience that will be created in Snap. Defaults to the snake_cased Segment audience name if left blank.' ,
12389 default : '' ,
12490 required : false
12591 } ,
@@ -133,7 +99,7 @@ const destination: AudienceDestinationDefinition<Settings, AudienceSettings> = {
13399 retention_in_days : {
134100 type : 'number' ,
135101 label : 'Retention in days' ,
136- description : '# of days to retain audience members. (Default retention is lifetime represented as 9999)' ,
102+ description : 'Number of days to retain audience members. (Default retention is lifetime represented as 9999)' ,
137103 default : 9999 ,
138104 required : false
139105 }
@@ -144,44 +110,50 @@ const destination: AudienceDestinationDefinition<Settings, AudienceSettings> = {
144110 full_audience_sync : false
145111 } ,
146112 async createAudience ( request , createAudienceInput ) {
147- const audienceName = createAudienceInput . audienceName
148- const ad_account_id = createAudienceInput . settings . ad_account_id
149- const { customAudienceName, description, retention_in_days } = createAudienceInput . audienceSettings || { }
113+ const {
114+ audienceName,
115+ settings : { ad_account_id } = { } ,
116+ audienceSettings : {
117+ customAudienceName,
118+ description,
119+ retention_in_days
120+ } = { }
121+ } = createAudienceInput
150122
151123 if ( ! audienceName ) {
152124 throw new IntegrationError ( 'Missing audience name value' , 'MISSING_REQUIRED_FIELD' , 400 )
153125 }
154126
155- const response = await request ( `https://adsapi.snapchat.com/v1/adaccounts/${ ad_account_id } /segments` , {
127+ if ( ! ad_account_id ) {
128+ throw new IntegrationError ( 'Missing Ad Account ID. Please configure the Ad Account ID in the destination settings.' , 'MISSING_REQUIRED_FIELD' , 400 )
129+ }
130+
131+ const json : CreateAudienceReq = {
132+ segments : [
133+ {
134+ name : customAudienceName || audienceName ,
135+ source_type : 'FIRST_PARTY' ,
136+ ad_account_id,
137+ description : description || `Audience ${ audienceName } created by Segment` ,
138+ retention_in_days : retention_in_days || DEFAULT_RETENTION_DAYS
139+ }
140+ ]
141+ }
142+
143+ const response = await request < SnapAudienceResponse > ( `https://adsapi.snapchat.com/v1/adaccounts/${ ad_account_id } /segments` , {
156144 method : 'POST' ,
157- json : {
158- segments : [
159- {
160- name : customAudienceName !== '' ? customAudienceName : audienceName ,
161- source_type : 'FIRST_PARTY' ,
162- ad_account_id,
163- description,
164- retention_in_days
165- }
166- ]
167- } as CreateAudienceReq
145+ json
168146 } )
169147
170- const data : SnapAudienceResponse = await response . json ( )
171- const snapAudienceId = data . segments [ 0 ] . segment . id
172-
173- return { externalId : snapAudienceId }
148+ return { externalId : response . data . segments [ 0 ] . segment . id }
174149 } ,
175150
176151 getAudience : async ( request , { externalId } ) => {
177- const response = await request ( `https://adsapi.snapchat.com/v1/segments/${ externalId } ` , {
152+ const response = await request < SnapAudienceResponse > ( `https://adsapi.snapchat.com/v1/segments/${ externalId } ` , {
178153 method : 'GET'
179154 } )
180155
181- const data : SnapAudienceResponse = await response . json ( )
182- const snapAudienceId = data . segments [ 0 ] . segment . id
183-
184- return { externalId : snapAudienceId }
156+ return { externalId : response . data . segments [ 0 ] . segment . id }
185157 }
186158 }
187159}
0 commit comments