@@ -125,53 +125,69 @@ export async function editDeviceMobileIds(
125125 return response . data
126126}
127127
128- export async function editContactInfo (
129- request : RequestClient ,
130- payloads : Payload [ ] ,
131- operation : 'add' | 'remove' ,
132- statsContext ?: StatsContext
133- ) {
134- const payload = payloads [ 0 ]
135- const audienceId = payloads [ 0 ] . external_id
136-
137- //Check if one of the required identifiers exists otherwise drop the event
138- if (
139- payload . emails === undefined &&
140- payload . phoneNumbers === undefined &&
141- payload . firstName === undefined &&
142- payload . lastName === undefined
143- ) {
144- return
145- }
146-
147- //Format the endpoint
148- const endpoint = DV360API + '/' + audienceId + ':editCustomerMatchMembers'
149-
150- // Prepare the request payload
151- const contactInfoList = {
152- contactInfos : [ processPayload ( payload ) ] ,
128+ // Helper to build contactInfoList
129+ function buildContactInfoList ( contactInfos : Record < string , string > [ ] ) : {
130+ contactInfos : Record < string , string > [ ]
131+ consent : { adUserData : string ; adPersonalization : string }
132+ } {
133+ return {
134+ contactInfos,
153135 consent : {
154136 adUserData : CONSENT_STATUS_GRANTED ,
155137 adPersonalization : CONSENT_STATUS_GRANTED
156138 }
157139 }
140+ }
158141
159- // Convert the payload to string if needed
160- const requestPayload = JSON . stringify ( {
161- advertiserId : payload . advertiser_id ,
142+ // Helper to build request payload
143+ function buildRequestPayload (
144+ advertiserId : string ,
145+ contactInfoList : {
146+ contactInfos : Record < string , string > [ ]
147+ consent : { adUserData : string ; adPersonalization : string }
148+ } ,
149+ operation : 'add' | 'remove'
150+ ) {
151+ return JSON . stringify ( {
152+ advertiserId,
162153 ...( operation === 'add' ? { addedContactInfoList : contactInfoList } : { } ) ,
163154 ...( operation === 'remove' ? { removedContactInfoList : contactInfoList } : { } )
164155 } )
156+ }
165157
158+ export async function editContactInfo (
159+ request : RequestClient ,
160+ payloads : Payload [ ] ,
161+ operation : 'add' | 'remove' ,
162+ statsContext ?: StatsContext
163+ ) {
164+ if ( ! payloads || payloads . length === 0 ) return
165+
166+ // TODO: remove this check, the framework should handle this
167+ const validPayloads = payloads . filter (
168+ ( payload ) =>
169+ payload . emails !== undefined ||
170+ payload . phoneNumbers !== undefined ||
171+ payload . firstName !== undefined ||
172+ payload . lastName !== undefined
173+ )
174+ if ( validPayloads . length === 0 ) return
175+
176+ // Assume all payloads are for the same audience/advertiser (use first)
177+ const { external_id : audienceId , advertiser_id : advertiserId } = validPayloads [ 0 ]
178+ if ( ! audienceId || ! advertiserId ) {
179+ throw new IntegrationError ( 'Missing required audience or advertiser ID' , 'MISSING_REQUIRED_FIELD' , 400 )
180+ }
181+ const contactInfos = validPayloads . map ( processPayload )
182+ const contactInfoList = buildContactInfoList ( contactInfos )
183+ const requestPayload = buildRequestPayload ( advertiserId , contactInfoList , operation )
184+ const endpoint = DV360API + '/' + audienceId + ':editCustomerMatchMembers'
166185 const response = await request < DV360editCustomerMatchResponse > ( endpoint , {
167186 method : 'POST' ,
168- headers : {
169- 'Content-Type' : 'application/json; charset=utf-8'
170- } ,
187+ headers : { 'Content-Type' : 'application/json; charset=utf-8' } ,
171188 body : requestPayload
172189 } )
173-
174- statsContext ?. statsClient ?. incr ( 'addCustomerMatchMembers.success' , 1 , statsContext ?. tags )
190+ statsContext ?. statsClient ?. incr ( 'addCustomerMatchMembers.success' , contactInfos . length , statsContext ?. tags )
175191 return response . data
176192}
177193
0 commit comments