Skip to content

Adquery Bid Adapter : IdSystem fix getId and decode method, added userSync with iframe type #11019

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 53 additions & 18 deletions modules/adqueryBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER} from '../src/mediaTypes.js';
import {buildUrl, logInfo, parseSizesInput, triggerPixel} from '../src/utils.js';
import {buildUrl, logInfo, logMessage, parseSizesInput, triggerPixel} from '../src/utils.js';

/**
* @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest
Expand All @@ -14,7 +14,9 @@ const ADQUERY_GVLID = 902;
const ADQUERY_BIDDER_CODE = 'adquery';
const ADQUERY_BIDDER_DOMAIN_PROTOCOL = 'https';
const ADQUERY_BIDDER_DOMAIN = 'bidder.adquery.io';
const ADQUERY_USER_SYNC_DOMAIN = ADQUERY_BIDDER_DOMAIN_PROTOCOL + '://' + ADQUERY_BIDDER_DOMAIN + '/prebid/userSync?1=1';
const ADQUERY_STATIC_DOMAIN_PROTOCOL = 'https';
const ADQUERY_STATIC_DOMAIN = 'api.adquery.io';
const ADQUERY_USER_SYNC_DOMAIN = ADQUERY_BIDDER_DOMAIN;
const ADQUERY_DEFAULT_CURRENCY = 'PLN';
const ADQUERY_NET_REVENUE = true;
const ADQUERY_TTL = 360;
Expand All @@ -26,7 +28,6 @@ export const spec = {
supportedMediaTypes: [BANNER],

/**
* f
* @param {object} bid
* @return {boolean}
*/
Expand All @@ -41,10 +42,18 @@ export const spec = {
*/
buildRequests: (bidRequests, bidderRequest) => {
const requests = [];

let adqueryRequestUrl = buildUrl({
protocol: ADQUERY_BIDDER_DOMAIN_PROTOCOL,
hostname: ADQUERY_BIDDER_DOMAIN,
pathname: '/prebid/bid',
// search: params
});

for (let i = 0, len = bidRequests.length; i < len; i++) {
const request = {
method: 'POST',
url: ADQUERY_BIDDER_DOMAIN_PROTOCOL + '://' + ADQUERY_BIDDER_DOMAIN + '/prebid/bid',
url: adqueryRequestUrl, // ADQUERY_BIDDER_DOMAIN_PROTOCOL + '://' + ADQUERY_BIDDER_DOMAIN + '/prebid/bid',
data: buildRequest(bidRequests[i], bidderRequest),
options: {
withCredentials: false,
Expand All @@ -62,8 +71,8 @@ export const spec = {
* @return {Bid[]}
*/
interpretResponse: (response, request) => {
logInfo(request);
logInfo(response);
logMessage(request);
logMessage(response);

const res = response && response.body && response.body.data;
let bidResponses = [];
Expand Down Expand Up @@ -125,7 +134,6 @@ export const spec = {
*/
onBidWon: (bid) => {
logInfo('onBidWon', bid);

const bidString = JSON.stringify(bid);
let copyOfBid = JSON.parse(bidString);
delete copyOfBid.ad;
Expand Down Expand Up @@ -169,21 +177,48 @@ export const spec = {
});
triggerPixel(adqueryRequestUrl);
},
/**
* Retrieves user synchronization URLs based on provided options and consents.
*
* @param {object} syncOptions - Options for synchronization.
* @param {object[]} serverResponses - Array of server responses.
* @param {object} gdprConsent - GDPR consent object.
* @param {object} uspConsent - USP consent object.
* @returns {object[]} - Array of synchronization URLs.
*/
getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => {
let syncUrl = ADQUERY_USER_SYNC_DOMAIN;
if (gdprConsent && gdprConsent.consentString) {
if (typeof gdprConsent.gdprApplies === 'boolean') {
syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`;
} else {
syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`;
}
logMessage('getUserSyncs', syncOptions, serverResponses, gdprConsent, uspConsent);
let syncData = {
'gdpr': gdprConsent && gdprConsent.gdprApplies ? 1 : 0,
'gdpr_consent': gdprConsent && gdprConsent.consentString ? gdprConsent.consentString : '',
'ccpa_consent': uspConsent && uspConsent.uspConsent ? uspConsent.uspConsent : '',
};

if (window.qid) { // only for new users (new qid)
syncData.qid = window.qid;
}
if (uspConsent && uspConsent.consentString) {
syncUrl += `&ccpa_consent=${uspConsent.consentString}`;

let syncUrlObject = {
protocol: ADQUERY_BIDDER_DOMAIN_PROTOCOL,
hostname: ADQUERY_USER_SYNC_DOMAIN,
pathname: '/prebid/userSync',
search: syncData
};

if (syncOptions.iframeEnabled) {
syncUrlObject.protocol = ADQUERY_STATIC_DOMAIN_PROTOCOL;
syncUrlObject.hostname = ADQUERY_STATIC_DOMAIN;
syncUrlObject.pathname = '/user-sync-iframe.html';

return [{
type: 'iframe',
url: buildUrl(syncUrlObject)
}];
}

return [{
type: 'image',
url: syncUrl
url: buildUrl(syncUrlObject)
}];
}
};
Expand All @@ -205,7 +240,7 @@ function buildRequest(validBidRequests, bidderRequest) {
// onetime User ID
const ramdomValues = Array.from(window.crypto.getRandomValues(new Uint32Array(4)));
userId = ramdomValues.map(val => val.toString(36)).join('').substring(0, 20);
logInfo('generated onetime User ID: ', userId);
logMessage('generated onetime User ID: ', userId);
window.qid = userId;
}

Expand Down
15 changes: 13 additions & 2 deletions modules/adqueryIdSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import {ajax} from '../src/ajax.js';
import {getStorageManager} from '../src/storageManager.js';
import {submodule} from '../src/hook.js';
import {isFn, isPlainObject, isStr, logError, logInfo} from '../src/utils.js';
import {isFn, isPlainObject, isStr, logError, logInfo, logMessage} from '../src/utils.js';
import {MODULE_TYPE_UID} from '../src/activities/modules.js';

/**
Expand Down Expand Up @@ -66,7 +66,18 @@ export const adqueryIdSubmodule = {
* @returns {IdResponse|undefined}
*/
getId(config) {
logInfo('adqueryIdSubmodule getId');
logMessage('adqueryIdSubmodule getId');

let qid = storage.getDataFromLocalStorage('qid');

if (qid) {
return {
callback: function (callback) {
callback(qid);
}
}
}

if (!isPlainObject(config.params)) {
config.params = {};
}
Expand Down
30 changes: 29 additions & 1 deletion test/spec/modules/adqueryBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,39 @@ describe('adqueryBidAdapter', function () {

describe('getUserSyncs', function () {
it('should return iframe sync', function () {
let sync = spec.getUserSyncs()
let sync = spec.getUserSyncs(
{
iframeEnabled: true,
pixelEnabled: true,
},
{},
{
consentString: 'ALL',
gdprApplies: true,
},
{}
)
expect(sync.length).to.equal(1)
expect(sync[0].type === 'iframe')
expect(typeof sync[0].url === 'string')
})
it('should return image sync', function () {
let sync = spec.getUserSyncs(
{
iframeEnabled: false,
pixelEnabled: true,
},
{},
{
consentString: 'ALL',
gdprApplies: true,
},
{}
)
expect(sync.length).to.equal(1)
expect(sync[0].type === 'image')
expect(typeof sync[0].url === 'string')
})

it('Should return array of objects with proper sync config , include GDPR', function() {
const syncData = spec.getUserSyncs({}, {}, {
Expand Down
12 changes: 6 additions & 6 deletions test/spec/modules/adqueryIdSystem_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,23 @@ describe('AdqueryIdSystem', function () {
const callback = adqueryIdSubmodule.getId(config).callback;
callback(callbackSpy);
const request = server.requests[0];
expect(request.url).to.contains(`https://bidder.adquery.io/prebid/qid?qid=`);
request.respond(200, {'Content-Type': 'application/json'}, JSON.stringify({qid: '6dd9eab7dfeab7df6dd9ea'}));
expect(callbackSpy.lastCall.lastArg).to.deep.equal('6dd9eab7dfeab7df6dd9ea');
expect(request.url).to.contain(`https://bidder.adquery.io/prebid/qid`);
request.respond(200, { 'Content-Type': 'application/json' }, JSON.stringify({ qid: 'qid_string' }));
expect(callbackSpy.lastCall.lastArg).to.deep.equal('qid_string');
});

it('allows configurable id url', function () {
const config = {
params: {
url: 'https://another_bidder.adquery.io/qid'
url: 'https://bidder2.adquery.io'
}
};
const callbackSpy = sinon.spy();
const callback = adqueryIdSubmodule.getId(config).callback;
callback(callbackSpy);
const request = server.requests[0];
expect(request.url).to.contains('https://another_bidder.adquery.io/qid');
request.respond(200, {'Content-Type': 'application/json'}, JSON.stringify({qid: 'testqid'}));
expect(request.url).to.contains('https://bidder2.adquery.io');
request.respond(200, { 'Content-Type': 'application/json' }, JSON.stringify({ qid: 'testqid' }));
expect(callbackSpy.lastCall.lastArg).to.deep.equal('testqid');
});
});
Expand Down