@@ -22,8 +22,9 @@ import {
2222 CLIENT_HINTS_KEY ,
2323 EMPTY ,
2424 GVLID ,
25- VERSION ,
25+ VERSION , INVALID_ID , GDPR_ENDPOINT , VR_ENDPOINT , SYNC_ENDPOINT , SCREEN_PARAMS , GDPR_SYNC_ENDPOINT , SYNC_REFRESH_MILL
2626} from '../libraries/intentIqConstants/intentIqConstants.js' ;
27+ import { SYNC_KEY } from '../libraries/intentIqUtils/getSyncKey.js' ;
2728
2829/**
2930 * @typedef {import('../modules/userId/index.js').Submodule } Submodule
@@ -44,9 +45,7 @@ const encoderCH = {
4445 wow64 : 7 ,
4546 fullVersionList : 8
4647} ;
47- const INVALID_ID = 'INVALID_ID' ;
48- const ENDPOINT = 'https://api.intentiq.com' ;
49- const GDPR_ENDPOINT = 'https://api-gdpr.intentiq.com' ;
48+
5049export let firstPartyData ;
5150
5251/**
@@ -82,6 +81,89 @@ export function decryptData(encryptedText) {
8281 return bytes . toString ( Utf8 ) ;
8382}
8483
84+ function collectDeviceInfo ( ) {
85+ return {
86+ windowInnerHeight : window . innerHeight ,
87+ windowInnerWidth : window . innerWidth ,
88+ devicePixelRatio : window . devicePixelRatio ,
89+ windowScreenHeight : window . screen . height ,
90+ windowScreenWidth : window . screen . width ,
91+ language : navigator . language
92+ }
93+ }
94+
95+ function addUniquenessToUrl ( url ) {
96+ url += '&tsrnd=' + Math . floor ( Math . random ( ) * 1000 ) + '_' + new Date ( ) . getTime ( ) ;
97+ return url ;
98+ }
99+
100+ function appendDeviceInfoToUrl ( url , deviceInfo ) {
101+ const screenParamsString = Object . entries ( SCREEN_PARAMS )
102+ . map ( ( [ index , param ] ) => {
103+ const value = ( deviceInfo ) [ param ] ;
104+ return `${ index } :${ value } ` ;
105+ } )
106+ . join ( ',' ) ;
107+
108+ url += `&cz=${ encodeURIComponent ( screenParamsString ) } ` ;
109+ url += `&dw=${ deviceInfo . windowScreenWidth } &dh=${ deviceInfo . windowScreenHeight } &dpr=${ deviceInfo . devicePixelRatio } &lan=${ deviceInfo . language } ` ;
110+ return url ;
111+ }
112+
113+ function appendFirstPartyData ( url , firstPartyData , partnerData ) {
114+ url += firstPartyData . pid ? '&pid=' + encodeURIComponent ( firstPartyData . pid ) : '' ;
115+ url += firstPartyData . pcid ? '&iiqidtype=2&iiqpcid=' + encodeURIComponent ( firstPartyData . pcid ) : '' ;
116+ url += firstPartyData . pcidDate ? '&iiqpciddate=' + encodeURIComponent ( firstPartyData . pcidDate ) : '' ;
117+ return url
118+ }
119+
120+ function appendCMPData ( url , cmpData ) {
121+ url += cmpData . uspString ? '&us_privacy=' + encodeURIComponent ( cmpData . uspString ) : '' ;
122+ url += cmpData . gppString ? '&gpp=' + encodeURIComponent ( cmpData . gppString ) : '' ;
123+ url += cmpData . gdprApplies
124+ ? '&gdpr_consent=' + encodeURIComponent ( cmpData . gdprString ) + '&gdpr=1'
125+ : '&gdpr=0' ;
126+ return url
127+ }
128+
129+ export function createPixelUrl ( firstPartyData , clientHints , configParams , partnerData , cmpData ) {
130+ const deviceInfo = collectDeviceInfo ( )
131+
132+ let url = cmpData . gdprString ? GDPR_SYNC_ENDPOINT : SYNC_ENDPOINT ;
133+ url += '/profiles_engine/ProfilesEngineServlet?at=20&mi=10&secure=1'
134+ url += '&dpi=' + configParams . partner ;
135+ url = appendFirstPartyData ( url , firstPartyData , partnerData ) ;
136+ url = addUniquenessToUrl ( url ) ;
137+ url += partnerData ?. clientType ? '&idtype=' + partnerData . clientType : '' ;
138+ if ( deviceInfo ) url = appendDeviceInfoToUrl ( url , deviceInfo )
139+ url += VERSION ? '&jsver=' + VERSION : '' ;
140+ if ( clientHints ) url += '&uh=' + encodeURIComponent ( clientHints ) ;
141+ url = appendVrrefAndFui ( url , configParams . domainName ) ;
142+ url = appendCMPData ( url , cmpData )
143+ return url ;
144+ }
145+
146+ function sendSyncRequest ( allowedStorage , url , partner , firstPartyData , newUser ) {
147+ const lastSyncDate = Number ( readData ( SYNC_KEY ( partner ) || '' , allowedStorage ) ) || false ;
148+ const lastSyncElapsedTime = Date . now ( ) - lastSyncDate
149+
150+ if ( firstPartyData . isOptedOut ) {
151+ const needToDoSync = ( Date . now ( ) - ( firstPartyData ?. date || firstPartyData ?. sCal || Date . now ( ) ) ) > SYNC_REFRESH_MILL
152+ if ( newUser || needToDoSync ) {
153+ ajax ( url , ( ) => {
154+ } , undefined , { method : 'GET' , withCredentials : true } ) ;
155+ if ( firstPartyData ?. date ) {
156+ firstPartyData . date = Date . now ( )
157+ storeData ( FIRST_PARTY_KEY , JSON . stringify ( firstPartyData ) , allowedStorage , firstPartyData ) ;
158+ }
159+ }
160+ } else if ( ! lastSyncDate || lastSyncElapsedTime > SYNC_REFRESH_MILL ) {
161+ storeData ( SYNC_KEY ( partner ) , Date . now ( ) + '' , allowedStorage ) ;
162+ ajax ( url , ( ) => {
163+ } , undefined , { method : 'GET' , withCredentials : true } ) ;
164+ }
165+ }
166+
85167/**
86168 * Parse json if possible, else return null
87169 * @param data
@@ -161,6 +243,7 @@ export const intentIqIdSubmodule = {
161243 decode ( value ) {
162244 return value && value != '' && INVALID_ID != value ? { 'intentIqId' : value } : undefined ;
163245 } ,
246+
164247 /**
165248 * performs action to obtain id and return a value in the callback's response argument
166249 * @function
@@ -210,13 +293,7 @@ export const intentIqIdSubmodule = {
210293
211294 const currentBrowserLowerCase = detectBrowser ( ) ;
212295 const browserBlackList = typeof configParams . browserBlackList === 'string' ? configParams . browserBlackList . toLowerCase ( ) : '' ;
213-
214- // Check if current browser is in blacklist
215- if ( browserBlackList ?. includes ( currentBrowserLowerCase ) ) {
216- logError ( 'User ID - intentIqId submodule: browser is in blacklist!' ) ;
217- if ( configParams . callback ) configParams . callback ( '' , BLACK_LIST ) ;
218- return ;
219- }
296+ let newUser = false ;
220297
221298 if ( ! firstPartyData ?. pcid ) {
222299 const firstPartyId = generateGUID ( ) ;
@@ -230,6 +307,7 @@ export const intentIqIdSubmodule = {
230307 gdprString : EMPTY ,
231308 date : Date . now ( )
232309 } ;
310+ newUser = true ;
233311 storeData ( FIRST_PARTY_KEY , JSON . stringify ( firstPartyData ) , allowedStorage , firstPartyData ) ;
234312 } else if ( ! firstPartyData . pcidDate ) {
235313 firstPartyData . pcidDate = Date . now ( ) ;
@@ -284,7 +362,6 @@ export const intentIqIdSubmodule = {
284362 firstPartyData . uspString = cmpData . uspString ;
285363 firstPartyData . gppString = cmpData . gppString ;
286364 firstPartyData . gdprString = cmpData . gdprString ;
287- firstPartyData . date = Date . now ( ) ;
288365 shouldCallServer = true ;
289366 storeData ( FIRST_PARTY_KEY , JSON . stringify ( firstPartyData ) , allowedStorage , firstPartyData ) ;
290367 storeData ( FIRST_PARTY_DATA_KEY , JSON . stringify ( partnerData ) , allowedStorage , firstPartyData ) ;
@@ -297,26 +374,29 @@ export const intentIqIdSubmodule = {
297374 firePartnerCallback ( )
298375 }
299376
377+ // Check if current browser is in blacklist
378+ if ( browserBlackList ?. includes ( currentBrowserLowerCase ) ) {
379+ logError ( 'User ID - intentIqId submodule: browser is in blacklist! Data will be not provided.' ) ;
380+ if ( configParams . callback ) configParams . callback ( '' , BLACK_LIST ) ;
381+ const url = createPixelUrl ( firstPartyData , clientHints , configParams , partnerData , cmpData )
382+ sendSyncRequest ( allowedStorage , url , configParams . partner , firstPartyData , newUser )
383+ return
384+ }
385+
300386 if ( ! shouldCallServer ) {
301387 if ( isGroupB ) runtimeEids = { eids : [ ] } ;
302388 firePartnerCallback ( ) ;
303389 return { id : runtimeEids . eids } ;
304390 }
305391
306392 // use protocol relative urls for http or https
307- let url = `${ gdprDetected ? GDPR_ENDPOINT : ENDPOINT } /profiles_engine/ProfilesEngineServlet?at=39&mi=10&dpi=${ configParams . partner } &pt=17&dpn=1` ;
393+ let url = `${ gdprDetected ? GDPR_ENDPOINT : VR_ENDPOINT } /profiles_engine/ProfilesEngineServlet?at=39&mi=10&dpi=${ configParams . partner } &pt=17&dpn=1` ;
308394 url += configParams . pcid ? '&pcid=' + encodeURIComponent ( configParams . pcid ) : '' ;
309395 url += configParams . pai ? '&pai=' + encodeURIComponent ( configParams . pai ) : '' ;
310- url += firstPartyData . pcid ? '&iiqidtype=2&iiqpcid=' + encodeURIComponent ( firstPartyData . pcid ) : '' ;
311- url += firstPartyData . pid ? '&pid=' + encodeURIComponent ( firstPartyData . pid ) : '' ;
396+ url = appendFirstPartyData ( url , firstPartyData , partnerData ) ;
312397 url += ( partnerData . cttl ) ? '&cttl=' + encodeURIComponent ( partnerData . cttl ) : '' ;
313398 url += ( partnerData . rrtt ) ? '&rrtt=' + encodeURIComponent ( partnerData . rrtt ) : '' ;
314- url += firstPartyData . pcidDate ? '&iiqpciddate=' + encodeURIComponent ( firstPartyData . pcidDate ) : '' ;
315- url += cmpData . uspString ? '&us_privacy=' + encodeURIComponent ( cmpData . uspString ) : '' ;
316- url += cmpData . gppString ? '&gpp=' + encodeURIComponent ( cmpData . gppString ) : '' ;
317- url += cmpData . gdprApplies
318- ? '&gdpr_consent=' + encodeURIComponent ( cmpData . gdprString ) + '&gdpr=1'
319- : '&gdpr=0' ;
399+ url = appendCMPData ( url , cmpData )
320400 url += clientHints ? '&uh=' + encodeURIComponent ( clientHints ) : '' ;
321401 url += VERSION ? '&jsver=' + VERSION : '' ;
322402 url += firstPartyData ?. group ? '&testGroup=' + encodeURIComponent ( firstPartyData . group ) : '' ;
@@ -403,7 +483,7 @@ export const intentIqIdSubmodule = {
403483 }
404484
405485 if ( 'ct' in respJson ) {
406- partnerData . ct = respJson . ct ;
486+ partnerData . clientType = respJson . ct ;
407487 }
408488
409489 if ( 'sid' in respJson ) {
0 commit comments