Skip to content
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

adnuntias Bid Adapter: Added GDPR support and segment passing #6796

Merged
merged 8 commits into from
Jun 3, 2021
22 changes: 17 additions & 5 deletions modules/adnuntiusBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,50 @@
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER } from '../src/mediaTypes.js';
import * as utils from '../src/utils.js';
import { config } from '../src/config.js';

const BIDDER_CODE = 'adnuntius';
const ENDPOINT_URL = 'https://delivery.adnuntius.com/i?tzo=';
const GVLID = 855;

export const spec = {
code: BIDDER_CODE,

gvlid: GVLID,
supportedMediaTypes: [BANNER],
isBidRequestValid: function (bid) {
return !!(bid.bidId || (bid.params.member && bid.params.invCode));
},

buildRequests: function (validBidRequests) {
buildRequests: function (validBidRequests, bidderRequest) {
const networks = {};
const bidRequests = {};
const requests = [];
const segments = config.getConfig('segments');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not so much of a change request, but more curious about this config setting. I am not aware of segments being set under the config at the top level, so I am curious if this is something specific to your adapter and if so, should it be in your docs? I also want to make sure that this is not meant to be first party segment data that is defined to be passed via ortb2.user.data and ortb2.site.content.data respectively

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was strugling to find where to put it, and yes it's just meant to be for our adapter only, but if ortb2.user.data is the place to put it I will go for it. Should I also prefix our segments (like adn-segments) or are there any other rules for how to structure it?

Copy link
Contributor

@mmoschovas mmoschovas May 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can offer suggestions, but Im not sure where you mean to put the prefix. Maybe reviewing this will offer a better understanding of first party segment data: https://docs.prebid.org/features/firstPartyData.html. You can see under ortb2.user.data, this is an array of objects that "should" include at the very least name and segment (with segment as an array of objects), as well as ext property that can contain other data. Let me know if this helps in any way. Also, the pubs will have the option to utilize setBidderConfig to set config data meant only for specific adapters, meaning that only your adapter will receive those values if set using your bidder.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should now be solved and the documentation is filed under this pull request:
prebid/prebid.github.io#2975

utils.logMessage('CONF', segments)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this line should be removed entirely, as this does not seem like a necessary log to me. I believe that we would rather not inflate code with messaging that is not pertinent as this is neither a user warning/error or really clear in label as to what is being logged - also this can be achieved in the console via a pbjs.getConfig('segments').

Copy link
Contributor Author

@mikael-lundin mikael-lundin May 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, that was just a blunder from me, will remove that.

const tzo = new Date().getTimezoneOffset();

const gdprApplies = utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies');
const consentString = utils.deepAccess(bidderRequest, 'gdprConsent.consentString');
const reqConsent = (gdprApplies !== undefined) ? '&consentString=' + consentString : '';
const reqSegments = (segments !== undefined && utils.isArray(segments) && segments.length > 0) ? '&segments=' + segments.join(',') : '';
for (var i = 0; i < validBidRequests.length; i++) {
const bid = validBidRequests[i]
const network = bid.params.network || 'network';
const targeting = bid.params.targeting || {};

bidRequests[network] = bidRequests[network] || [];
bidRequests[network].push(bid);

networks[network] = networks[network] || {};
networks[network].adUnits = networks[network].adUnits || [];
networks[network].adUnits.push({ ...bid.params.targeting, auId: bid.params.auId, targetId: bid.bidId });
networks[network].adUnits.push({ ...targeting, auId: bid.params.auId, targetId: bid.bidId });
}

const networkKeys = Object.keys(networks)
for (var j = 0; j < networkKeys.length; j++) {
const network = networkKeys[j];
requests.push({
method: 'POST',
url: ENDPOINT_URL + tzo + '&format=json',
url: ENDPOINT_URL + tzo + '&format=json' + reqSegments + reqConsent,
data: JSON.stringify(networks[network]),
bid: bidRequests[network]
});
Expand Down
32 changes: 32 additions & 0 deletions test/spec/modules/adnuntiusBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@
import { expect } from 'chai'; // may prefer 'assert' in place of 'expect'
import { spec } from 'modules/adnuntiusBidAdapter.js';
import { newBidder } from 'src/adapters/bidderFactory.js';
import { config } from 'src/config.js';

describe('adnuntiusBidAdapter', function () {
beforeEach(function () {
config.setConfig({ segments: [] });
});
const tzo = new Date().getTimezoneOffset();
const ENDPOINT_URL = `https://delivery.adnuntius.com/i?tzo=${tzo}&format=json`;
const ENDPOINT_URL_SEGMENTS = `https://delivery.adnuntius.com/i?tzo=${tzo}&format=json&segments=segment1,segment2`;
const ENDPOINT_URL_CONSENT = `https://delivery.adnuntius.com/i?tzo=${tzo}&format=json&consentString=consentString`;
const adapter = newBidder(spec);

const bidRequests = [
Expand Down Expand Up @@ -116,6 +122,32 @@ describe('adnuntiusBidAdapter', function () {
expect(request[0]).to.have.property('data');
expect(request[0].data).to.equal('{\"adUnits\":[{\"auId\":\"8b6bc\",\"targetId\":\"123\"}]}');
});

it('should pass segments if available in config', function () {
config.setConfig({
segments: ['segment1', 'segment2']
});
const request = spec.buildRequests(bidRequests);
expect(request.length).to.equal(1);
expect(request[0]).to.have.property('url')
expect(request[0].url).to.equal(ENDPOINT_URL_SEGMENTS);
});
});

describe('user privacy', function () {
it('should send GDPR Consent data if gdprApplies', function () {
let request = spec.buildRequests(bidRequests, { gdprConsent: { gdprApplies: true, consentString: 'consentString' } });
expect(request.length).to.equal(1);
expect(request[0]).to.have.property('url')
expect(request[0].url).to.equal(ENDPOINT_URL_CONSENT);
});

it('should not send GDPR Consent data if gdprApplies equals undefined', function () {
let request = spec.buildRequests(bidRequests, { gdprConsent: { gdprApplies: undefined, consentString: 'consentString' } });
expect(request.length).to.equal(1);
expect(request[0]).to.have.property('url')
expect(request[0].url).to.equal(ENDPOINT_URL);
});
});

describe('interpretResponse', function () {
Expand Down