diff --git a/modules/BTBidAdapter.js b/modules/BTBidAdapter.js index 84ccb37655b..c9680322f07 100644 --- a/modules/BTBidAdapter.js +++ b/modules/BTBidAdapter.js @@ -7,6 +7,7 @@ import { ortbConverter } from '../libraries/ortbConverter/converter.js'; const BIDDER_CODE = 'blockthrough'; const GVLID = 815; const ENDPOINT_URL = 'https://pbs.btloader.com/openrtb2/auction'; +const SYNC_URL = 'https://cdn.btloader.com/user_sync.html'; const CONVERTER = ortbConverter({ context: { @@ -121,6 +122,45 @@ function interpretResponse(serverResponse, request) { }).bids; } +/** + * Generates user synchronization data based on provided options and consents. + * + * @param {Object} syncOptions - Synchronization options. + * @param {Object[]} serverResponses - An array of server responses. + * @param {Object} gdprConsent - GDPR consent information. + * @param {string} uspConsent - US Privacy consent string. + * @param {Object} gppConsent - Google Publisher Policies (GPP) consent information. + * @returns {Object[]} An array of user synchronization objects. + */ +function getUserSyncs( + syncOptions, + serverResponses, + gdprConsent, + uspConsent, + gppConsent +) { + let syncs = []; + const syncUrl = new URL(SYNC_URL); + + if (syncOptions.iframeEnabled) { + if (gdprConsent) { + syncUrl.searchParams.set('gdpr', Number(gdprConsent.gdprApplies)); + syncUrl.searchParams.set('gdpr_consent', gdprConsent.consentString); + } + if (gppConsent) { + syncUrl.searchParams.set('gpp', gppConsent.gppString); + syncUrl.searchParams.set('gpp_sid', gppConsent.applicableSections); + } + if (uspConsent) { + syncUrl.searchParams.set('us_privacy', uspConsent); + } + + syncs.push({ type: 'iframe', url: syncUrl.href }); + } + + return syncs; +} + export const spec = { code: BIDDER_CODE, gvlid: GVLID, @@ -128,6 +168,7 @@ export const spec = { isBidRequestValid, buildRequests, interpretResponse, + getUserSyncs, }; registerBidder(spec); diff --git a/test/spec/modules/BTBidAdapte_spec.js b/test/spec/modules/BTBidAdapte_spec.js index 59230a45dbd..10a282f5d53 100644 --- a/test/spec/modules/BTBidAdapte_spec.js +++ b/test/spec/modules/BTBidAdapte_spec.js @@ -151,4 +151,49 @@ describe('BT Bid Adapter', () => { expect(bids).to.deep.equal(expectedBids); }); }); + + describe('getUserSyncs', () => { + const SYNC_URL = 'https://cdn.btloader.com/user_sync.html'; + + it('should return an empty array if no sync options are provided', () => { + const syncs = spec.getUserSyncs({}, [], null, null, null); + + expect(syncs).to.deep.equal([]); + }); + + it('should include consent parameters in sync URL if they are provided', () => { + const gdprConsent = { + gdprApplies: true, + consentString: 'GDPRConsentString123', + }; + const gppConsent = { + gppString: 'GPPString123', + applicableSections: ['sectionA'], + }; + const us_privacy = '1YNY'; + const expectedSyncUrl = `${SYNC_URL}?gdpr=1&gdpr_consent=${gdprConsent.consentString}&gpp=${gppConsent.gppString}&gpp_sid=sectionA&us_privacy=${us_privacy}`; + + const syncs = spec.getUserSyncs( + { iframeEnabled: true }, + [], + gdprConsent, + us_privacy, + gppConsent + ); + + expect(syncs).to.deep.equal([{ type: 'iframe', url: expectedSyncUrl }]); + }); + + it('should not include any consent parameters if no consents are provided', () => { + const syncs = spec.getUserSyncs( + { iframeEnabled: true }, + [], + null, + null, + null + ); + + expect(syncs).to.deep.equal([{ type: 'iframe', url: SYNC_URL }]); + }); + }); });