Skip to content

Commit 6567b1a

Browse files
new uid2 client side sample site
1 parent 5d8a596 commit 6567b1a

File tree

6 files changed

+456
-0
lines changed

6 files changed

+456
-0
lines changed
1.93 KB
Loading
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8" />
5+
<title>UID2 Publisher Client-Side Integration Example using UID2 JavaScript SDK, Secure Signals</title>
6+
<link rel="stylesheet" type="text/css" href="./styles/ads.css" />
7+
<link rel="stylesheet" type="text/css" href="./styles/app.css" />
8+
<link rel="shortcut icon" href="images/favicon.png" />
9+
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
10+
<script>
11+
12+
</script>
13+
</head>
14+
<body>
15+
<h1>UID2 Publisher Client-Side Integration Example using UID2 JavaScript SDK, Secure Signals</h1>
16+
<p>
17+
This example demonstrates how a content publisher can follow the
18+
<a href="https://unifiedid.com/docs/guides/integration-javascript-client-side">Client-Side Integration Guide for JavaScript</a> to implement UID2 integration and generate UID2 tokens.
19+
Secure Signals is updated when the page is reloaded.
20+
Reload the page in order to update Secure Signals in local storage.
21+
</p>
22+
<div id="page-content">
23+
<div id="video-container">
24+
<video id="video-element">
25+
<source src="https://storage.googleapis.com/interactive-media-ads/media/android.mp4">
26+
<source src="https://storage.googleapis.com/interactive-media-ads/media/android.webm">
27+
</video>
28+
<div id="ad-container"></div>
29+
</div>
30+
<button id="play-button">Play</button>
31+
</div>
32+
<div class="product-tables">
33+
<table id="uid2_state">
34+
<thead>
35+
<th >UID2 Enabled<input type="checkbox" checked></input></th>
36+
</thead>
37+
<tr>
38+
<td class="label">Ready for Targeted Advertising:</td>
39+
<td class="value"><pre id="targeted_advertising_ready"></pre></td>
40+
</tr>
41+
<tr>
42+
<td class="label">UID2 Advertising Token:</td>
43+
<td class="value"><pre id="advertising_token"></pre></td>
44+
</tr>
45+
<tr>
46+
<td class="label">Is UID2 Login Required?</td>
47+
<td class="value"><pre id="login_required"></pre></td>
48+
</tr>
49+
<tr>
50+
<td class="label">UID2 Identity Callback State:</td>
51+
<td class="value"><pre id="identity_state"></pre></td>
52+
</tr>
53+
<tr>
54+
<td class="label">Secure Signals Loaded?</td>
55+
<td class="value"><pre id="secure_signals_loaded"></pre></td>
56+
</tr>
57+
<tr>
58+
<td class="label">Secure Signals Value:</td>
59+
<td class="value"><pre id="secure_signals_value"></pre></td>
60+
</tr>
61+
</table>
62+
</div>
63+
<div id="login_form" style="display: none" class="form">
64+
<div class="email_prompt">
65+
<input
66+
type="text"
67+
id="email"
68+
name="email"
69+
placeholder="Enter an email address"
70+
style="border-style: none"
71+
72+
/>
73+
</div>
74+
<div><button type="button" class="button" id="login">Log In</button>></div>
75+
</div>
76+
<div id="logout_form" style="display: none" class="form">
77+
<form>
78+
<button type="button" class="button" id="logout">Log Out</button>
79+
</form>
80+
</div>
81+
<script src="https://cdn.integ.uidapi.com/uid2-sdk-3.9.0.js"></script>
82+
<script src="https://cdn.integ.uidapi.com/uid2SecureSignal.js"></script>
83+
<script type="text/javascript" src="scripts/ads.js"></script>
84+
<script type="text/javascript" src="https://imasdk.googleapis.com/js/sdkloader/ima3.js"></script>
85+
<script type="text/javascript" src="scripts/scripts.js"></script>
86+
</body>
87+
</html>
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
var videoElement;
2+
var adsLoaded = false;
3+
var adContainer;
4+
var adDisplayContainer;
5+
var adsLoader;
6+
var adsManager;
7+
8+
window.addEventListener('load', function(event) {
9+
videoElement = document.getElementById('video-element');
10+
initializeIMA();
11+
videoElement.addEventListener('play', function(event) {
12+
loadAds(event);
13+
});
14+
var playButton = document.getElementById('play-button');
15+
playButton.addEventListener('click', function(event) {
16+
videoElement.play();
17+
});
18+
});
19+
20+
window.addEventListener('resize', function(event) {
21+
console.log("window resized");
22+
if(adsManager) {
23+
var width = videoElement.clientWidth;
24+
var height = videoElement.clientHeight;
25+
adsManager.resize(width, height, google.ima.ViewMode.NORMAL);
26+
}
27+
});
28+
29+
function initializeIMA() {
30+
console.log("initializing IMA");
31+
adContainer = document.getElementById('ad-container');
32+
adContainer.addEventListener('click', adContainerClick);
33+
adDisplayContainer = new google.ima.AdDisplayContainer(adContainer, videoElement);
34+
adsLoader = new google.ima.AdsLoader(adDisplayContainer);
35+
adsLoader.addEventListener(
36+
google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,
37+
onAdsManagerLoaded,
38+
false);
39+
adsLoader.addEventListener(
40+
google.ima.AdErrorEvent.Type.AD_ERROR,
41+
onAdError,
42+
false);
43+
44+
// Let the AdsLoader know when the video has ended
45+
videoElement.addEventListener('ended', function() {
46+
adsLoader.contentComplete();
47+
});
48+
49+
var adsRequest = new google.ima.AdsRequest();
50+
adsRequest.adTagUrl = 'https://pubads.g.doubleclick.net/gampad/ads?' +
51+
'iu=/21775744923/external/single_ad_samples&sz=640x480&' +
52+
'cust_params=sample_ct%3Dlinear&ciu_szs=300x250%2C728x90&' +
53+
'gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&impl=s&correlator=';
54+
55+
// Specify the linear and nonlinear slot sizes. This helps the SDK to
56+
// select the correct creative if multiple are returned.
57+
adsRequest.linearAdSlotWidth = videoElement.clientWidth;
58+
adsRequest.linearAdSlotHeight = videoElement.clientHeight;
59+
adsRequest.nonLinearAdSlotWidth = videoElement.clientWidth;
60+
adsRequest.nonLinearAdSlotHeight = videoElement.clientHeight / 3;
61+
62+
// Pass the request to the adsLoader to request ads
63+
adsLoader.requestAds(adsRequest);
64+
}
65+
66+
function loadAds(event) {
67+
// Prevent this function from running on if there are already ads loaded
68+
if(adsLoaded) {
69+
return;
70+
}
71+
adsLoaded = true;
72+
73+
// Prevent triggering immediate playback when ads are loading
74+
event.preventDefault();
75+
76+
console.log("loading ads");
77+
78+
// Initialize the container. Must be done via a user action on mobile devices.
79+
videoElement.load();
80+
adDisplayContainer.initialize();
81+
82+
var width = videoElement.clientWidth;
83+
var height = videoElement.clientHeight;
84+
try {
85+
adsManager.init(width, height, google.ima.ViewMode.NORMAL);
86+
adsManager.start();
87+
} catch (adError) {
88+
// Play the video without ads, if an error occurs
89+
console.log("AdsManager could not be started");
90+
videoElement.play();
91+
}
92+
}
93+
94+
function onAdsManagerLoaded(adsManagerLoadedEvent) {
95+
// Instantiate the AdsManager from the adsLoader response and pass it the video element.
96+
adsManager = adsManagerLoadedEvent.getAdsManager(
97+
videoElement);
98+
adsManager.addEventListener(
99+
google.ima.AdErrorEvent.Type.AD_ERROR,
100+
onAdError);
101+
adsManager.addEventListener(
102+
google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED,
103+
onContentPauseRequested);
104+
adsManager.addEventListener(
105+
google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED,
106+
onContentResumeRequested);
107+
adsManager.addEventListener(
108+
google.ima.AdEvent.Type.LOADED,
109+
onAdLoaded);
110+
}
111+
112+
function onAdError(adErrorEvent) {
113+
// Handle the error logging.
114+
console.log(adErrorEvent.getError());
115+
if(adsManager) {
116+
adsManager.destroy();
117+
}
118+
}
119+
120+
function onContentPauseRequested() {
121+
videoElement.pause();
122+
}
123+
124+
function onContentResumeRequested() {
125+
videoElement.play();
126+
}
127+
128+
function adContainerClick(event) {
129+
console.log("ad container clicked");
130+
if(videoElement.paused) {
131+
videoElement.play();
132+
} else {
133+
videoElement.pause();
134+
}
135+
}
136+
137+
function onAdLoaded(adEvent) {
138+
var ad = adEvent.getAd();
139+
if (!ad.isLinear()) {
140+
videoElement.play();
141+
}
142+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
const clientSideIdentityOptions = {
2+
subscriptionId: 'QRtT141htm',
3+
serverPublicKey:
4+
'UID2-X-I-MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEYla1YQ6N+surF4Yjaax46mPxCv7ixCR0zd3AYV5D8nhEVbQOuhs+GGxp0rUVpucJGQxNvkINwdSeCTpyzLMtFA==',
5+
};
6+
7+
function updateGuiElements(state) {
8+
$('#targeted_advertising_ready').text(__uid2.getAdvertisingToken() ? 'yes' : 'no');
9+
const token = __uid2.getAdvertisingToken();
10+
$('#advertising_token').text(String(token));
11+
$('#login_required').text(
12+
__uid2.isLoginRequired() || __uid2.isLoginRequired() === undefined ? 'yes' : 'no'
13+
);
14+
$('#identity_state').text(String(JSON.stringify(state, null, 2)));
15+
16+
const uid2LoginRequired = __uid2.isLoginRequired();
17+
if (uid2LoginRequired) {
18+
$('#login_form').show();
19+
$('#logout_form').hide();
20+
} else {
21+
$('#login_form').hide();
22+
$('#logout_form').show();
23+
}
24+
25+
const secureSignalsStorage = localStorage['_GESPSK-uidapi.com'];
26+
if (token && !secureSignalsStorage) {
27+
//Token is valid but Secure Signals has not been refreshed. Reload the page.
28+
location.reload();
29+
}
30+
const secureSignalsStorageJson = secureSignalsStorage && JSON.parse(secureSignalsStorage);
31+
if (secureSignalsStorageJson && secureSignalsStorageJson[1]) {
32+
$('#secure_signals_loaded').text('yes');
33+
$('#secure_signals_value').text(JSON.stringify(secureSignalsStorageJson, null, 2));
34+
} else {
35+
$('#secure_signals_loaded').text('no');
36+
$('#secure_signals_value').text('undefined');
37+
}
38+
}
39+
40+
function isEnabled(product) {
41+
return $(`#${product}_state th input`)[0].checked;
42+
}
43+
44+
function onUid2IdentityUpdated(eventType, payload) {
45+
console.log('UID2 Callback', payload);
46+
// allow secure signals time to load
47+
setTimeout(() => updateGuiElements(payload), 1000);
48+
}
49+
50+
function onDocumentReady() {
51+
$('#logout').click(() => {
52+
window.googletag.secureSignalProviders.clearAllCache();
53+
if (isEnabled('uid2')) {
54+
__uid2.disconnect();
55+
}
56+
});
57+
58+
$('#login').click(async () => {
59+
window.googletag.secureSignalProviders.clearAllCache();
60+
const email = $('#email').val();
61+
62+
try {
63+
if (isEnabled('uid2')) {
64+
await __uid2.setIdentityFromEmail(email, clientSideIdentityOptions);
65+
}
66+
} catch (e) {
67+
console.error('setIdentityFromEmail failed', e);
68+
}
69+
});
70+
}
71+
72+
window.__uid2 = window.__uid2 || {};
73+
window.__uid2.callbacks = window.__uid2.callbacks || [];
74+
75+
window.__uid2.callbacks.push(onUid2IdentityUpdated);
76+
window.__uid2.callbacks.push((eventType, payload) => {
77+
if (eventType === 'SdkLoaded') {
78+
window.__uid2.init({
79+
baseUrl: 'https://operator-integ.uidapi.com/',
80+
});
81+
$(document).ready(onDocumentReady);
82+
}
83+
});
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#page-content {
2+
position: relative;
3+
/* this element's width controls the effective height */
4+
/* of the video container's padding-bottom */
5+
max-width: 640px;
6+
margin: 10px 0;
7+
}
8+
9+
#video-container {
10+
position: relative;
11+
/* forces the container to match a 16x9 aspect ratio */
12+
/* replace with 75% for a 4:3 aspect ratio, if needed */
13+
padding-bottom: 56.25%;
14+
}
15+
16+
#video-element {
17+
/* forces the contents to fill the container */
18+
position: absolute;
19+
top: 0;
20+
left: 0;
21+
width: 100%;
22+
height: 100%;
23+
}
24+
25+
#ad-container {
26+
position: absolute;
27+
top: 0;
28+
left: 0;
29+
width: 100%;
30+
height: 100%;
31+
}

0 commit comments

Comments
 (0)