Prebid.js icon indicating copy to clipboard operation
Prebid.js copied to clipboard

Yieldmo Synthetic Inventory Module: ad prefetch from the yieldmo ad server

Open ym-abaranov opened this issue 4 years ago • 24 comments

This PR adds an ad prefetch feature to the module. The main thing is to make sure that Yieldmo will get an ad and only then it makes a Google Ad Manager ad request to avoid discrepancy. To implement that we've reproduced a Yieldmo ad request with certain query parameters such as page title, URL, width and height, consent, etc.

Type of change

  • [ ] Bugfix
  • [x] Feature
  • [ ] New bidder adapter
  • [ ] Code style update (formatting, local variables)
  • [ ] Refactoring (no functional changes, no api changes)
  • [ ] Build related changes
  • [ ] CI related changes
  • [ ] Does this change affect user-facing APIs or examples documented on http://prebid.org?
  • [ ] Other

Description of change

  • test parameters for validating bids
{
  bidder: '<bidder name>',
  params: {
    // ...
  }
}

Be sure to test the integration with your adserver using the Hello World sample page.

  • contact email of the adapter’s maintainer
  • [ ] official adapter submission

For any changes that affect user-facing APIs or example code documented on http://prebid.org, please provide:

  • A link to a PR on the docs repo at https://github.com/prebid/prebid.github.io/

Other information

ym-abaranov avatar Dec 03 '21 21:12 ym-abaranov

This pull request introduces 2 alerts when merging b8607f509e4073fc3706f74f5da5fe26b2e4c1da into f50b7ec513fd872c7c9410fdc5bbcee4f4128f54 - view on LGTM.com

new alerts:

  • 2 for Useless conditional

lgtm-com[bot] avatar Dec 03 '21 21:12 lgtm-com[bot]

@ym-abaranov please see the lgtm induced alerts

patmmccann avatar Dec 14 '21 19:12 patmmccann

@ym-abaranov please see the lgtm induced alerts

resolved

ym-abaranov avatar Dec 15 '21 20:12 ym-abaranov

@ym-abaranov Please update the description on the PR explaining what this new module does.

msm0504 avatar Dec 22 '21 21:12 msm0504

@ym-abaranov Please update the description on the PR explaining what this new module does. @msm0504 done

ym-abaranov avatar Dec 22 '21 22:12 ym-abaranov

Hi @ym-abaranov,

I see that an external ajax call is made, you can use the inbuilt ajax library for that. Also, I see a lot of code duplication between Consent Management modules and your code over here. Isn't there any way to avoid that?

Also, this change, will it require any changes in the docs?

Fawke avatar Jan 12 '22 16:01 Fawke

Hi @Fawke,

Isn't there any way to avoid that?

Actually, there is a way. Those functions are not exported in the consent management modules, so if you can export them, probably we could import them as is.

Also, this change, will it require any changes in the docs?

No, it's not

ym-abaranov avatar Jan 12 '22 18:01 ym-abaranov

@ym-abaranov,

Can you please route your ajax call through the in-built module apart from the other changes I suggested.

I'm not sure if importing the functions from the consentManagement file is allowed, modules are not allowed to import stuff from other modules.

Isn't there a way for you to utilise the consent information passed by the existing module?

Fawke avatar Jan 21 '22 14:01 Fawke

@Fawke,

Can you please route your ajax call through the in-built module apart from the other changes I suggested.

Done

Isn't there a way for you to utilise the consent information passed by the existing module?

I'm not quite sure about that. Seems like this module was designed to be used with adapters and at the first glance there is no proper way to use it in the module.

I'm not sure if importing the functions from the consentManagement file is allowed, modules are not allowed to import stuff from other modules.

These implementations look pretty much conventional. So we could re-implement it in the module but the problem with DRY will be present. We could resolve it in any way you would like.

ym-abaranov avatar Jan 27 '22 21:01 ym-abaranov

Tagging @bretg and @gglas. I think this issue of code duplication between the consentManagement modules and this module was discussed in one of our PMC meetings. Did we take a stance on this?

Fawke avatar Feb 01 '22 13:02 Fawke

core's adapterManager exposes UPS and GDPR consent data, this is an example of a module using them:

https://github.com/prebid/Prebid.js/blob/5abf5c3af94eba9736ccf6cdc623adb0f98ed767/modules/liveIntentIdSystem.js#L85-L89

Would that work instead of the duplication? An issue I see is that it does not make it easy to discriminate between "consent data not available yet" and "consent module is not installed" (both would just return null), which would be a problem for code that runs on page load. Even then, updating that interface to accept a callback seems better than duplicating.

dgirardi avatar Feb 02 '22 18:02 dgirardi

@ym-abaranov Would solution proposed above work for you?

Fawke avatar Feb 14 '22 11:02 Fawke

@Fawke @dgirardi I don’t think that would work. In order to get consent data (uspDataHandler.getConsentData) it previously should be stored by consentManagement and consentManagementUsp. Those modules could be used and initialized though, they won’t store anything because they will invoke by requestBids before hook, but our module doesn’t create any bids hanse no data will be stored.

ym-abaranov avatar Feb 14 '22 19:02 ym-abaranov

@ym-abaranov the handler interface, and its interaction with the consent management modules, could be modified to address those points with a much smaller footprint compared the replication of the consent management logic. Something like:

let handler = {
    // ...
    enabled: false,
    callbacks: [],
    enable() { /* called by consent management module on init */ this.enabled = true; }
    onConsentData(callback) { /* this is your entry point */ if (!this.enabled) callback(null) else if (this.consentData != null) callback(this.consentData) else { this.callbacks.push(callback)} }
    setConsentData(cd) { /* ... */ this.callbacks.forEach((cb) => cb(cd)) }
}

It's not exactly that simple becase there are some inconsistencies between GDPR and USP on how setConsentData is called; I can make these changes in a separate PR if you prefer to not get too deep in the inner workings of Prebid - would this approach work for you?

dgirardi avatar Feb 14 '22 20:02 dgirardi

@dgirardi From my point of view exporting lookupIabConsent and lookupUspConsent might have an even smaller footprint though. Also, the handler interface and its interaction changes would work just fine for us.

ym-abaranov avatar Feb 14 '22 21:02 ym-abaranov

@ym-abaranov I'll post a PR with the handler changes. exporting/importing across modules does not work well because the webpack compilation would repeat the code on both ends (since all modules are optional, it can't simply call into some code that may not be there; that's why they go through the handlers now); I agree it looks simpler but the final build output would have roughly the same duplication as in this PR.

I'll come back with an update soon.

dgirardi avatar Feb 14 '22 22:02 dgirardi

https://github.com/prebid/Prebid.js/pull/8071 should allow you to call gpdrDataHandler.promise.then(...) and uspDataHandler.promise.then(...) instead of the lookup functions.

dgirardi avatar Feb 15 '22 15:02 dgirardi

@dgirardi I'm not quite sure I'm using it right but looks like a promise is never resolved. Here are my steps:

  1. Initializing consentManagment:
pbjs.que.push(function() {
  pbjs.setConfig({
    consentManagement: {
      gdpr: {},
      usp: {cmpApi: 'daa', timeout: 7500}
    }
  });
});
  1. Importing handlers in the module and logging data:
gdprDataHandler.promise.then(data => console.log('gdprData, data)).catch(e => console.log(e));
uspDataHandler.promise.then(data => console.log('uspDatar', data)).catch(e => console.log(e));

Did I miss something?

ym-abaranov avatar Mar 10 '22 02:03 ym-abaranov

@ym-abaranov can you post an updated version, or a test page to help me troubleshoot? if I try your config, and drop the same lines where the last version now calls the lookupConsent logic, it's working as expected (considering the CMP I'm using does not support USP):

async_consent

dgirardi avatar Mar 10 '22 17:03 dgirardi

@dgirardi Here’s the test page — https://qa.yieldmo.com/temp/prebid-module-test/index.html So the duplicated methods from the adapterManager and adapterManagmentUsp: (lookupUspConsent and lookupIabConsent) are logging the data just fine. There are interfaces in the global scope too: __tcfapi and __uspapi which can be used to get user data. For example __tcfapi('getTCData', 2, (tcData, success) => {console.log(tcData)}); will return {…, tcString: "CPV2iS4PV2i…”}. Google scripts are also able to get a user consent data and and send this data via ad request https://securepubads.g.doubleclick.net/gampad/ads contains both values in the query params: gdpr_consent=CPV2iS4PV2 and us_privacy=1--- But the promises are never resolved

ym-abaranov avatar Mar 14 '22 16:03 ym-abaranov

@ym-abaranov I believe that's because there's no auction in your scenario - the consentManagement logic is triggered by requestBids. Is this an issue? I was assuming that every page that loads Prebid would also immediately start an auction, but if that's not the case I may have missed the mark on that PR.

dgirardi avatar Mar 14 '22 17:03 dgirardi

@dgirardi probably. I guess there is a chance that a publisher will use the module with no auction

ym-abaranov avatar Mar 14 '22 22:03 ym-abaranov

@ym-abaranov I'm working on a second PR to resolve consent data without an auction; I plan to leave everything in adapterManager untouched, so hopefully it shouldn't block your work here.

dgirardi avatar Mar 15 '22 14:03 dgirardi

Hi @ym-abaranov,

Just checking if the changes made in #8185 worked for you? If so, I can review it and get this merged.

Fawke avatar Jun 21 '22 12:06 Fawke

Closing this as it's open for a long time without any activity. Please feel free to reopen.

Fawke avatar Oct 31 '22 08:10 Fawke