Skip to content

Commit 65aa96b

Browse files
authored
Update Prebid.js support (#37)
- Update prebidUserDataFromCache API to return an object that can be directly sent to pbjs.setConfig(ortb2.user.data) by the caller. The returned user.data object now references Optable's requested segtax (seller defined audience/segment taxonomy) corresponding to "Optable Private Audiences" which is segtax=5001 as per our pending PR: InteractiveAdvertisingBureau/openrtb#81 - Document prebidUserDataFromCache in README - Add a link to the prebid demo page from demos/index - Delete old prebid-us-east-16 demo pages - Silence webpack5 warnings when building lib/core/network.ts - Complete replacing "sandbox" with "DCN" or "dcn" in demo pages and SDK codebase, but continue to support optable.instance.sandbox for backward compatibility - Update broken privacy policy link in footer of demos/index pages - Provide link to demos/index-nocookies.html as alternative integration example - More succinct naming and labels and clarify documentation on Prebid.js integration in demos
1 parent 636f86b commit 65aa96b

40 files changed

+365
-1360
lines changed

Dockerfile

+1-4
Original file line numberDiff line numberDiff line change
@@ -46,23 +46,20 @@ WORKDIR /usr/share/nginx/html/
4646
COPY --from=build /build/demos/vanilla/targeting/gam360.html ./vanilla/targeting/gam360.html
4747
COPY --from=build /build/demos/vanilla/targeting/gam360-cached.html ./vanilla/targeting/gam360-cached.html
4848
COPY --from=build /build/demos/vanilla/targeting/prebid.html ./vanilla/targeting/prebid.html
49-
COPY --from=build /build/demos/vanilla/targeting/prebid-us-east-16.html ./vanilla/targeting/prebid-us-east-16.html
5049
COPY --from=build /build/demos/vanilla/targeting/prebid.js ./vanilla/targeting/prebid.js
51-
COPY --from=build /build/demos/vanilla/targeting/prebid-us-east-16.js ./vanilla/targeting/prebid-us-east-16.js
5250
COPY --from=build /build/demos/vanilla/identify.html ./vanilla/identify.html
5351
COPY --from=build /build/demos/vanilla/profile.html ./vanilla/profile.html
5452
COPY --from=build /build/demos/vanilla/witness.html ./vanilla/witness.html
5553
COPY --from=build /build/demos/vanilla/nocookies/targeting/gam360.html ./vanilla/nocookies/targeting/gam360.html
5654
COPY --from=build /build/demos/vanilla/nocookies/targeting/gam360-cached.html ./vanilla/nocookies/targeting/gam360-cached.html
5755
COPY --from=build /build/demos/vanilla/nocookies/targeting/prebid.html ./vanilla/nocookies/targeting/prebid.html
58-
COPY --from=build /build/demos/vanilla/nocookies/targeting/prebid-us-east-16.html ./vanilla/nocookies/targeting/prebid-us-east-16.html
5956
COPY --from=build /build/demos/vanilla/nocookies/targeting/prebid.js ./vanilla/nocookies/targeting/prebid.js
60-
COPY --from=build /build/demos/vanilla/nocookies/targeting/prebid-us-east-16.js ./vanilla/nocookies/targeting/prebid-us-east-16.js
6157
COPY --from=build /build/demos/vanilla/nocookies/identify.html ./vanilla/nocookies/identify.html
6258
COPY --from=build /build/demos/vanilla/nocookies/profile.html ./vanilla/nocookies/profile.html
6359
COPY --from=build /build/demos/vanilla/nocookies/witness.html ./vanilla/nocookies/witness.html
6460
COPY --from=build /build/demos/react/dist/ ./react/dist/
6561
COPY --from=build /build/demos/index.html ./index.html
62+
COPY --from=build /build/demos/index-nocookies.html ./index-nocookies.html
6663
COPY --from=build /build/demos/css/ ./css/
6764
COPY --from=build /build/demos/images/ ./images/
6865

README.md

+160
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ JavaScript SDK for integrating with an [Optable Data Connectivity Node (DCN)](ht
2020
- [Targeting key values](#targeting-key-values)
2121
- [Targeting key values from local cache](#targeting-key-values-from-local-cache)
2222
- [Witnessing ad events](#witnessing-ad-events)
23+
- [Integrating Prebid](#integrating-prebid)
24+
- [Seller Defined Audiences](#seller-defined-audiences)
25+
- [Custom key values](#custom-key-values)
2326
- [Identifying visitors arriving from Email newsletters](#identifying-visitors-arriving-from-email-newsletters)
2427
- [Insert oeid into your Email newsletter template](#insert-oeid-into-your-email-newsletter-template)
2528
- [Call tryIdentifyFromParams SDK API](#call-tryidentifyfromparams-sdk-api)
@@ -425,6 +428,161 @@ Note that you can call `installGPTEventListeners()` as many times as you like on
425428

426429
A working example of both targeting and event witnessing is available in the demo pages.
427430

431+
## Integrating Prebid
432+
433+
The Optable Web SDK can fetch targeting data from a DCN and prepare an audience taxonomy object similar to the one described in [the prebid.js first party data documentation](https://docs.prebid.org/features/firstPartyData.html#segments-and-taxonomy). The `prebidUserDataFromCache()` function returns the object from the targeting data stored by `targeting()` API calls in `LocalStorage`.
434+
435+
### Seller Defined Audiences
436+
437+
The HTML code snippet below shows how `prebidUserDataFromCache()` can be used to retrieve targeting data from the `LocalStorage` administered by the Optable SDK, and write Seller Defined Audiences (SDA) into [prebid.js](https://prebid.org/product-suite/prebid-js/) which is also loaded into the page, using `pbjs.setConfig({ ortb2: { user: { data: [ { ... } ] } } })` as documented in [the prebid.js first party data documentation](https://docs.prebid.org/features/firstPartyData.html#segments-and-taxonomy). The `targeting()` API is also called in order to retrieve and locally store the latest matching activations from `dcn.customer.com/my-site`.
438+
439+
Note that [prebid.js bidder adapters](https://docs.prebid.org/dev-docs/bidders.html) can subsequently retrieve the data from the [global config](https://docs.prebid.org/features/firstPartyData.html#supplying-global-data).
440+
441+
An example of how to install the SDA data through `pbjs` is shown below. The `districtMDMX` bidder adapter is referenced, though the integration would look similar with any SDA compatible bidder adapters.
442+
443+
For a working demo showing a `pbjs` and GAM integrated together, see the [demo pages section](#demo-pages) below.
444+
445+
```html
446+
<!-- Optable SDK async load: -->
447+
<script async src="https://cdn.optable.co/web-sdk/v0/sdk.js"></script>
448+
449+
<!-- Prebid.js lib async load: -->
450+
<script async src="prebid.js"></script>
451+
452+
<!-- Initialize Optable SDK, and targeting call early when possible: -->
453+
<script>
454+
window.optable = window.optable || { cmd: [] };
455+
456+
// Init Optable SDK via command:
457+
optable.cmd.push(function () {
458+
optable.instance = new optable.SDK({ host: "dcn.customer.com", site: "my-site" });
459+
});
460+
461+
// Call Optable DCN for targeting data which will update the local cache on success.
462+
optable.cmd.push(function () {
463+
optable.instance.targeting().catch((err) => {
464+
// Maybe log error
465+
});
466+
});
467+
</script>
468+
469+
<!-- Placeholder DIV for adSlot -->
470+
<div id="div-gpt-ad-12345-0"></div>
471+
472+
<!-- Initialize prebid.js -->
473+
<script>
474+
window.pbjs = window.pbjs || { que: [] };
475+
476+
var PREBID_TIMEOUT = 3000;
477+
var FAILSAFE_TIMEOUT = 5000;
478+
479+
var adUnits = [
480+
{
481+
code: "/22081946781/web-sdk-demo/box-ad",
482+
mediaTypes: {
483+
banner: {
484+
sizes: [
485+
[250, 250],
486+
[300, 250],
487+
[200, 200],
488+
],
489+
},
490+
},
491+
bids: [
492+
{
493+
bidder: "districtmDMX",
494+
params: {
495+
dmxid: "/22081946781/web-sdk-demo/box-ad",
496+
memberid: "102034",
497+
},
498+
},
499+
],
500+
},
501+
];
502+
503+
function initAdserver() {
504+
if (pbjs.initAdserverSet) return;
505+
pbjs.initAdserverSet = true;
506+
// ... etc ...
507+
}
508+
509+
pbjs.que.push(function () {
510+
optable.cmd.push(function () {
511+
const pbdata = optable.instance.prebidUserDataFromCache();
512+
if (pbdata.length > 0) {
513+
pbjs.setConfig({
514+
ortb2: {
515+
user: {
516+
data: pbdata,
517+
},
518+
},
519+
});
520+
}
521+
522+
// ... etc ...
523+
524+
pbjs.requestBids({
525+
bidsBackHandler: initAdserver,
526+
timeout: PREBID_TIMEOUT,
527+
});
528+
});
529+
});
530+
531+
setTimeout(function () {
532+
initAdserver();
533+
}, FAILSAFE_TIMEOUT);
534+
</script>
535+
```
536+
537+
### Custom key values
538+
539+
For bidder adapters that do not support SDA, but that do support targeting private marketplace deals to key values, you can use a samilar approach to the [Google Ad Manager integration with key values from local cache](#targeting-key-values-from-local-cache). For example, for the IX bidder adapter and [IX bidder-specific FPD](https://docs.prebid.org/dev-docs/bidders/ix.html#ix-bidder-specific-fpd), you can encode the targeting key values as shown below:
540+
541+
```html
542+
<script>
543+
// ...
544+
// prior to pbjs.requestBids():
545+
pbjs.que.push(function () {
546+
optable.cmd.push(function () {
547+
const tdata = optable.instance.targetingFromCache();
548+
var fpd = {};
549+
550+
/*
551+
* Flatten targeting key=values from Optable SDK targeting cache
552+
* into a custom key value object, such that a key K with values
553+
* V1, V2, ... in the Optable SDK targeting cache is transformed
554+
* to look like:
555+
* {
556+
* K + V1: 1,
557+
* K + V2: 1,
558+
* ...
559+
* }
560+
*
561+
* Note that + above indicates string concatenation.
562+
*
563+
* Optable DCNs have K configured to "optable" by default, so the
564+
* above would result in a custom key value "optable_audienceKeyword=1"
565+
* being set whenever the visitor is matched to the activated audience
566+
* specified by audienceKeyword by the DCN.
567+
*/
568+
for (const [key, values] of Object.entries(tdata || {})) {
569+
for (const seg of values) {
570+
fpd[key + seg] = "1";
571+
}
572+
}
573+
574+
pbjs.setConfig({
575+
ix: {
576+
firstPartyData: fpd,
577+
},
578+
});
579+
});
580+
581+
pbjs.requestBids(...);
582+
});
583+
</script>
584+
```
585+
428586
## Identifying visitors arriving from Email newsletters
429587

430588
If you send Email newsletters that contain links to your website, then you may want to automatically _identify_ visitors that have clicked on any such links via their Email address.
@@ -460,3 +618,5 @@ On your website destination page, you can call a helper method provided by the S
460618
The demo pages are working examples of both `identify` and `targeting` APIs, as well as an integration with the [Google Ad Manager 360](https://admanager.google.com/home/) ad server, enabling the targeting of ads served by GAM360 to audiences activated in the [Optable](https://optable.co/) DCN.
461619

462620
You can browse a recent (but not necessarily the latest) released version of the demo pages at [https://demo.optable.co/](https://demo.optable.co/). The source code to the demos can be found [here](https://github.com/Optable/optable-web-sdk/tree/master/demos). The demo pages will connect to the [Optable](https://optable.co/) demo DCN at `sandbox.optable.co` and reference the web site slug `web-sdk-demo`. The GAM360 targeting demo loads ads from a GAM360 account operated by [Optable](https://optable.co/).
621+
622+
Note that the demo pages at [https://demo.optable.co/](https://demo.optable.co/) will by default rely on secure HTTP first-party cookies as described [here](https://github.com/Optable/optable-web-sdk#domains-and-cookies). To see an example based on [LocalStorage](https://github.com/Optable/optable-web-sdk#localstorage), see the [index-nocookies variant here](https://demo.optable.co/index-nocookies.html).

demos/Makefile

+1-3
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,12 @@ html:
1111
envsubst < ./vanilla/targeting/gam360.html.tpl > ./vanilla/targeting/gam360.html && \
1212
envsubst < ./vanilla/targeting/gam360-cached.html.tpl > ./vanilla/targeting/gam360-cached.html && \
1313
envsubst < ./vanilla/targeting/prebid.html.tpl > ./vanilla/targeting/prebid.html && \
14-
envsubst < ./vanilla/targeting/prebid-us-east-16.html.tpl > ./vanilla/targeting/prebid-us-east-16.html && \
1514
envsubst < ./vanilla/nocookies/identify.html.tpl > ./vanilla/nocookies/identify.html && \
1615
envsubst < ./vanilla/nocookies/witness.html.tpl > ./vanilla/nocookies/witness.html && \
1716
envsubst < ./vanilla/nocookies/profile.html.tpl > ./vanilla/nocookies/profile.html && \
1817
envsubst < ./vanilla/nocookies/targeting/gam360.html.tpl > ./vanilla/nocookies/targeting/gam360.html && \
1918
envsubst < ./vanilla/nocookies/targeting/gam360-cached.html.tpl > ./vanilla/nocookies/targeting/gam360-cached.html && \
20-
envsubst < ./vanilla/nocookies/targeting/prebid.html.tpl > ./vanilla/nocookies/targeting/prebid.html && \
21-
envsubst < ./vanilla/nocookies/targeting/prebid-us-east-16.html.tpl > ./vanilla/nocookies/targeting/prebid-us-east-16.html
19+
envsubst < ./vanilla/nocookies/targeting/prebid.html.tpl > ./vanilla/nocookies/targeting/prebid.html
2220

2321
.PHONY: react
2422
react:

demos/index-nocookies.html

+27-16
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
</div>
2222
<div class="row">
2323
<div class="twelve column">
24-
<h4>👋 demo.optable.co (cookies=false)</h4>
24+
<h4>👋 demo.optable.co (LocalStorage)</h4>
2525
<p>
2626
To learn about optable-web-sdk integration on your web site or application, see the latest releases, or
2727
report an issue, please check out the
@@ -34,14 +34,14 @@ <h4>👋 demo.optable.co (cookies=false)</h4>
3434
</p>
3535
<p>
3636
<strong
37-
>Note that the examples below initialize the OptableSDK with cookies=false, so all ID transport is done
37+
>Note that the examples below initialize the OptableSDK with cookies=false, so all ID storage is done
3838
using browser LocalStorage.</strong
3939
>
4040
Generally, it is preferable to use secure first party HTTP-only cookies for transporting IDs from
4141
OptableSDK. However, when the integrating website does not share the same top-level domain name with the
42-
Optable Sandbox, then first party cookies are not reliable, and the LocalStorage method is suggested. To
43-
enable it, simply initialize the OptableSDK object with the <code>cookies</code> option set to
44-
<code>false</code>, and the SDK will do the rest.
42+
Optable DCN, then first party cookies are not reliable, and the LocalStorage method is suggested. To enable
43+
it, simply initialize the OptableSDK object with the <code>cookies</code> option set to <code>false</code>,
44+
and the SDK will do the rest.
4545
</p>
4646
</div>
4747
</div>
@@ -51,28 +51,28 @@ <h5>Examples</h5>
5151
<table class="u-full-width">
5252
<thead>
5353
<tr>
54-
<th>Link</th>
54+
<th>API</th>
5555
<th>Description</th>
5656
</tr>
5757
</thead>
5858
<tbody>
5959
<tr>
60-
<td><a href="/vanilla/nocookies/identify.html">identify API</a></td>
60+
<td><a href="/vanilla/nocookies/identify.html">identify</a></td>
6161
<td>
6262
Simple <code>script</code> tag integration showing how to send a hashed Email address and optional
63-
publisher user ID to your sandbox.
63+
publisher user ID to your DCN.
6464
</td>
6565
</tr>
6666
<tr>
67-
<td><a href="/vanilla/nocookies/witness.html">witness API</a></td>
68-
<td>Shows how to log events with optional properties to your sandbox.</td>
67+
<td><a href="/vanilla/nocookies/witness.html">witness</a></td>
68+
<td>Shows how to log events with optional properties to your DCN.</td>
6969
</tr>
7070
<tr>
71-
<td><a href="/vanilla/nocookies/profile.html">profile API</a></td>
72-
<td>Shows how to set visitor traits (e.g., <code>age=45</code>) and sync them to your sandbox.</td>
71+
<td><a href="/vanilla/nocookies/profile.html">profile</a></td>
72+
<td>Shows how to set visitor traits (e.g., <code>age=45</code>) and sync them to your DCN.</td>
7373
</tr>
7474
<tr>
75-
<td><a href="/vanilla/nocookies/targeting/gam360.html">targeting &amp; GAM360 activation</a></td>
75+
<td><a href="/vanilla/nocookies/targeting/gam360.html">targeting: GAM360</a></td>
7676
<td>
7777
Shows how to load active cohorts for a visitor and pass them to
7878
<a href="https://admanager.google.com/home/">Google Ad Manager</a> (GAM) via the
@@ -82,7 +82,7 @@ <h5>Examples</h5>
8282
</tr>
8383
<tr>
8484
<td>
85-
<a href="/vanilla/nocookies/targeting/gam360-cached.html">cached targeting &amp; GAM360 activation</a>
85+
<a href="/vanilla/nocookies/targeting/gam360-cached.html">targeting: GAM360 (cached data)</a>
8686
</td>
8787
<td>
8888
Shows how to load and cache active cohorts in a visitor's browser. Separately, cached cohorts are
@@ -91,15 +91,26 @@ <h5>Examples</h5>
9191
ad targeting.
9292
</td>
9393
</tr>
94+
<tr>
95+
<td><a href="/vanilla/nocookies/targeting/prebid.html">targeting: Prebid.js</a></td>
96+
<td>
97+
Shows how to load and cache active cohorts in a visitor's browser. Separately, cached cohorts are
98+
passed to <a href="https://prebid.org/">Prebid.js</a> bidder adapters via the
99+
<a href="https://docs.prebid.org/features/firstPartyData.html#segments-and-taxonomy"
100+
>first-party data segments and taxonomy mechanism</a
101+
>.
102+
</td>
103+
</tr>
94104
</tbody>
95105
</table>
96106
</div>
97107
</div>
98108
<div class="row">
99-
<div class="twelve column" style="font-size: 0.8rem; padding: 10px;">
109+
<div class="twelve column" style="padding: 10px;">
100110
<center>
101111
<a href="https://www.optable.co/">Home</a> | <a href="https://www.optable.co/company/contact">Contact</a> |
102-
<a href="https://optable.co/privacy">Privacy</a> |
112+
<a href="https://docs.optable.co/">Documentation</a> |
113+
<a href="https://www.optable.co/privacy/products-and-services-privacy-policy">Privacy</a> |
103114
<a href="https://www.linkedin.com/company/optableco/">LinkedIn</a> |
104115
<a href="https://twitter.com/optable_co">Twitter</a>
105116
</center>

0 commit comments

Comments
 (0)