InteractiveAdvertisingBureau / Global-Privacy-Platform

IAB Tech Lab Global Privacy Platform specification
72 stars 36 forks source link

Updated spec to reflect the changes for GPP API v1.1 and for IAB EU TCF v2.2 #70

Closed HeinzBaumann closed 1 year ago

HeinzBaumann commented 1 year ago

Open for public comment until May 26th, 2023 Changes in this PR to support GPP API v1.1

Changes in PR to support TCF 2.2:

janwinkler commented 1 year ago

While implementing the changes into our code, we found that the event order is not explizit enough, especially when vendors will start relying on "signalStatus" event. I'd therefore suggest to add some clarification to addEventListerner or another place.

Suggested text (please check & correct my english):

Event order A CMP must send all approriate events and it must send them in a specific order so that listeners (e.g. vendors) can understand when a task has ended. Whenever the CMP starts to change or is about to change any of the existing sections or whenever the CMP is processing user input for an existing GPP string, it must always first set "signalStatus" to "not ready" and fire the corresponding event. It can then then perform the tasks (e.g. change the sections along with fireing the section change events). Only when all tasks are completed for the moment, the CMP can set the "signalStatus" to "ready" and fire the corresponding event. In other words: The event "signalStatus" shall always be the first (if applicable) and last in a chain of events being fired by the CMP.

Example 1: The following example illustrates the events that being fired assuming support for IAB TCF Canada for a new visitor:

  1. (initial data of PingReturn is {gppVersion:1.1, cmpStatus: loading, cmpDisplayStatus: hidden, signalStatus: not ready, ... }
  2. listenerRegistered - CMP has registered the event listener, Event is immediatly fired after registering.
  3. cmpStatus - CMP is now loaded. Event is fired with name=cmpStatus and data=loaded
  4. cmpDisplayStatus - CMP now displays the consent layer. Event is fired with name=cmpDisplayStatus and data=visible
  5. (Visitor makes their choices and clicks on accept or reject or save)
  6. cmpDisplayStatus - CMP closed the consent layer and processes user input. Event is fired with name=cmpDisplayStatus and data=hidden
  7. sectionChange - CMP changes the section based on user input. Event is fired with name=sectionChange and data=tcfcav1
  8. (Note: If multiple sections are present, multiple sectionChange events may occur after another)
  9. signalStatus - CMP is done with the processing, vendors can use the data. Event is fired with name=signalStatus and data=ready

Example 2: The following example illustrates the events that being fired assuming support for IAB TCF Canada for a returning visitor with a preexisting choice:

  1. (initial data of PingReturn is {gppVersion:1.1, cmpStatus: loading, cmpDisplayStatus: hidden, signalStatus: not ready, ... }
  2. listenerRegistered - CMP has registered the event listener, Event is immediatly fired after registering.
  3. cmpStatus - CMP is now loaded. Event is fired with name=cmpStatus and data=loaded
  4. signalStatus - CMP is done with the processing (consent information is loaded, no further processing needed, consent layer will not be shown), vendors can use the data. Event is fired with name=signalStatus and data=ready
  5. (User clicks on a link or button to re-surface the consent layer in order to change their choice
  6. signalStatus - CMP is expecting changes, vendors should not use the data but wait and pausetheir processing. Event is fired with name=signalStatus and data=not ready
  7. cmpDisplayStatus - CMP now displays the consent layer. Event is fired with name=cmpDisplayStatus and data=visible
  8. (Visitor makes their choices and clicks on accept or reject or save)
  9. cmpDisplayStatus - CMP closed the consent layer and processes user input. Event is fired with name=cmpDisplayStatus and data=hidden
  10. sectionChange - CMP changes the section based on user input. Event is fired with name=sectionChange and data=tcfcav1
  11. (Note: If multiple sections are present, multiple sectionChange events may occur after another)
  12. signalStatus - CMP is done with the processing, vendors can use the data. Event is fired with name=signalStatus and data=ready
janwinkler commented 1 year ago
  1. Clarification on addEventListerner data property for signalStatus missing: Please add "The data property will contain the new signalStatus value." to the table under EventListener Object.

  2. The second example at "Using the CMP API" is still using return values instead of callbacks. updated example code:

if(gpp) { gpp('addEventListener', function (evt) { //callback will receive all events, we only want to react on signalStatus ready events if(evt.eventName !== 'signalStatus' || evt.data !== 'ready'){return ;}

//if only the TCString is needed, it get be taken directly from pingData.gppString var gppString = evt.pingData.gppString;

//get the data from the TCF Canada section __gpp('getSection',function(data, success)){ if(data === null){return ;}

var vendorConsent = data[0].VendorExpressConsent; var vendorImpConsent = data[0].VendorImpliedConsent; var purposeConsent = data[0].PurposesExpressConsent; // ... do something Canadian ! } }, 'tcfcav1'); }

  1. note that the above example does not work with TCF EU in the same way since we cant use getSection there. suggestion: Add "parsedSections" object to pingReturn. Description: The parsedSections property represents an object of all parsed sections of the gppString property that are supported by the API on this page (see supportedAPIs property). The object contains one property for each supported API with the name of the API as the property name and the value as a parsed representation of this section (similar to getSection command). If a section is supported but not represented in the gppString, it is omitted in the parsedSections object. Example: ... parsedSections: {tcfcav1: [{Version; 1 ...}, {...} ], tcfeuv2: [{Version: 2, ...}, {...} ], ... }, ...
patmmccann commented 1 year ago

as noted in the meeting, would be very helpful to see @janwinkler 's excellent parsedSections suggestion return parsedSections: {tcfcav1: [{SID : 5}, {Version; 1 ...}, {...} ], or something of that nature [ eg applicableAPIs], so maintaining sid to api maps will not be necessary for every api consumer.

dgirardi commented 1 year ago

While I like the parsedSections suggestion, I don't think it solves the problem of mapping from prefix to SID. It spares the necessity of calling getSection in a loop.

The other, hidden suggestion in @patmmccann comment would solve the mapping problem: include the SID in each section. Perhaps getSection could return something like this:

{
   sid: 7,
   api: "usnat",
   subSections: [
     /* Core Sub-section */
     {
      Version:1, 
      Created: Date (Thu Apr 13 2023 18:07:12 GMT+0200),
      LastUpdated: Date (Thu Apr 13 2023 18:07:12 GMT+0200),
      CmpId: 31, 
      CmpVersion: 123,
      ConsentScreen: 5,
      ...
      }, 
      /* Publisher Purposes Sub-section (optional) */
     {
      subsectionType:3, 
      PubPurposesExpressConsent : [1,2,3,4,5],
      PubPurposesImpliedConsent  : [6,7,8,9],
      ...
      } 
 ]
}
janwinkler commented 1 year ago

@dgirardi @patmmccann although im not against adding the section IDs, Im still not sure I understand the issue with the mapping: If I as a vendor decide to support lets say US Nat., then I will anyway need to build a lot of custom logic (e.g. which fields to use and how). Adding a mapping "7=usnat" in my code doesnt seem too complicated ;-) And all other APIs/section IDs that are not mapped, i can simply ignore them (because my code wouldnt anyway know what to do with the data).

patmmccann commented 1 year ago

Adding a mapping "7=usnat" in my code doesnt seem too complicated ;-)

It isn't; the issue is maintaining the mapping. And as we see in #73 ; not even existing mappings can be considered stable. Publishers often take years to upgrade header bidding libraries. Prebid understanding a new mapping shouldn't require a software library upgrade. The cmp should present the mappings to its consumers.

janwinkler commented 1 year ago

@patmmccann But thats what i mean: once the mapping is created, it should never change (the recent changes i see more as a bug in the spec an not a real change). hence the only situation when you would need to update your mapping, is when you anyway work on your code to support a new legislation or new tcf version or something. anyhow, lets cut the conversation here and add the sid to the section and make us all happy ;-)

patmmccann commented 1 year ago

Great work!