From eaa84e850a04bf09886e2fbb33019e413dddee14 Mon Sep 17 00:00:00 2001 From: MO Thibault <103271673+MO-Thibault@users.noreply.github.com> Date: Wed, 4 Dec 2024 14:21:39 -0500 Subject: [PATCH] Remove lmpid and allow passing other ids to secure signals (#136) --- Makefile | 2 - demos/Dockerfile | 2 - demos/integration/lmpid-prebid-gpt.html.tpl | 346 -------------------- demos/integration/lmpid-signal-gpt.html.tpl | 266 --------------- lib/addons/gpt.test.js | 63 ++++ lib/addons/gpt.ts | 25 +- lib/core/storage.test.js | 12 - lib/core/storage.ts | 30 +- lib/edge/targeting.ts | 18 +- lib/sdk.ts | 5 - 10 files changed, 75 insertions(+), 694 deletions(-) delete mode 100644 demos/integration/lmpid-prebid-gpt.html.tpl delete mode 100644 demos/integration/lmpid-signal-gpt.html.tpl create mode 100644 lib/addons/gpt.test.js diff --git a/Makefile b/Makefile index aef1b5e1..adf5b083 100644 --- a/Makefile +++ b/Makefile @@ -60,8 +60,6 @@ demo-html: envsubst $(DEMO_VARS) < demos/vanilla/nocookies/targeting/gam360.html.tpl > demos/vanilla/nocookies/targeting/gam360.html envsubst $(DEMO_VARS) < demos/vanilla/nocookies/targeting/gam360-cached.html.tpl > demos/vanilla/nocookies/targeting/gam360-cached.html envsubst $(DEMO_VARS) < demos/vanilla/nocookies/targeting/prebid.html.tpl > demos/vanilla/nocookies/targeting/prebid.html - envsubst $(DEMO_VARS) < demos/integration/lmpid-prebid-gpt.html.tpl > demos/integration/lmpid-prebid-gpt.html - envsubst $(DEMO_VARS) < demos/integration/lmpid-signal-gpt.html.tpl > demos/integration/lmpid-signal-gpt.html envsubst $(DEMO_VARS) < demos/ads/protected-audience/advertiser.html.tpl > demos/ads/protected-audience/advertiser.html envsubst $(DEMO_VARS) < demos/ads/protected-audience/publisher.html.tpl > demos/ads/protected-audience/publisher.html envsubst $(DEMO_VARS) < demos/ads/protected-audience/publisher-gam.html.tpl > demos/ads/protected-audience/publisher-gam.html diff --git a/demos/Dockerfile b/demos/Dockerfile index 316f631b..f5bdd38d 100644 --- a/demos/Dockerfile +++ b/demos/Dockerfile @@ -5,8 +5,6 @@ COPY --chmod=0444 ./vanilla/targeting/gam360.html ./vanilla/targeting/gam360.htm COPY --chmod=0444 ./vanilla/targeting/gam360-cached.html ./vanilla/targeting/gam360-cached.html COPY --chmod=0444 ./vanilla/targeting/prebid.html ./vanilla/targeting/prebid.html COPY --chmod=0444 ./vanilla/targeting/prebid.js ./vanilla/targeting/prebid.js -COPY --chmod=0444 ./integration/lmpid-prebid-gpt.html ./integration/lmpid-prebid-gpt.html -COPY --chmod=0444 ./integration/lmpid-signal-gpt.html ./integration/lmpid-signal-gpt.html COPY --chmod=0444 ./integration/prebid.js ./integration/prebid.js COPY --chmod=0444 ./vanilla/identify.html ./vanilla/identify.html COPY --chmod=0444 ./vanilla/profile.html ./vanilla/profile.html diff --git a/demos/integration/lmpid-prebid-gpt.html.tpl b/demos/integration/lmpid-prebid-gpt.html.tpl deleted file mode 100644 index 26deaea3..00000000 --- a/demos/integration/lmpid-prebid-gpt.html.tpl +++ /dev/null @@ -1,346 +0,0 @@ - - - - - Optable Web SDK Demos - - - - - - - - - - - - - - -
-
-
- -
-
-
-
-
-

Loblaw Media Private ID (LM PID) with Prebid.js and GPT Secure Signals

-
-
-
-
-

- The - Optable SDK - enables easy deployment of the - Loblaw Media - Private ID (LM PID). - The LM PID is generated automatically for all identified users successfully matched with - Loblaw Media. LM PID is a secure token that contains information on matched users - that is computed within the Optable data clean room environment. It enables the - Loblaw Media DSP (MediaAisle) - to target, control ad exposure frequency, and measure the - effectiveness of Loblaw Media advertisements to identified, authenticated, and consented publisher users. -

-

- This demo page shows an integration of LM PID deployed via Optable, with both Prebid.js - (including Loblaw Media's bidder adapter and user ID modules), and with - Google Publisher Tag (GPT) - and - Google Ad Manager (GAM) - Secure Signals. - Whenever possible, - it is recommended that both methods are enabled together as shown in this demo page, such that - the likelihood of MediaAisle bidding is maximised. -

- -
Step 1: Request access
-

- Contact your Optable account manager to request access to the Loblaw Media Private ID - framework integration. Once configured and enabled, the Loblaw Media partner - will appear connected in the partnerships section of the Optable user interface. -

-

- Please note that Steps 2-4 below should be repeated for each web site that you would like to enable - LM PID on. -

- -
Step 2: Create a Javascript SDK source
-

- If your web site is not already represented by a source in your Optable - Data Collaboration Node (DCN), create a - Javascript SDK source - and note its - unique slug identifier, as well as the hostname of your DCN, as these will be required - for Optable SDK integration (see Step 3). -

-

- LM PID will be returned by your Optable DCN for all matched users associated with - activation clean rooms originating from the Loblaw Media partner. -

- -
Step 3: Deploy the Optable SDK to your site
-

- If you haven't already deployed the Optable SDK to your web site, have a look at the - Optable SDK README. There are two SDK APIs which you must deploy in order to integrate LM PID: - identify - and - targeting. -

-

- The identify API enables you to associate a user's browser with a known identifier, such - as an email address or a publisher assigned user ID. Since Loblaw Media activation matches operate on a - combination of email address, phone number, and mobile advertising IDs, it is recommended that you - identify consenting users with all of that user's known and consented ad IDs. - You can do this by calling - identify with additional identifiers directly from your web site, or by calling - it with a single publisher assigned user ID, and then separately loading identity mappings - (associated with the publisher assigned user ID) via any - supported sources. -

-

- The targeting API retrieves targeting data, including the LM PID when available, - and stores it in browser local storage for subsequent retrieval. -

- -
Step 4: Prebid.js and GPT integrations
-

- For Prebid.js installations, you must make sure to include the mabidder bidder adapter and - the lmpid user ID module. Note that you must include mabidder in the - addAdUnits() call. - See - Prebid.js download instructions - and - Prebid.js user ID modules - for details. -

-

- For Google Publisher Tag (GPT), you must call the installGPTSecureSignals() API - shortly after Optable SDK instantiation. This API will configure GPT to pass lmpid - to Google Ad Manager (GAM), when it is available in browser local storage. -

-

- Try to call the Optable SDK targeting() API as early as possible. This API will - retrieve the latest lmpid, when it is enabled and available for the current user, - and store it in browser local storage for retrieval by both Prebid.js and GPT as previously described. -

- -
Prebid.js and GPT integration example
-

- While the lmpid user ID module passes the Loblaw Media Private ID to the - Loblaw Media bidder (mabidder), the installGPTSecureSignals() API in Optable's - Javascript SDK exposes it to Google Ad Manager via - Secure Signals. - Please make sure to follow Google's instructions for enabling Secure Signals sharing on your websites. -

-

- The code snippet below shows an example integration with both Prebid.js and GPT on page. Note - that {OPTABLE_DCN_HOST} and {OPTABLE_DCN_SOURCE_SLUG} must be replaced - with your Optable Data Collaboration Node (DCN) hostname and Javascript SDK source slug, respectively. -

-

-

// Setup Optable, Prebid.js and GPT SDKs.
-window.optable = window.optable || { cmd: [] };
-window.googletag = window.googletag || { cmd: [] };
-window.pbjs = window.pbjs || { que: [] };
-
-// When optable SDK is loaded, initialize it and install GPT Secure Signals provider.
-optable.cmd.push(function () {
-  optable.instance = new optable.SDK({
-    host: "{OPTABLE_DCN_HOST}",
-    site: "{OPTABLE_DCN_SOURCE_SLUG}",
-  });
-
-  optable.instance.installGPTSecureSignals();
-  optable.instance.targeting();
-});
-
-// Disable initial GPT load, required for Prebid.js
-googletag.cmd.push(function () {
-  googletag.pubads().disableInitialLoad();
-});
-
-// When prebid SDK is loaded, configure it to use LMPID user ID module and
-// request bids for the defined ad units.
-
-pbjs.que.push(function () {
-  // Enable Loblaw Media Private ID user ID module (lmpid):
-  pbjs.mergeConfig({ userSync: { userIds: [{ name: "lmpid" }] } })
-
-  // Configure some ad units.
-  // Note that while it's not relevant for LMPID integration,
-  // Loblaw Media's prebid ad server currently requires passing a ppid.
-  pbjs.addAdUnits([{
-    code: "/my/slot", // must match the defined ad slots below
-    mediaTypes: { banner: { sizes: [[728, 90]] } },
-    bids: [{ bidder: "mabidder", params: { ppid: "{MY_PPID}" }}],
-  }]);
-
-  // Define some slots
-  googletag.cmd.push(function() {
-    googletag
-      .defineSlot("/my/slot", [[728, 90]], "ad")
-      .addService(googletag.pubads());
-
-    googletag.pubads().enableSingleRequest();
-    googletag.enableServices();
-
-    googletag.display("ad");
-
-    // Request bids through Prebid.js.
-    pbjs.requestBids({
-      bidsBackHandler: function() {
-        // Set targeting in matching GPT ad slots
-        pbjs.setTargetingForGPTAsync();
-
-        // Request ads
-        googletag.pubads().refresh();
-      },
-    });
-  });
-});
-
-

- -

Try it!

-

- This demo page is setup so that the following random emails are generating LM PID requests. -

-

- To trigger LM PID insertion in ad requests, you must first - identify using one of the following test email identifiers: - -

john.doe@acme.test
-emily.smith@acme.test
-alexander.wilson@acme.test
-sarah.johnson@acme.test
-david.thompson@acme.test
-lisa.brown@acme.test
-jason.miller@acme.test
-jessica.wright@acme.test
-matthew.harris@acme.test
-olivia.anderson@acme.test
-

-
-
-
-
-
-
-
web-sdk-demo-securesignals/header-ad
- -
-
-
-
-
-
-
web-sdk-demo-securesignals/box-ad
- -
-
-
-
-
-
-
web-sdk-demo-securesignals/footer-ad
- -
-
-
-
- -
-
-
- Home | Contact | - Privacy | - LinkedIn | - Twitter -
-
-
-
- - - - diff --git a/demos/integration/lmpid-signal-gpt.html.tpl b/demos/integration/lmpid-signal-gpt.html.tpl deleted file mode 100644 index 000f1c99..00000000 --- a/demos/integration/lmpid-signal-gpt.html.tpl +++ /dev/null @@ -1,266 +0,0 @@ - - - - - Optable Web SDK Demos - - - - - - - - - - - - -
-
-
- -
-
-
-
-
-

Loblaw Media Private ID (LM PID) with GPT Secure Signals

-
-
-
-
-

- The - Optable SDK - enables easy deployment of the - Loblaw Media - Private ID (LM PID). - The LM PID is generated automatically for all identified users successfully matched with - Loblaw Media. LM PID is a secure token that contains information on matched users - that is computed within the Optable data clean room environment. It enables the - Loblaw Media DSP (MediaAisle) - to target, control ad exposure frequency, and measure the - effectiveness of Loblaw Media advertisements to identified, authenticated, and consented publisher users. -

-

- This demo page shows an integration of LM PID deployed via Optable, with the - Google Publisher Tag (GPT) - and - Google Ad Manager (GAM) - Secure Signals. -

- -
Step 1: Request access
-

- Contact your Optable account manager to request access to the Loblaw Media Private ID - framework integration. Once configured and enabled, the Loblaw Media partner - will appear connected in the partnerships section of the Optable user interface. -

-

- Please note that Steps 2-4 below should be repeated for each web site that you would like to enable - LM PID on. -

- -
Step 2: Create a Javascript SDK source
-

- If your web site is not already represented by a source in your Optable - Data Collaboration Node (DCN), create a - Javascript SDK source - and note its - unique slug identifier, as well as the hostname of your DCN, as these will be required - for Optable SDK integration (see Step 3). -

-

- LM PID will be returned by your Optable DCN for all matched users associated with - activation clean rooms originating from the Loblaw Media partner. -

- -
Step 3: Deploy the Optable SDK to your site
-

- If you haven't already deployed the Optable SDK to your web site, have a look at the - Optable SDK README. There are two SDK APIs which you must deploy in order to integrate LM PID: - identify - and - targeting. -

-

- The identify API enables you to associate a user's browser with a known identifier, such - as an email address or a publisher assigned user ID. Since Loblaw Media activation matches operate on a - combination of email address, phone number, and mobile advertising IDs, it is recommended that you - identify consenting users with all of that user's known and consented ad IDs. - You can do this by calling - identify with additional identifiers directly from your web site, or by calling - it with a single publisher assigned user ID, and then separately loading identity mappings - (associated with the publisher assigned user ID) via any - supported sources. -

-

- The targeting API retrieves targeting data, including the LM PID when available, - and stores it in browser local storage for subsequent retrieval. -

- -
Step 4: GPT integration
-

- You must call the installGPTSecureSignals() SDK API - shortly after Optable SDK instantiation. This API will configure GPT to pass lmpid - to Google Ad Manager (GAM), when it is available in browser local storage. -

-

- Try to call the Optable SDK targeting() API as early as possible. This API will - retrieve the latest lmpid, when it is enabled and available for the current user, - and store it in browser local storage for retrieval by GPT as previously described. -

- -
Prebid.js and GPT integration example
-

- The code snippet below shows an example integration with GPT on page. Note - that {OPTABLE_DCN_HOST} and {OPTABLE_DCN_SOURCE_SLUG} must be replaced - with your Optable Data Collaboration Node (DCN) hostname and Javascript SDK source slug, respectively. -

-

-

// Setup both Optable and GPT SDKs.
-window.optable = window.optable || { cmd: [] };
-window.googletag = window.googletag || { cmd: [] };
-
-// When optable SDK is loaded, initialize it and install GPT Secure Signals provider.
-optable.cmd.push(function () {
-  optable.instance = new optable.SDK({
-    host: "{OPTABLE_DCN_HOST}",
-    site: "{OPTABLE_DCN_SOURCE_SLUG}",
-  });
-
-  optable.instance.installGPTSecureSignals();
-  optable.instance.targeting()
-});
-
-// When GPT SDK is loaded, define and prepare an ad slot.
-// Note that we disableInitialLoad() in order to defer the first ad request
-// until secure signals are installed.
-googletag.cmd.push(function() {
-  googletag.pubads().disableInitialLoad();
-
-  googletag
-    .defineSlot('/my/slot', [[728, 90]], "ad")
-    .addService(googletag.pubads());
-
-  googletag.pubads().enableSingleRequest();
-  googletag.enableServices();
-  googletag.display("ad");
-});
-
-// Explicitly refresh ads when everything is loaded and the above setup is done.
-googletag.cmd.push(function () {
-  optable.cmd.push(function () {
-    googletag.pubads().refresh();
-  });
-});
-
-

-

Try it!

-

- This demo page is setup so that the following random emails are generating LM PID requests. -

-

- To trigger LM PID insertion in ad requests, you must first - identify using one of the following test email identifiers: - -

john.doe@acme.test
-emily.smith@acme.test
-alexander.wilson@acme.test
-sarah.johnson@acme.test
-david.thompson@acme.test
-lisa.brown@acme.test
-jason.miller@acme.test
-jessica.wright@acme.test
-matthew.harris@acme.test
-olivia.anderson@acme.test
-

-
-
-
- -
-
-
-
web-sdk-demo-securesignals/header-ad
- -
-
-
-
-
-
-
web-sdk-demo-securesignals/box-ad
- -
-
-
-
-
-
-
web-sdk-demo-securesignals/footer-ad
- -
-
-
-
- -
-
-
- Home | Contact | - Privacy | - LinkedIn | - Twitter -
-
-
- -
- - diff --git a/lib/addons/gpt.test.js b/lib/addons/gpt.test.js new file mode 100644 index 00000000..d02b363b --- /dev/null +++ b/lib/addons/gpt.test.js @@ -0,0 +1,63 @@ +import OptableSDK from "../sdk"; +import "./gpt.ts"; + +describe("OptableSDK - installGPTSecureSignals", () => { + let SDK; + + beforeEach(() => { + // Initialize the SDK instance + SDK = new OptableSDK({ host: "localhost", site: "test" }); + + // Reset global googletag object + window.googletag = { cmd: [], secureSignalProviders: [] }; + }); + + test("installs secure signals when provided valid signals", () => { + const signals = [ + { provider: "provider1", id: "idString1" }, + { provider: "provider2", id: "idString2" }, + ]; + + // Call the installGPTSecureSignals method + SDK.installGPTSecureSignals(...signals); + + // Execute all googletag commands + window.googletag.cmd.forEach((cmd) => cmd()); + + // Expectations + expect(window.googletag.secureSignalProviders).toHaveLength(2); + expect(window.googletag.secureSignalProviders).toEqual([ + { + id: "provider1", + collectorFunction: expect.any(Function), + }, + { + id: "provider2", + collectorFunction: expect.any(Function), + }, + ]); + + // Verify the collector functions + const collectedIds = window.googletag.secureSignalProviders.map((provider) => provider.collectorFunction()); + return Promise.all(collectedIds).then((results) => { + expect(results).toEqual(["idString1", "idString2"]); + }); + }); + + test("does nothing when no signals are provided", () => { + // Call the installGPTSecureSignals method with no arguments + SDK.installGPTSecureSignals(); + + // Expectations + expect(window.googletag.cmd).toHaveLength(0); + expect(window.googletag.secureSignalProviders).toHaveLength(0); + }); + + test("handles an empty signals array gracefully", () => { + SDK.installGPTSecureSignals(); + + // Expectations + expect(window.googletag.cmd).toHaveLength(0); // cmd should remain empty + expect(window.googletag.secureSignalProviders).toHaveLength(0); // No secureSignalProviders should be added + }); +}); diff --git a/lib/addons/gpt.ts b/lib/addons/gpt.ts index 077ba738..394b7769 100644 --- a/lib/addons/gpt.ts +++ b/lib/addons/gpt.ts @@ -1,5 +1,4 @@ import type { WitnessProperties } from "../edge/witness"; -import { lmpidProvider } from "../edge/targeting"; import OptableSDK from "../sdk"; declare module "../sdk" { @@ -48,23 +47,19 @@ OptableSDK.prototype.installGPTEventListeners = function () { }; /* - * installGPTSecureSignals() sets up loblaw media private ID secure signals on GPT from targeting. + * Pass user-defined signals to GAM Secure Signals */ -OptableSDK.prototype.installGPTSecureSignals = function () { - const sdk = this; - sdk.installGPTSecureSignals = function () {}; - - window.googletag = window.googletag || { cmd: [], secureSignalProviders: [] }; +OptableSDK.prototype.installGPTSecureSignals = function (...signals: Array<{ provider: string; id: string }>) { + window.googletag = window.googletag || { cmd: [] }; const gpt = window.googletag; - const lmpid = sdk.lmpidFromCache(); - if (lmpid) { - gpt.cmd.push(function () { - gpt.secureSignalProviders.push({ - id: lmpidProvider, - collectorFunction: function () { - return Promise.resolve(lmpid); - }, + if (signals && signals.length > 0) { + gpt.cmd.push(() => { + signals.forEach(({ provider, id }) => { + gpt.secureSignalProviders.push({ + id: provider, + collectorFunction: () => Promise.resolve(id), + }); }); }); } diff --git a/lib/core/storage.test.js b/lib/core/storage.test.js index 0a4eb931..483f15af 100644 --- a/lib/core/storage.test.js +++ b/lib/core/storage.test.js @@ -52,16 +52,4 @@ describe("LocalStorage", () => { audience: [], }); }); - - test("setLmpid doesn't store anything if disabled", () => { - const store = new LocalStorage(randomConfig()); - store.setLmpid({ user: [], audience: [] }); - expect(store.getLmpid()).toBeNull(); - }); - - test("setLmpid store first private id if enabled", () => { - const store = new LocalStorage(randomConfig()); - store.setLmpid({ user: [{ provider: "loblawmedia.ca", ids: [{ id: "PIDV1first" }, { id: "PIDV1second" }] }] }); - expect(store.getLmpid()).toBe("PIDV1first"); - }); }); diff --git a/lib/core/storage.ts b/lib/core/storage.ts index 15275ce3..1bc6eab5 100644 --- a/lib/core/storage.ts +++ b/lib/core/storage.ts @@ -1,7 +1,6 @@ import { SiteResponse } from "../edge/site"; import type { OptableConfig } from "../config"; import type { TargetingResponse } from "../edge/targeting"; -import { lmpidProvider } from "../edge/targeting"; function toBinary(str: string): string { const codeUnits = new Uint16Array(str.length); @@ -11,17 +10,10 @@ function toBinary(str: string): string { return String.fromCharCode(...new Uint8Array(codeUnits.buffer)); } -declare global { - interface Window { - __lmpid?: string; - } -} - class LocalStorage { private passportKey: string; private targetingV1Key: string; private targetingKey: string; - private lmpidKey: string; private siteKey: string; constructor(private Config: OptableConfig) { @@ -31,7 +23,6 @@ class LocalStorage { this.passportKey = "OPTABLE_PASS_" + sfx; this.targetingKey = "OPTABLE_V2_TGT_" + sfx; - this.lmpidKey = "__lmpid"; this.siteKey = "OPTABLE_SITE_" + sfx; } @@ -83,7 +74,6 @@ class LocalStorage { } window.localStorage.setItem(this.targetingKey, JSON.stringify(targeting)); - this.setLmpid(targeting); } setSite(site?: SiteResponse | null) { @@ -99,24 +89,6 @@ class LocalStorage { return parsed; } - // setLmpid conditionally set the Lmpid in local storage - // based on the provider being present in the targeting response - setLmpid(targeting: TargetingResponse) { - const provider = targeting.user?.find((userIds) => userIds.provider === lmpidProvider); - // Don't touch local storage if the provider is not enabled - if (!provider) { - return; - } - - const id = provider.ids?.[0]?.id ?? ""; - window.localStorage.setItem(this.lmpidKey, id); - window.__lmpid = id; - } - - getLmpid(): string | null { - return window.__lmpid || window.localStorage.getItem(this.lmpidKey) || null; - } - clearPassport() { window.localStorage.removeItem(this.passportKey); } @@ -130,5 +102,5 @@ class LocalStorage { } } -export { LocalStorage, lmpidProvider }; +export { LocalStorage }; export default LocalStorage; diff --git a/lib/edge/targeting.ts b/lib/edge/targeting.ts index 3670964f..b4475719 100644 --- a/lib/edge/targeting.ts +++ b/lib/edge/targeting.ts @@ -24,8 +24,6 @@ type TargetingResponse = { user?: UserIdentifiers[]; }; -const lmpidProvider = "loblawmedia.ca"; - async function Targeting(config: Required, id: string): Promise { const searchParams = new URLSearchParams({ id }); const path = "/v2/targeting?" + searchParams.toString(); @@ -43,11 +41,6 @@ async function Targeting(config: Required, id: string): Promise): string | null { - const ls = new LocalStorage(config); - return ls.getLmpid(); -} - function TargetingFromCache(config: Required): TargetingResponse | null { const ls = new LocalStorage(config); return ls.getTargeting(); @@ -110,14 +103,5 @@ function TargetingKeyValues(tdata: TargetingResponse | null): TargetingKeyValues return result; } -export { - Targeting, - TargetingFromCache, - TargetingClearCache, - TargetingResponse, - PrebidORTB2, - TargetingKeyValues, - LmpidFromCache, - lmpidProvider, -}; +export { Targeting, TargetingFromCache, TargetingClearCache, TargetingResponse, PrebidORTB2, TargetingKeyValues }; export default Targeting; diff --git a/lib/sdk.ts b/lib/sdk.ts index bcbb1f36..21057294 100644 --- a/lib/sdk.ts +++ b/lib/sdk.ts @@ -13,7 +13,6 @@ import { TargetingFromCache, TargetingClearCache, PrebidORTB2, - LmpidFromCache, } from "./edge/targeting"; import { Witness } from "./edge/witness"; import { Profile } from "./edge/profile"; @@ -67,10 +66,6 @@ class OptableSDK { TargetingClearCache(this.dcn); } - lmpidFromCache(): string | null { - return LmpidFromCache(this.dcn); - } - async prebidORTB2(): Promise { return PrebidORTB2(await this.targeting()); }