Skip to content

Add GDPR/consent support to amp-slikeplayer#40500

Merged
powerivq merged 2 commits intoampproject:mainfrom
SlikeTech:feat/amp-slikeplayer-consent-support
Apr 15, 2026
Merged

Add GDPR/consent support to amp-slikeplayer#40500
powerivq merged 2 commits intoampproject:mainfrom
SlikeTech:feat/amp-slikeplayer-consent-support

Conversation

@SlikeTech
Copy link
Copy Markdown
Contributor

@SlikeTech SlikeTech commented Mar 27, 2026

Summary

  • Integrate AMP consent framework into amp-slikeplayer so the embedded Slike player iframe can request and receive consent data via postMessage
  • Player always loads regardless of consent state — cleo-player handles personalisation and analytics decisions internally based on the consent response
  • Add amp-consent and amp-geo to the example page with a consent banner UI
  • Add unit tests for consent data forwarding

Changes

  • extensions/amp-slikeplayer/0.1/amp-slikeplayer.js: Import getConsentDataToForward, listen for send-consent-data messages from iframe, respond with AMP consent state (consentPolicyState, consentString, consentMetadata, consentPolicySharedData)
  • examples/slikeplayer.amp.html: Add amp-consent + amp-geo scripts, consent prompt UI, and geo-based EEA country groups
  • extensions/amp-slikeplayer/0.1/test/test-amp-slikeplayer.js: Add tests for consent message handling and edge cases

How it works

  1. Slike player iframe sends { type: 'send-consent-data', sentinel: 'amp' } to parent
  2. amp-slikeplayer receives this, queries AMP's consent service
  3. Responds with { sentinel: 'amp', type: 'consent-data', consentPolicyState, ... }
  4. Cleo-player resolves consent and adjusts personalisation/analytics accordingly

SlikeTech and others added 2 commits March 27, 2026 15:48
Integrate AMP consent framework so the Slike player iframe can request
and receive consent data via postMessage, enabling cleo-player to handle
personalisation and analytics decisions based on user consent state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds GDPR/consent-message support to amp-slikeplayer so the embedded Slike player iframe can request AMP consent data and receive it via postMessage, plus updates the example page and extends unit tests.

Changes:

  • Add a send-consent-data message handler in amp-slikeplayer and reply with AMP consent state via getConsentDataToForward.
  • Update the Slikeplayer example page to include amp-consent UI and amp-geo configuration.
  • Add unit tests covering consent request handling paths.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
extensions/amp-slikeplayer/0.1/amp-slikeplayer.js Adds consent request handling and posts consent data back to the iframe.
extensions/amp-slikeplayer/0.1/test/test-amp-slikeplayer.js Adds tests for consent request message handling and an iframe-lifecycle edge case.
examples/slikeplayer.amp.html Demonstrates consent UI and geo grouping for the example page.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +355 to +368
sendConsentData_() {
getConsentDataToForward(this.element, this.getConsentPolicy()).then(
(consents) => {
if (!this.iframe_ || !this.iframe_.contentWindow) {
return;
}
this.iframe_.contentWindow./*OK*/ postMessage(
{
'sentinel': 'amp',
'type': 'consent-data',
...consents,
},
this.targetOrigin_
);
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

sendConsentData_() uses this.targetOrigin_ as the postMessage targetOrigin, but targetOrigin_ is never defined anywhere in this class. This will result in the message being sent with an invalid/incorrect targetOrigin (often preventing delivery). Capture the request's origin from the triggering message event and use that as targetOrigin (or otherwise compute/store a validated origin when creating the iframe) instead of referencing an undefined field.

Copilot uses AI. Check for mistakes.
Comment on lines +217 to +243
it('calls sendConsentData_ on send-consent-data message', async () => {
const consentData = {
consentPolicyState: 1,
consentString: 'abc123',
consentMetadata: {gdprApplies: true, purposeOne: true},
consentPolicySharedData: null,
};
env.sandbox
.stub(consent, 'getConsentDataToForward')
.resolves(consentData);

const {iframe, impl} = await buildPlayer();
const sendSpy = env.sandbox.spy(impl, 'sendConsentData_');

// Simulate consent request from iframe (raw object, not JSON)
impl.onMessage_({
source: iframe.contentWindow,
data: {type: 'send-consent-data', sentinel: 'amp'},
});

expect(sendSpy).to.have.been.calledOnce;

// Wait for the consent promise to resolve
await new Promise((r) => setTimeout(r, 0));

expect(consent.getConsentDataToForward).to.have.been.calledOnce;
});
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

This test only verifies that sendConsentData_ was invoked and that getConsentDataToForward was called, but it never asserts that consent data is actually forwarded to the iframe (e.g., that postMessage is called with {sentinel:'amp', type:'consent-data', ...} and the expected consent fields). Add an assertion around the postMessage call/payload so regressions in the response format or posting behavior are caught.

Copilot uses AI. Check for mistakes.
Comment on lines +247 to +261
env.sandbox
.stub(consent, 'getConsentDataToForward')
.resolves(consentData);

const {iframe, impl} = await buildPlayer();

// Destroy iframe before consent resolves
impl.iframe_ = null;

impl.onMessage_({
source: iframe.contentWindow,
data: {type: 'send-consent-data', sentinel: 'amp'},
});

await new Promise((r) => setTimeout(r, 0));
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

The test name/comment says the iframe is destroyed before the consent promise resolves, but impl.iframe_ is set to null before onMessage_ is called. That means onMessage_ returns early and the async path in sendConsentData_ (the guard that checks this.iframe_ after consent data resolves) is never exercised. To cover the intended edge case, trigger the request first and then null out impl.iframe_ while the consent promise is still pending (e.g., with a manually controlled promise).

Suggested change
env.sandbox
.stub(consent, 'getConsentDataToForward')
.resolves(consentData);
const {iframe, impl} = await buildPlayer();
// Destroy iframe before consent resolves
impl.iframe_ = null;
impl.onMessage_({
source: iframe.contentWindow,
data: {type: 'send-consent-data', sentinel: 'amp'},
});
await new Promise((r) => setTimeout(r, 0));
let resolveConsentData;
const consentDataPromise = new Promise((resolve) => {
resolveConsentData = resolve;
});
env.sandbox
.stub(consent, 'getConsentDataToForward')
.returns(consentDataPromise);
const {iframe, impl} = await buildPlayer();
impl.onMessage_({
source: iframe.contentWindow,
data: {type: 'send-consent-data', sentinel: 'amp'},
});
// Destroy iframe while consent is still pending so the async guard
// inside sendConsentData_() is exercised after the promise resolves.
impl.iframe_ = null;
resolveConsentData(consentData);
await Promise.resolve();

Copilot uses AI. Check for mistakes.
Comment on lines +341 to +363
<!-- Geo detection for consent -->
<amp-geo layout="nodisplay">
<script type="application/json">
{
"ISOCountryGroups": {
"eea": ["at", "be", "bg", "hr", "cy", "cz", "dk", "ee", "fi", "fr",
"de", "gr", "hu", "ie", "it", "lv", "lt", "lu", "mt", "nl",
"pl", "pt", "ro", "sk", "si", "es", "se", "gb", "is", "li",
"no", "ch"]
}
}
</script>
</amp-geo>

<!-- Consent management -->
<amp-consent id="slike-consent" layout="nodisplay">
<script type="application/json">
{
"consentInstanceId": "slike-player-consent",
"consentRequired": true,
"promptUI": "consent-prompt",
"postPromptUI": "post-consent-prompt"
}
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

amp-geo is configured with an eea group, but the amp-consent config doesn't reference any geo group (e.g., via promptIfUnknownForGeoGroup / consentRequired gating), so geo detection has no effect and the consent UI will always be required. Either wire amp-consent to the eea group as described in the PR summary, or remove the unused amp-geo configuration from the example.

Copilot uses AI. Check for mistakes.
@powerivq powerivq merged commit 4eeab9b into ampproject:main Apr 15, 2026
60 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants