Closed bretg closed 5 years ago
@bretg What's your thinking about whether the default config is before the bid request or after?
For sync delay for bid request, is there a reason to have separate timer? An option that keeps things simpler would be run the OpenID sync with the rest of the adapter syncs.
Discussed with some members of OpenID consortium and RubiconProject internal. Changed:
delayAuctionStart
option as more clearly defined behaviorLooks like a great start - thanks Bret!
delayAuctionStart
to something like maxDelayToAuction
- indicating that we will trigger the auction ASAP if we get a quick response from openID or until max time is hit. usersync: {
universalIds: [{
name: 'openId',
url: 'URL_TO_OPEN_ID_SERVER',
storage: {
type: 'html5',
name: 'pbjs-openid'
},
maxDelayToAuction: 500
}]
}
Not sure if that's a use case we'd ever need to support though.
This looks similar to the already existing pubCommonId module so we should probably make this generic enough to support multiple implementations.
Right now the pubCommonId uses the requestBids hook to add its extension. Don't know if we want to do something similar here or add a more specific extension point for shared ids.
+1 to Rich's comment. I think we can cover pubCommonId with the proposed structure above.
Edit: We'd probably remove pubCommonId as a separate module and either 1) Put the logic into core generically to support OpenID / pubCommonId / other provider 2) Create a separate module for the same functionality
thanks for the input. Description updated:
@mkendall07 I think it's worth making the mechanism generic enough to support multiple providers given that's far from clear which id providers publishers will want to use, especially with AppNexus leaving the Advertising ID Consortium
@mike-chowla yes Bret updated the proposal to be generic.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Made an update to move the "url" attribute underneath a "params" object and add a "partner" attribute as well.
Looks like the TradeDesk is going to allow us to use their URL as a default for OpenId - will post that once confirming. Once that happens, params.partner
attribute would be a way to specify their "partner id" rather than the whole URL.
Looks good. It's great that GDPR for publishers will be taken into account. A few questions from pubCommonId perspective.
PubCommonId doesn't reach out to servers to obtain or sync ID's. Rather, the id is generated locally and stored. I guess the logic flow would be something like this: Universal ID module checks storage for id first. If not found then wait till the sync phase and pass the params object to get ID. This means if the ID was missing or expired, then there is a one-cycle delay. Would it be possible to accommodate submodules that do not require syncs?
Would submodule custom parameters be a part of params section?
More on storage. Should pubCommonId still store its own cookie? If not, then could the storage period be extended beyond 30 days?
Ok - I took a cut at integrating all features of PubCommonID into this proposal.
@mkendall07 - this is now complicated enough to warrant a review. Perhaps we can do that in the next PBJS PMC meeting?
Spoke with DigiTrust - added a couple of minor tweaks to support their involvement in this.
Hello. I've recently come on to supporting the DigiTrust id system via IAB Tech Lab. One of our high priorities is integration with Prebid, so to that end I'll be picking everyone's brains on how to do that correctly.
In reading this thread it isn't clear if a consensus was reached. Is the plan to build on pubCommonId module, or to implement the pseudo code for UniversalId outlined in the spec? Forgive me if some questions appear dense. I'm just starting to dig into this code.
@goosemanjack - we're building this new "universal ID" module that has a a simple requirement for supporting each additional ID system must be implementable using a small amount of code, say ~0.25 KB. The framework does most of the work -- the only code that each ID system provides is:
Isaac has provided much of the general code already in the opening comment - it seems likely that we'll release with OpenID and PubCommon, and when you have DigiTrust ready we'll add it. If you have a webservice all ready to go, then you can pile on to this release.
Great. In most cases the DigiTrust ID will be cryptographically generated on the browser client. Some edge cases with Chrome over non-ssl connections require our web service. We may need to talk more about your file size constraints. Use of DigiTrust IDs is restricted to members and we utilize an iframe to make the ID portable across different member publisher sites without the need for sync calls or server hits. The framework also provides some functionality around GDPR compliance and opt-out that we should insure is otherwise covered in Prebid or integrated from DigiTrust into Prebid.
On a more technical note, it appears prebid is using ES6 syntax for modules. We are currently CommonJS/ES5. It is my understanding that we will need to upgrade to ES6 syntax in order to integrate into your build system. If anyone has insight where that wouldn't be the case, please LMK.
Thanks.
this is LGTM from a spec proposal - I'd have some comments on the implementation but let's do that as a formal review process. @bretg Feel free to open the PR.
They renamed OpenId to UnifiedId. Updated.
Note: added a feature to let the gdprConsent object be available to the getId function. We'll update the unifiedId getId function to use it
@pycnvr noted in https://github.com/prebid/prebid.github.io/pull/1068 that the PubCommonID requires an "optout" cookie flag, which is the per-user ability to avoid setting IDs for sites that don't have a GDPR-compliant CMP. Added this item above:
For sites that don't support GDPR, the module should also support a cookie-based opt-out
like the PubCommonID module does. Specifically, if there exists a first party cookie called
"_pbjs_id_optout" (with any value), then this module becomes inactive for this particular
user just like if there was a CMP without Purpose 1 consent.
Draft documentation at https://staging.prebid.org/dev-docs/modules/universalid.html
@bretg https://staging.prebid.org/dev-docs/modules/universalid.html - 404
when building PB with userID from download page - {"error":"Prebid file not built properly","requestId":"d99fd837-0fa9-41b4-8fa6-98386173c118"}
@bretg: Is there a timeline for release of this module?
Actually, it was released on Weds with PBJS 2.10. Documentation at https://prebid.org/dev-docs/modules/userId.html
Currently only two adapters support Unified ID - would love to see others add support.
Overview
UnifiedID is a way of establishing 'universal' user device IDs for web browsers instead of having dozens of exchanges sync IDs with hundreds of demand sources. The basic concept is that the UnifiedID organization stores a set of global IDs at several locations and each publisher using Prebid.js should be able to take advantage of UnifiedID to get better bids from supporting DSPs.
Note that UnifiedID is not a single ID, but potentially a set of IDs. At first just from The TradeDesk, but someday perhaps others.
There are several main steps in the process:
Note that universal user IDs aren't needed in the mobile app world because device ID is available in those ad serving scenarios.
Prebid, Unified ID, and other User IDs
Prebid.org intends to support integration of Unified ID and other 'universal' IDs as a core feature in header bidding products with appropriate publisher-level controls. We will also deprecate the "pubCommonId", folding it's functionality into this more generic module. (The existing module will be left for a few months as there will be page changes to make.)
Prebid support of IDs should include:
gdprConsent
settings for the userThe role of Prebid.js is to:
The role of Prebid Server is to:
Then it's up to each adapter to read the ID values from a standard location and forward it through their pipeline.
Use Cases
Examples of the proposed publisher configuration for various scenarios follows:
1) Publisher supports Unified ID and first party domain cookie storage
2) Publisher supports UnifiedID with HTML5 local storage, synchronously with the first PBJS
3) Publisher has integrated with unifiedID on their own and wants to pass the unifiedID directly through to Prebid.js
4) Publisher supports PubCommonID and first party domain cookie storage
5) Publisher supports both unifiedID and PubCommonID and first party domain cookie storage
6) DigiTrust example
Design Notes
Prebid.js will use the setConfig values configured by the publisher to look for locally stored ID values. If it doesn't find local IDs, it will reach out to the configured URLs, storing any results for the specified number of days as appropriate after checking for GDPR consent.
The prebidServerBidAdapter adds the values to the user.ext.eids section of the OpenRtb2 protocol:
/**
/**
/**
/**
/**
/**
/**
/**
@returns {} / function requestBidHook (config, next) { // Note: calling next() allows Prebid to continue processing an auction, if not called, the auction will be stalled. // pass id data to adapters if bidRequestData list is not empty if (extendedBidRequestData.length) { const data = extendedBidRequestData.reduce(function(aggregate, item) { Object.keys(item).forEach(function(propName) { aggregate[propName] = item[propName] return aggregate }) }, {})
} return next.apply(this, arguments) }
/**
/**
/**
/**
/**
/**
/**
@param {IdSubmodule} submodule */ function getIdComplete (response, data, submodule) { if (response) {
} else { // log error web request for id failed } }
/**
init user id module if config values are set correctly */ function initUserId () { // check if cookie/local storage is active if (!localStorageEnabled()) { // exit if no cookies or local storage return }
// check if any user id types are set in configuration (must opt-in to enable) if (!Array.isArray(config.get('usersync.userIds'))) { // exit if no configurations are set return }
[pubCommonId, unifiedId].forEach(function(submodule) { // try to get config for id submodule const submoduleConfig = config.get('usersync.userIds').find(userIdConfig => userIdConfig.name === submodule.configKey) if (!submoduleConfig) { // log error, config not found for submodule, skip this id submodule return }
})
// add hook only if data is going to be passed at this point, else add hook in getId complete if (extendedBidRequestData.length) { $$PREBID_GLOBAL$$.requestBids.addHook(requestBidHook) } }
// call init initUserId()