Skip to content

Commit

Permalink
Move to proposed edge targeting v2 response format (#42)
Browse files Browse the repository at this point in the history
* Move to targeting v2 with backward compat for previous targeting cache

* Don't type constraint the possible providers
  • Loading branch information
zapo authored Nov 21, 2022
1 parent fb32556 commit 9f898a4
Show file tree
Hide file tree
Showing 19 changed files with 261 additions and 104 deletions.
33 changes: 14 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,21 +166,19 @@ type ProfileTraits = {

### Targeting API

To get the targeting key values associated by the configured DCN with the user's browser in real-time, you can call the targeting API as follows:
To get the targeting information associated by the configured DCN with the user's browser in real-time, you can call the targeting API as follows:

```js
sdk
.targeting()
.then((keyvalues) => {
// Iterate over all the key values entries and print them
for (const [key, values] of Object.entries(keyvalues)) {
console.log(`Targeting KV: ${key} = ${values.join(",")}`);
}
.then((response) => {
console.log(`Audience targeting: ${targeting.audience}`)
console.log(`User targeting: ${targeting.user}`)
})
.catch((err) => console.warn(`Targeting API Error: ${err.message}`));
```

On success, the resulting key values are typically sent as part of a subsequent ad call. Therefore we recommend that you either call targeting() before each ad call, or in parallel periodically, caching the resulting key values which you then provide in ad calls.
On success, the resulting targeting data is typically sent as part of a subsequent ad call. Therefore we recommend that you either call targeting() before each ad call, or in parallel periodically, caching the resulting targeting data which you then provide in ad calls.

#### Caching Targeting Data

Expand All @@ -189,9 +187,8 @@ The `targeting` API will automatically cache resulting key value data in client
```{javascript
const cachedTargetingData = sdk.targetingFromCache();
if (cachedTargetingData) {
for (const [key, values] of Object.entries(cachedTargetingData)) {
console.log(`Targeting KV: ${key} = ${values.join(",")}`);
}
console.log(`Audience targeting: ${targeting.audience}`)
console.log(`User targeting: ${targeting.user}`)
}
```

Expand Down Expand Up @@ -271,7 +268,7 @@ The following shows an example of how to safely initialize the SDK and dispatch

## Integrating GAM360

The Optable Web SDK can fetch targeting keyvalue data from a DCN and send it to a [Google Ad Manager 360](https://admanager.google.com/home/) ad server account for real-time targeting. It's also capable of intercepting advertising events from the [Google Publisher Tag](https://developers.google.com/doubleclick-gpt/guides/get-started) and logging them to a DCN via the **witness API**.
The Optable Web SDK can fetch targeting data from a DCN and map it to be sent to [Google Ad Manager 360](https://admanager.google.com/home/) ad server account for real-time targeting. It's also capable of intercepting advertising events from the [Google Publisher Tag](https://developers.google.com/doubleclick-gpt/guides/get-started) and logging them to a DCN via the **witness API**.

### Targeting key values

Expand Down Expand Up @@ -333,10 +330,8 @@ It's suggested to load the GAM banner view with an ad even when the call to your
// so that GAM ads are always loaded.
optable.cmd.push(function () {
optable.instance
.targeting()
.then(function (result) {
loadGAM(result);
})
.targetingKeyValues()
.then(loadGAM)
.catch((err) => {
loadGAM();
});
Expand All @@ -352,7 +347,7 @@ Note the use of `googletag.pubads().disableInitialLoad()` in the above example.

### Targeting key values from local cache

It's also possible to avoid disabling of the initial ad load by using the SDK's `targetingFromCache()` method instead as in the following example:
It's also possible to avoid disabling of the initial ad load by using the SDK's `targetingKeyValuesFromCache()` method instead as in the following example:

```html
<!-- Optable SDK async load: -->
Expand All @@ -379,7 +374,7 @@ It's also possible to avoid disabling of the initial ad load by using the SDK's
// Attempt to load Optable targeting key values from local cache, then load GAM ads:
optable.cmd.push(function () {
const tdata = optable.instance.targetingFromCache();
const tdata = optable.instance.targetingKeyValuesFromCache();
for (const [key, values] of Object.entries(tdata)) {
googletag.pubads().setTargeting(key, values);
}
Expand Down Expand Up @@ -536,15 +531,15 @@ For a working demo showing a `pbjs` and GAM integrated together, see the [demo p

### Custom key values

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:
For bidder adapters that do not support SDA, but that do support targeting private marketplace deals to key values, you can use a similar 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:

```html
<script>
// ...
// prior to pbjs.requestBids():
pbjs.que.push(function () {
optable.cmd.push(function () {
const tdata = optable.instance.targetingFromCache();
const tdata = optable.instance.targetingKeyValuesFromCache();
var fpd = {};
/*
Expand Down
2 changes: 1 addition & 1 deletion demos/npm/src/identifyAndTargeting.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ sdk.identify(emailID, ppid)
// DCN that are activated AND include one (or more) of the current user's registered identifiers.
// See https://github.com/Optable/optable-web-sdk#targeting-api for more info.
sdk
.targeting()
.targetingKeyValues()
.then((keyvalues) => {
for (const [key, values] of Object.entries(keyvalues)) {
console.log(`Targeting KV: ${key} = ${values.join(",")}`);
Expand Down
2 changes: 1 addition & 1 deletion demos/vanilla/nocookies/targeting/gam360-cached.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@

// Setup page-level GAM targeting from any cached targeting data and load ads as usual:
optable.cmd.push(function () {
const tdata = optable.instance.targetingFromCache();
const tdata = optable.instance.targetingKeyValuesFromCache();

if (tdata) {
for (const [key, values] of Object.entries(tdata)) {
Expand Down
2 changes: 1 addition & 1 deletion demos/vanilla/nocookies/targeting/gam360-cached.html.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
// Setup page-level GAM targeting from any cached targeting data and load ads as usual:
optable.cmd.push(function () {
const tdata = optable.instance.targetingFromCache();
const tdata = optable.instance.targetingKeyValuesFromCache();
if (tdata) {
for (const [key, values] of Object.entries(tdata)) {
Expand Down
10 changes: 4 additions & 6 deletions demos/vanilla/nocookies/targeting/gam360.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,11 @@
// Try to fetch targeting data from sandbox and pass it to GAM:
optable.cmd.push(function () {
optable.instance
.targeting()
.then(function (result) {
loadGAM(result);
})
.targetingKeyValues()
.then(loadGAM)
.catch((err) => {
console.log("[OptableSDK] targeting() exception: " + err.message);
loadGAM();
loadGAM()
});
});
</script>
Expand Down Expand Up @@ -116,7 +114,7 @@ <h4>Example: targeting API: GAM360</h4>
ad targeting.
</p>
<p>
In this example, the call to the <code>targeting</code> API happens first and, on success or error, banner
In this example, the call to the <code>targetingKeyValues()</code> API happens first and, on success or error, banner
ads are loaded from Optable's demo GAM account via <code>googletag.pubads().refresh()</code>. In order to
prevent ads loading until the asynchronous <code>targeting</code> call is done, we start by disabling
automatic ads loading with <code>googletag.pubads().disableInitialLoad()</code>.
Expand Down
10 changes: 4 additions & 6 deletions demos/vanilla/nocookies/targeting/gam360.html.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,11 @@
// Try to fetch targeting data from sandbox and pass it to GAM:
optable.cmd.push(function () {
optable.instance
.targeting()
.then(function (result) {
loadGAM(result);
})
.targetingKeyValues()
.then(loadGAM)
.catch((err) => {
console.log("[OptableSDK] targeting() exception: " + err.message);
loadGAM();
loadGAM()
});
});
</script>
Expand Down Expand Up @@ -116,7 +114,7 @@
ad targeting.
</p>
<p>
In this example, the call to the <code>targeting</code> API happens first and, on success or error, banner
In this example, the call to the <code>targetingKeyValues()</code> API happens first and, on success or error, banner
ads are loaded from Optable's demo GAM account via <code>googletag.pubads().refresh()</code>. In order to
prevent ads loading until the asynchronous <code>targeting</code> call is done, we start by disabling
automatic ads loading with <code>googletag.pubads().disableInitialLoad()</code>.
Expand Down
4 changes: 2 additions & 2 deletions demos/vanilla/nocookies/targeting/prebid.html
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@

// Setup page-level GAM targeting from any cached targeting data, and load GAM ads:
optable.cmd.push(function () {
const tdata = optable.instance.targetingFromCache();
const tdata = optable.instance.targetingKeyValuesFromCache();

if (tdata) {
for (const [key, values] of Object.entries(tdata)) {
Expand Down Expand Up @@ -240,7 +240,7 @@ <h4>Example: targeting API: Prebid.js</h4>
we also pass matching active cohorts to GAM.
</p>
<p>
In this example, we use the <code>prebidUserDataFromCache</code> API to retrieve any targeting data from browser
In this example, we use the <code>prebidUserDataFromCache()</code> API to retrieve any targeting data from browser
LocalStorage, in order to pass it to Prebid.js via <a href="https://docs.prebid.org/features/firstPartyData.html#segments-and-taxonomy">seller defined audiences</a>. We also call the SDK <code>targeting</code> API
which will fetch the latest targeting data from our DCN and cache it locally for later use. Since these
two events happen asynchronously, it's possible that the targeting data passed to GAM is slightly outdated.
Expand Down
4 changes: 2 additions & 2 deletions demos/vanilla/nocookies/targeting/prebid.html.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
// Setup page-level GAM targeting from any cached targeting data, and load GAM ads:
optable.cmd.push(function () {
const tdata = optable.instance.targetingFromCache();
const tdata = optable.instance.targetingKeyValuesFromCache();
if (tdata) {
for (const [key, values] of Object.entries(tdata)) {
Expand Down Expand Up @@ -240,7 +240,7 @@
we also pass matching active cohorts to GAM.
</p>
<p>
In this example, we use the <code>prebidUserDataFromCache</code> API to retrieve any targeting data from browser
In this example, we use the <code>prebidUserDataFromCache()</code> API to retrieve any targeting data from browser
LocalStorage, in order to pass it to Prebid.js via <a href="https://docs.prebid.org/features/firstPartyData.html#segments-and-taxonomy">seller defined audiences</a>. We also call the SDK <code>targeting</code> API
which will fetch the latest targeting data from our DCN and cache it locally for later use. Since these
two events happen asynchronously, it's possible that the targeting data passed to GAM is slightly outdated.
Expand Down
8 changes: 4 additions & 4 deletions demos/vanilla/targeting/gam360-cached.html
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@

// Setup page-level GAM targeting from any cached targeting data and load ads as usual:
optable.cmd.push(function () {
const tdata = optable.instance.targetingFromCache();
const gamTargeting = optable.instance.targetingKeyValuesFromCache();

if (tdata) {
for (const [key, values] of Object.entries(tdata)) {
if (gamTargeting) {
for (const [key, values] of Object.entries(gamTargeting)) {
googletag.pubads().setTargeting(key, values);
console.log("[OptableSDK] googletag.pubads().setTargeting(" + key + ", [" + values + "])");
}
Expand Down Expand Up @@ -107,7 +107,7 @@ <h4>Example: targeting API: GAM360 (cached data)</h4>
ad targeting.
</p>
<p>
In this example, we use the <code>targetingFromCache()</code> API to retrieve any targeting data from
In this example, we use the <code>targetingKeyValuesFromCache()</code> API to retrieve any targeting data from
browser LocalStorage, in order to pass it to GPT via <code>googletag.pubads().setTargeting()</code>. We also
call the SDK <code>targeting</code> API which will fetch the latest targeting data from our DCN and
cache it locally for later use. Since these two events happen asynchronously, it's possible that the
Expand Down
8 changes: 4 additions & 4 deletions demos/vanilla/targeting/gam360-cached.html.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@
// Setup page-level GAM targeting from any cached targeting data and load ads as usual:
optable.cmd.push(function () {
const tdata = optable.instance.targetingFromCache();
const gamTargeting = optable.instance.targetingKeyValuesFromCache();
if (tdata) {
for (const [key, values] of Object.entries(tdata)) {
if (gamTargeting) {
for (const [key, values] of Object.entries(gamTargeting)) {
googletag.pubads().setTargeting(key, values);
console.log("[OptableSDK] googletag.pubads().setTargeting(" + key + ", [" + values + "])");
}
Expand Down Expand Up @@ -107,7 +107,7 @@
ad targeting.
</p>
<p>
In this example, we use the <code>targetingFromCache()</code> API to retrieve any targeting data from
In this example, we use the <code>targetingKeyValuesFromCache()</code> API to retrieve any targeting data from
browser LocalStorage, in order to pass it to GPT via <code>googletag.pubads().setTargeting()</code>. We also
call the SDK <code>targeting</code> API which will fetch the latest targeting data from our DCN and
cache it locally for later use. Since these two events happen asynchronously, it's possible that the
Expand Down
10 changes: 4 additions & 6 deletions demos/vanilla/targeting/gam360.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,11 @@
// Try to fetch targeting data from DCN and pass it to GAM:
optable.cmd.push(function () {
optable.instance
.targeting()
.then(function (result) {
loadGAM(result);
})
.targetingKeyValues()
.then(loadGAM)
.catch((err) => {
console.log("[OptableSDK] targeting() exception: " + err.message);
loadGAM();
loadGAM()
});
});
</script>
Expand Down Expand Up @@ -115,7 +113,7 @@ <h4>Example: targeting API: GAM360</h4>
ad targeting.
</p>
<p>
In this example, the call to the <code>targeting</code> API happens first and, on success or error, banner
In this example, the call to the <code>targetingKeyValues()</code> API happens first and, on success or error, banner
ads are loaded from Optable's demo GAM account via <code>googletag.pubads().refresh()</code>. In order to
prevent ads loading until the asynchronous <code>targeting</code> call is done, we start by disabling
automatic ads loading with <code>googletag.pubads().disableInitialLoad()</code>.
Expand Down
10 changes: 4 additions & 6 deletions demos/vanilla/targeting/gam360.html.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,11 @@
// Try to fetch targeting data from DCN and pass it to GAM:
optable.cmd.push(function () {
optable.instance
.targeting()
.then(function (result) {
loadGAM(result);
})
.targetingKeyValues()
.then(loadGAM)
.catch((err) => {
console.log("[OptableSDK] targeting() exception: " + err.message);
loadGAM();
loadGAM()
});
});
</script>
Expand Down Expand Up @@ -115,7 +113,7 @@
ad targeting.
</p>
<p>
In this example, the call to the <code>targeting</code> API happens first and, on success or error, banner
In this example, the call to the <code>targetingKeyValues()</code> API happens first and, on success or error, banner
ads are loaded from Optable's demo GAM account via <code>googletag.pubads().refresh()</code>. In order to
prevent ads loading until the asynchronous <code>targeting</code> call is done, we start by disabling
automatic ads loading with <code>googletag.pubads().disableInitialLoad()</code>.
Expand Down
5 changes: 2 additions & 3 deletions demos/vanilla/targeting/prebid.html
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@

// Setup page-level GAM targeting from any cached targeting data, and load GAM ads:
optable.cmd.push(function () {
const tdata = optable.instance.targetingFromCache();
const tdata = optable.instance.targetingKeyValuesFromCache();

if (tdata) {
for (const [key, values] of Object.entries(tdata)) {
Expand Down Expand Up @@ -163,7 +163,6 @@
});

console.log("[OptableSDK] pbjs.setConfig(ortb2.user.data)");
console.log(pbdata);
}

pbjs.setConfig({
Expand Down Expand Up @@ -239,7 +238,7 @@ <h4>Example: targeting API: Prebid.js</h4>
we also pass matching active cohorts to GAM.
</p>
<p>
In this example, we use the <code>prebidUserDataFromCache</code> API to retrieve any targeting data from browser
In this example, we use the <code>prebidUserDataFromCache()</code> API to retrieve any targeting data from browser
LocalStorage, in order to pass it to Prebid.js via <a href="https://docs.prebid.org/features/firstPartyData.html#segments-and-taxonomy">seller defined audiences</a>. We also call the SDK <code>targeting</code> API
which will fetch the latest targeting data from our DCN and cache it locally for later use. Since these
two events happen asynchronously, it's possible that the targeting data passed to Prebid is slightly outdated.
Expand Down
5 changes: 2 additions & 3 deletions demos/vanilla/targeting/prebid.html.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@
// Setup page-level GAM targeting from any cached targeting data, and load GAM ads:
optable.cmd.push(function () {
const tdata = optable.instance.targetingFromCache();
const tdata = optable.instance.targetingKeyValuesFromCache();
if (tdata) {
for (const [key, values] of Object.entries(tdata)) {
Expand Down Expand Up @@ -163,7 +163,6 @@
});
console.log("[OptableSDK] pbjs.setConfig(ortb2.user.data)");
console.log(pbdata);
}
pbjs.setConfig({
Expand Down Expand Up @@ -239,7 +238,7 @@
we also pass matching active cohorts to GAM.
</p>
<p>
In this example, we use the <code>prebidUserDataFromCache</code> API to retrieve any targeting data from browser
In this example, we use the <code>prebidUserDataFromCache()</code> API to retrieve any targeting data from browser
LocalStorage, in order to pass it to Prebid.js via <a href="https://docs.prebid.org/features/firstPartyData.html#segments-and-taxonomy">seller defined audiences</a>. We also call the SDK <code>targeting</code> API
which will fetch the latest targeting data from our DCN and cache it locally for later use. Since these
two events happen asynchronously, it's possible that the targeting data passed to Prebid is slightly outdated.
Expand Down
Loading

0 comments on commit 9f898a4

Please sign in to comment.