Last active
February 28, 2022 19:49
-
-
Save josephrussell-cn/908fdba0c80b7d38f18119cbc5263039 to your computer and use it in GitHub Desktop.
Provides tcfapi interface to iframe window using amp-consent data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// amp-iframe tcfapi proxy | |
// The cne video player inside the iframe on amp does not have access to consent data. | |
// This script is creating a __tcfapi proxy that scripts needing it can call to obtain TCData. | |
// TCData is sourced from a postMessage with type=send-consent-data to sentinel=amp | |
// Should only execute on AMP pages where gdpr is enabled | |
var consentMetadata; | |
var consentString; | |
var gdprApplies; | |
var queue = []; | |
try { | |
// only add the proxy if a __tcfapiLocator frame is present | |
var tcfapiLocatorDetected = false; | |
try { | |
if (window.top.frames['__tcfapiLocator']) { | |
tcfapiLocatorDetected = true; | |
} | |
} catch (error) { | |
tcfapiLocatorDetected = false; | |
} | |
if (tcfapiLocatorDetected) { | |
// create a __tcfapi proxy that can be called by required scripts within the iframe | |
window.__tcfapi = function (cmd, version, callback, parameter) { | |
console.log(cmd); | |
console.log(version); | |
console.log(callback); | |
console.log(parameter); | |
if (!cmd) { | |
return queue; | |
} else if (cmd === 'ping') { | |
if (callback === 'function') { | |
if (consentString) { | |
callback({ | |
gdprApplies: gdprApplies, | |
cmpLoaded: true, | |
cmpStatus: 'loaded' | |
}); | |
} else { | |
callback({ | |
gdprApplies: gdprApplies, | |
cmpLoaded: false, | |
cmpStatus: 'stub' | |
}); | |
} | |
} | |
// https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework/blob/master/TCFv2/IAB%20Tech%20Lab%20-%20CMP%20API%20v2.md#gettcdata | |
} else if (cmd === 'getTCData') { | |
// https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework/blob/master/TCFv2/IAB%20Tech%20Lab%20-%20CMP%20API%20v2.md#tcdata | |
if (typeof callback === 'function') { | |
var tcData = Object.assign({ | |
tcString: consentString | |
}, consentMetadata); | |
callback({ | |
tcData: tcData, | |
success: true | |
}); | |
} | |
} else if (cmd === 'addEventListener') { | |
var listener = {cmd:cmd, version:version, callback:callback, parameter:parameter, id: Math.random() + ''} | |
queue.push(listener); | |
if (consentString && typeof listener.callback === 'function') { | |
var tcData = Object.assign({ | |
tcString: consentString, | |
eventStatus:'tcloaded', | |
listenderId:listener.id, | |
cmpStatus: 'loaded' | |
}, consentMetadata); | |
console.log(tcData); | |
console.log(consentString); | |
listener.callback(tcData, true); | |
} | |
} else if (cmd === 'removeEventListener') { | |
if (parameter) { | |
for (var i=0; i < queue.length; i++) { | |
if (listener.id && listener.id === parameter) { | |
queue.splice(i, 1); | |
if (callback === 'function') { | |
callback(true); // success = true | |
} | |
} | |
} | |
} | |
} | |
} | |
var processQueue = function () { | |
if (consentString) { | |
for (var i=0; i < queue.length; i++) { | |
var listener = queue[i]; | |
if (listener.callback && typeof listener.callback === 'function') { | |
console.log('processQueue ' + listener.id); | |
var tcData = Object.assign({ | |
tcString: consentString, | |
eventStatus:'tcloaded', | |
cmpStatus: 'loaded', | |
listenderId:listener.id | |
}, consentMetadata); | |
listener.callback(tcData, true); | |
} | |
} | |
} | |
} | |
var isAmpMessage = function isAmpMessage(event, type) { | |
return (event.source == window.parent && event.origin != window.location.origin && event.data && event.data.sentinel == 'amp' && event.data.type == type); | |
} | |
var postMessageHandler = function postMessageHandler(event) { | |
// response from amp-consent get-consent-data | |
if (isAmpMessage(event, 'consent-data')) { | |
// save consent data so it can be returned with 'getTCData' | |
gdprApplies = true; | |
consentMetadata = event.data.consentMetadata; | |
consentString = event.data.consentString; | |
console.log(consentMetadata); | |
console.log(consentString); | |
processQueue(); | |
} else { | |
// could be any other postMessage on the window here | |
var msgIsString = typeof event.data === 'string'; | |
var json = {}; | |
if (msgIsString) { | |
try { | |
/** | |
* Try to parse the data from the event. This is important | |
* to have in a try/catch because often messages may come | |
* through that are not JSON | |
*/ | |
json = JSON.parse(event.data); | |
} catch (ignore) { } | |
} else { | |
json = event.data; | |
} | |
var payload = (typeof json === 'object') ? json.__tcfapiCall : null; | |
if (payload) { | |
// this should be a message with __tcfapiCall asking for a response from __tcfapi | |
window.__tcfapi(payload.command, payload.version, function (retValue, success) { | |
var returnMsg = { | |
__tcfapiReturn: { | |
returnValue: retValue, | |
success: success, | |
callId: payload.callId, | |
}, | |
}; | |
if (event && event.source && event.source.postMessage) { | |
event.source.postMessage((msgIsString) ? JSON.stringify(returnMsg) : returnMsg, '*'); | |
} | |
}, payload.parameter); | |
} | |
} | |
} | |
window.addEventListener('message', postMessageHandler, false); | |
// https://github.com/ampproject/amphtml/blob/main/extensions/amp-iframe/0.1/amp-iframe.md#iframe--consent-data | |
window.parent.postMessage({ | |
sentinel: 'amp', | |
type: 'send-consent-data' | |
}, '*'); | |
} | |
} catch (error) { | |
console.log(error) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment