11import {
22 AudienceDestinationDefinition ,
33 InvalidAuthenticationError ,
4- PayloadValidationError ,
4+ IntegrationError ,
55 defaultValues
66} from '@segment/actions-core'
7+ import type { RefreshTokenResponse , AmazonTestAuthenticationError } from './types'
8+ import type { Settings , AudienceSettings } from './generated-types'
79import {
8- RefreshTokenResponse ,
9- AmazonTestAuthenticationError ,
1010 AudiencePayload ,
11- DSPTargetResource ,
12- AMCTargetResource
13- } from './types'
14- import type { Settings , AudienceSettings } from './generated-types'
15- import { extractNumberAndSubstituteWithStringValue , getAuthToken } from './utils'
16- import { SYNC_TO , REGEX_AUDIENCEID , REGEX_ADVERTISERID , TTL_MAX_VALUE } from './constants'
11+ extractNumberAndSubstituteWithStringValue ,
12+ getAuthToken ,
13+ REGEX_ADVERTISERID ,
14+ REGEX_AUDIENCEID ,
15+ TTL_MAX_VALUE
16+ } from './utils'
17+ import { AMAZON_AMC_AUTH_API_VERSION } from './versioning-info'
1718import syncAudiencesToDSP from './syncAudiencesToDSP'
1819
1920const destination : AudienceDestinationDefinition < Settings , AudienceSettings > = {
@@ -76,17 +77,6 @@ const destination: AudienceDestinationDefinition<Settings, AudienceSettings> = {
7677 } ,
7778
7879 audienceFields : {
79- syncTo : {
80- type : 'string' ,
81- label : 'Sync To' ,
82- required : false ,
83- description : 'Chose whether to sync audience to DSP or AMC. Defaults to DSP.' ,
84- choices : [
85- { label : 'DSP' , value : SYNC_TO . DSP } ,
86- { label : 'AMC' , value : SYNC_TO . AMC }
87- ] ,
88- default : SYNC_TO . DSP
89- } ,
9080 description : {
9181 type : 'string' ,
9282 label : 'Description' ,
@@ -141,23 +131,9 @@ const destination: AudienceDestinationDefinition<Settings, AudienceSettings> = {
141131 //As per the discussion, for now taking `advertiserId` in `audienceFields` as user can create multiple audiences within a single instance of destination.
142132 advertiserId : {
143133 label : 'Advertiser ID' ,
144- description : 'Advertiser ID when when syncing an Audience to Amazon Ads DSP' ,
145- type : 'string'
146- } ,
147- amcInstanceId : {
148- label : 'AMC Instance ID' ,
149- description : 'AMC Instance ID used when syncing an audience to Amazon Marketing Cloud (AMC)' ,
150- type : 'string'
151- } ,
152- amcAccountId : {
153- label : 'AMC Account ID' ,
154- description : 'AMC Account ID used when syncing an audience to Amazon Marketing Cloud (AMC)' ,
155- type : 'string'
156- } ,
157- amcAccountMarketplaceId : {
158- label : 'AMC Account Marketplace ID' ,
159- description : 'AMC Account Marketplace ID used when syncing an audience to Amazon Marketing Cloud (AMC)' ,
160- type : 'string'
134+ description : 'Advertiser Id' ,
135+ type : 'string' ,
136+ required : true
161137 }
162138 } ,
163139
@@ -169,115 +145,64 @@ const destination: AudienceDestinationDefinition<Settings, AudienceSettings> = {
169145 async createAudience ( request , createAudienceInput ) {
170146 const { audienceName, audienceSettings, settings } = createAudienceInput
171147 const endpoint = settings . region
148+ const description = audienceSettings ?. description
149+ const advertiser_id = audienceSettings ?. advertiserId
150+ const external_audience_id = audienceSettings ?. externalAudienceId
151+ const country_code = audienceSettings ?. countryCode
152+ const ttl = audienceSettings ?. ttl
153+ const currency = audienceSettings ?. currency
154+ const cpm_cents = audienceSettings ?. cpmCents
172155
173- const {
174- syncTo = SYNC_TO . DSP ,
175- description,
176- advertiserId,
177- externalAudienceId,
178- countryCode,
179- ttl,
180- currency,
181- cpmCents,
182- amcInstanceId,
183- amcAccountId,
184- amcAccountMarketplaceId
185- } = audienceSettings || { }
186-
187- if ( syncTo === SYNC_TO . DSP && ! advertiserId ) {
188- throw new PayloadValidationError ( 'Advertiser Id value is required when syncing an audience to DSP' )
189- }
190-
191- if ( syncTo === SYNC_TO . AMC && ( ! amcInstanceId || ! amcAccountId || ! amcAccountMarketplaceId ) ) {
192- throw new PayloadValidationError (
193- 'AMC Instance Id, AMC Account Id and AMC Account Marketplace Id value are required when syncing audience to AMC'
194- )
156+ if ( ! advertiser_id ) {
157+ throw new IntegrationError ( 'Missing advertiserId Value' , 'MISSING_REQUIRED_FIELD' , 400 )
195158 }
196159
197160 if ( ! description ) {
198- throw new PayloadValidationError ( 'Missing description Value' )
161+ throw new IntegrationError ( 'Missing description Value' , 'MISSING_REQUIRED_FIELD' , 400 )
199162 }
200163
201- if ( ! externalAudienceId ) {
202- throw new PayloadValidationError ( 'Missing externalAudienceId Value' )
164+ if ( ! external_audience_id ) {
165+ throw new IntegrationError ( 'Missing externalAudienceId Value' , 'MISSING_REQUIRED_FIELD' , 400 )
203166 }
204167
205168 if ( ! audienceName ) {
206- throw new PayloadValidationError ( 'Missing audienceName Value' )
169+ throw new IntegrationError ( 'Missing audienceName Value' , 'MISSING_REQUIRED_FIELD' , 400 )
207170 }
208-
209- if ( ! countryCode ) {
210- throw new PayloadValidationError ( 'Missing countryCode Value' )
171+ if ( ! country_code ) {
172+ throw new IntegrationError ( 'Missing countryCode Value' , 'MISSING_REQUIRED_FIELD' , 400 )
211173 }
212-
213174 if ( ttl && ttl > TTL_MAX_VALUE ) {
214- throw new PayloadValidationError ( `TTL must have value less than or equal to ${ TTL_MAX_VALUE } ` )
215- }
216-
217- let connectionId : string | undefined = undefined
218- if ( syncTo === SYNC_TO . AMC ) {
219- const payloadStringConnsAPI = JSON . stringify ( { amcInstanceId, amcAccountId, amcAccountMarketplaceId } )
220- const response = await request ( `${ endpoint } /amc/audiences/connections` , {
221- method : 'POST' ,
222- body : payloadStringConnsAPI ,
223- headers : {
224- 'Content-Type' : 'application/vnd.amcaudiencesconnections.v1+json'
225- }
226- } )
227-
228- connectionId = JSON . parse ( await response . text ( ) ) ?. connectionId
229- if ( ! connectionId ) {
230- throw new PayloadValidationError (
231- 'Unable to fetch connectionId with given AMC amcInstanceId amcAccountId and amcAccountMarketplaceId details'
232- )
233- }
175+ throw new IntegrationError ( `TTL must have value less than or equal to ${ TTL_MAX_VALUE } ` , 'INVALID_INPUT' , 400 )
234176 }
235177
236178 const payload : AudiencePayload = {
237179 name : audienceName ,
238- description,
239- targetResource : ( ( ) => {
240- if ( syncTo === SYNC_TO . AMC ) {
241- const targetResource : AMCTargetResource = {
242- amcInstanceId : amcInstanceId as string ,
243- amcAccountId : amcAccountId as string ,
244- amcAccountMarketplaceId : amcAccountMarketplaceId as string ,
245- connectionId : connectionId as string
246- }
247- return targetResource
248- }
249- if ( syncTo === SYNC_TO . DSP ) {
250- const targetResource : DSPTargetResource = {
251- advertiserId : advertiserId as string
252- }
253- return targetResource
254- }
255- throw new PayloadValidationError ( 'Invalid syncTo value' )
256- } ) ( ) ,
180+ description : description ,
181+ targetResource : {
182+ advertiserId : advertiser_id
183+ } ,
257184 metadata : {
258- externalAudienceId
185+ externalAudienceId : external_audience_id
259186 } ,
260- countryCode
187+ countryCode : country_code
261188 }
262189
263190 if ( ttl ) {
264191 payload . metadata . ttl = ttl
265192 }
266193
267- if ( cpmCents && currency ) {
194+ if ( cpm_cents && currency ) {
268195 payload . metadata . audienceFees = [ ]
269196 payload . metadata ?. audienceFees . push ( {
270197 currency,
271- cpmCents
198+ cpmCents : cpm_cents
272199 } )
273200 }
274201
275202 let payloadString = JSON . stringify ( payload )
276203 // Regular expression to find a advertiserId numeric string and replace the quoted advertiserId string with an unquoted number
277204 // AdvertiserId is very big number string and can not be assigned or converted to number directly as it changes the value due to integer overflow.
278- if ( syncTo === SYNC_TO . DSP ) {
279- payloadString = payloadString . replace ( REGEX_ADVERTISERID , '"advertiserId":$1' )
280- }
205+ payloadString = payloadString . replace ( REGEX_ADVERTISERID , '"advertiserId":$1' )
281206
282207 const response = await request ( `${ endpoint } /amc/audiences/metadata` , {
283208 method : 'POST' ,
@@ -292,17 +217,17 @@ const destination: AudienceDestinationDefinition<Settings, AudienceSettings> = {
292217 // Regular expression to find a audienceId number and replace the audienceId with quoted string
293218 const resp = extractNumberAndSubstituteWithStringValue ( res , REGEX_AUDIENCEID , '"audienceId":"$1"' )
294219 return {
295- externalId : syncTo === SYNC_TO . DSP ? resp . audienceId : resp . audienceId + ':' + connectionId
220+ externalId : resp . audienceId
296221 }
297222 } ,
298223
299224 async getAudience ( request , getAudienceInput ) {
300225 // getAudienceInput.externalId represents audience ID that was created in createAudience
301- const audience_id = getAudienceInput . externalId . split ( ':' ) [ 0 ]
226+ const audience_id = getAudienceInput . externalId
302227 const { settings } = getAudienceInput
303228 const endpoint = settings . region
304229 if ( ! audience_id ) {
305- throw new PayloadValidationError ( 'Missing audienceId value' )
230+ throw new IntegrationError ( 'Missing audienceId value' , 'MISSING_REQUIRED_FIELD' , 400 )
306231 }
307232 const response = await request ( `${ endpoint } /amc/audiences/metadata/${ audience_id } ` , {
308233 method : 'GET' ,
0 commit comments