diff --git a/services/ad-server/tsconfig.json b/services/ad-server/tsconfig.json
index 115261cf..c7ad80bc 100644
--- a/services/ad-server/tsconfig.json
+++ b/services/ad-server/tsconfig.json
@@ -6,6 +6,6 @@
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
- "skipLibCheck": true,
- },
+ "skipLibCheck": true
+ }
}
diff --git a/services/dsp-a/tsconfig.json b/services/dsp-a/tsconfig.json
index f8c3d840..9c07f0c9 100644
--- a/services/dsp-a/tsconfig.json
+++ b/services/dsp-a/tsconfig.json
@@ -8,6 +8,6 @@
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
- "skipLibCheck": true,
- },
+ "skipLibCheck": true
+ }
}
diff --git a/services/dsp-b/tsconfig.json b/services/dsp-b/tsconfig.json
index f8c3d840..9c07f0c9 100644
--- a/services/dsp-b/tsconfig.json
+++ b/services/dsp-b/tsconfig.json
@@ -8,6 +8,6 @@
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
- "skipLibCheck": true,
- },
+ "skipLibCheck": true
+ }
}
diff --git a/services/dsp/package-lock.json b/services/dsp/package-lock.json
index d44e26e9..6fd7c495 100644
--- a/services/dsp/package-lock.json
+++ b/services/dsp/package-lock.json
@@ -9,7 +9,7 @@
"version": "0.0.0",
"license": "apache-2.0",
"dependencies": {
- "cbor": "^9.0.0",
+ "cbor": "^9.0.2",
"ejs": "^3.1.9",
"express": "^4.18.2",
"structured-field-values": "^2.0.1"
@@ -280,9 +280,9 @@
}
},
"node_modules/cbor": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/cbor/-/cbor-9.0.1.tgz",
- "integrity": "sha512-/TQOWyamDxvVIv+DY9cOLNuABkoyz8K/F3QE56539pGVYohx0+MEA1f4lChFTX79dBTBS7R1PF6ovH7G+VtBfQ==",
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/cbor/-/cbor-9.0.2.tgz",
+ "integrity": "sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==",
"dependencies": {
"nofilter": "^3.1.0"
},
diff --git a/services/dsp/package.json b/services/dsp/package.json
index d880f01f..74eb9571 100644
--- a/services/dsp/package.json
+++ b/services/dsp/package.json
@@ -10,7 +10,7 @@
"ncu": "npx npm-check-updates -u"
},
"dependencies": {
- "cbor": "^9.0.0",
+ "cbor": "^9.0.2",
"ejs": "^3.1.9",
"express": "^4.18.2",
"structured-field-values": "^2.0.1"
diff --git a/services/dsp/src/index.ts b/services/dsp/src/index.ts
index 95bb1f8a..35761e5b 100644
--- a/services/dsp/src/index.ts
+++ b/services/dsp/src/index.ts
@@ -421,8 +421,12 @@ app.post(
},
);
-app.get('/private-aggregation', (req, res) => {
- res.render('private-aggregation');
+app.get('/private-aggregation-aws', (req, res) => {
+ res.render('private-aggregation-aws');
+});
+
+app.get('/private-aggregation-gcp', (req, res) => {
+ res.render('private-aggregation-gcp');
});
app.post(
diff --git a/services/dsp/src/public/js/dsp.js b/services/dsp/src/public/js/dsp.js
index ac98465e..2fcaede0 100644
--- a/services/dsp/src/public/js/dsp.js
+++ b/services/dsp/src/public/js/dsp.js
@@ -1,7 +1,10 @@
let dsp = document.currentScript.getAttribute('dsp');
window.addEventListener('load', (event) => {
- let iframe = document.createElement('iframe');
+ let iframeAws = document.createElement('iframe');
+ let iframeGcp = document.createElement('iframe');
// let dsp = document.currentScript.getAttribute('dsp');
- iframe.src = `https://${dsp}/private-aggregation`;
- document.body.appendChild(iframe);
+ iframeAws.src = `https://${dsp}/private-aggregation-aws`;
+ iframeGcp.src = `https://${dsp}/private-aggregation-gcp`;
+ document.body.appendChild(iframeAws);
+ document.body.appendChild(iframeGcp);
});
diff --git a/services/dsp/src/public/js/private-aggregation-aws.js b/services/dsp/src/public/js/private-aggregation-aws.js
new file mode 100644
index 00000000..eb3d14b1
--- /dev/null
+++ b/services/dsp/src/public/js/private-aggregation-aws.js
@@ -0,0 +1,14 @@
+async function runPrivateAggregationAws() {
+ const privateAggCloud = {
+ 'privateAggregationConfig': {
+ 'aggregationCoordinatorOrigin':
+ 'https://publickeyservice.msmt.aws.privacysandboxservices.com',
+ },
+ };
+ await window.sharedStorage.worklet.addModule(
+ 'js/private-aggregation-worklet-aws.js',
+ );
+ await window.sharedStorage.run('test-private-aggregation', privateAggCloud);
+}
+
+runPrivateAggregationAws();
diff --git a/services/dsp/src/public/js/private-aggregation-gcp.js b/services/dsp/src/public/js/private-aggregation-gcp.js
new file mode 100644
index 00000000..cefbb8be
--- /dev/null
+++ b/services/dsp/src/public/js/private-aggregation-gcp.js
@@ -0,0 +1,14 @@
+async function runPrivateAggregationGcp() {
+ const privateAggCloud = {
+ 'privateAggregationConfig': {
+ 'aggregationCoordinatorOrigin':
+ 'https://publickeyservice.msmt.gcp.privacysandboxservices.com',
+ },
+ };
+ await window.sharedStorage.worklet.addModule(
+ 'js/private-aggregation-worklet-gcp.js',
+ );
+ await window.sharedStorage.run('test-private-aggregation', privateAggCloud);
+}
+
+runPrivateAggregationGcp();
diff --git a/services/dsp/src/public/js/private-aggregation-worklet.js b/services/dsp/src/public/js/private-aggregation-worklet-aws.js
similarity index 91%
rename from services/dsp/src/public/js/private-aggregation-worklet.js
rename to services/dsp/src/public/js/private-aggregation-worklet-aws.js
index dfc4b533..6c72ddde 100644
--- a/services/dsp/src/public/js/private-aggregation-worklet.js
+++ b/services/dsp/src/public/js/private-aggregation-worklet-aws.js
@@ -1,6 +1,6 @@
class TestPrivateAggregation {
async run(data) {
- console.log('Enabling Private Aggregation Debug Mode');
+ console.log('Enabling AWS Private Aggregation Debug Mode');
privateAggregation.enableDebugMode({debugKey: 1234n});
let campaignId = await sharedStorage.get('campaignId');
if (!campaignId) {
diff --git a/services/dsp/src/public/js/private-aggregation-worklet-gcp.js b/services/dsp/src/public/js/private-aggregation-worklet-gcp.js
new file mode 100644
index 00000000..586ebd80
--- /dev/null
+++ b/services/dsp/src/public/js/private-aggregation-worklet-gcp.js
@@ -0,0 +1,24 @@
+class TestPrivateAggregation {
+ async run(data) {
+ console.log('Enabling GCP Private Aggregation Debug Mode');
+ privateAggregation.enableDebugMode({debugKey: 1234n});
+ let campaignId = await sharedStorage.get('campaignId');
+ if (!campaignId) {
+ console.log(
+ 'No campaign id found for client. Adding campaignId 1234567890.',
+ );
+ campaignId = '1234567890';
+ sharedStorage.set('campaignId', campaignId);
+ } else {
+ console.log(`Campaign ID found: ${campaignId}`);
+ }
+ function convertToBucket(bucketId) {
+ return BigInt(bucketId);
+ }
+ const bucket = convertToBucket(campaignId);
+ const value = 128;
+ privateAggregation.contributeToHistogram({bucket, value});
+ }
+}
+
+register('test-private-aggregation', TestPrivateAggregation);
diff --git a/services/dsp/src/public/js/private-aggregation.js b/services/dsp/src/public/js/private-aggregation.js
deleted file mode 100644
index e071dc28..00000000
--- a/services/dsp/src/public/js/private-aggregation.js
+++ /dev/null
@@ -1,8 +0,0 @@
-async function runPrivateAggregation() {
- await window.sharedStorage.worklet.addModule(
- 'js/private-aggregation-worklet.js',
- );
- await window.sharedStorage.run('test-private-aggregation');
-}
-
-runPrivateAggregation();
diff --git a/services/dsp/src/views/private-aggregation-aws.ejs b/services/dsp/src/views/private-aggregation-aws.ejs
new file mode 100644
index 00000000..6e29dc87
--- /dev/null
+++ b/services/dsp/src/views/private-aggregation-aws.ejs
@@ -0,0 +1,5 @@
+
+
+
\ No newline at end of file
diff --git a/services/dsp/src/views/private-aggregation-gcp.ejs b/services/dsp/src/views/private-aggregation-gcp.ejs
new file mode 100644
index 00000000..d3c8f54b
--- /dev/null
+++ b/services/dsp/src/views/private-aggregation-gcp.ejs
@@ -0,0 +1,5 @@
+
+
+
\ No newline at end of file
diff --git a/services/dsp/tsconfig.json b/services/dsp/tsconfig.json
index f8c3d840..9c07f0c9 100644
--- a/services/dsp/tsconfig.json
+++ b/services/dsp/tsconfig.json
@@ -8,6 +8,6 @@
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
- "skipLibCheck": true,
- },
+ "skipLibCheck": true
+ }
}
diff --git a/services/home/docs/demos/img/instream-video-ad-hb-time.png b/services/home/docs/demos/img/instream-video-ad-hb-time.png
new file mode 100644
index 00000000..3ffa4214
Binary files /dev/null and b/services/home/docs/demos/img/instream-video-ad-hb-time.png differ
diff --git a/services/home/docs/demos/img/instream-video-ad-ig-time.png b/services/home/docs/demos/img/instream-video-ad-ig-time.png
new file mode 100644
index 00000000..52bc038b
Binary files /dev/null and b/services/home/docs/demos/img/instream-video-ad-ig-time.png differ
diff --git a/services/home/docs/demos/img/instream-video-ad-render-time.png b/services/home/docs/demos/img/instream-video-ad-render-time.png
new file mode 100644
index 00000000..fa81f755
Binary files /dev/null and b/services/home/docs/demos/img/instream-video-ad-render-time.png differ
diff --git a/services/home/docs/demos/instream-video-ad-multi-seller.md b/services/home/docs/demos/instream-video-ad-multi-seller.md
index 36d74be9..e9ed48c0 100644
--- a/services/home/docs/demos/instream-video-ad-multi-seller.md
+++ b/services/home/docs/demos/instream-video-ad-multi-seller.md
@@ -22,6 +22,8 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
+☝️ Use the tabs to navigate to other sections in this document
+
If you have any questions and comments for this instream video ad demo, use
[the instream video ad demo post](https://github.com/privacysandbox/privacy-sandbox-demos/discussions/254) in the Discussions tab.
@@ -185,6 +187,8 @@ DSPA ->> Browser: Add user to Interest Group
Set a render URL with SSP VAST m
DSPB ->> Browser: Add user to Interest Group
Set a render URL with SSP VAST macro (%%SSP_VAST_URL%%)
```
+[Full-sized diagram](./img/instream-video-ad-ig-time.png)
+
#### Header bidding time
This is the time period when the seller defines the macro substitution in the component auction config
@@ -217,6 +221,8 @@ SSPB ->> HB: Respond with the header bid and component auction config
HB ->> AS: Pass the header bidding auction result to the ad server client-side library
```
+[Full-sized diagram](./img/instream-video-ad-hb-time.png)
+
### Ad rendering time
This is the time period when the VAST is transformed and passed to the creative.
@@ -255,33 +261,43 @@ AS ->> VP: The VAST is passed to the video player
VP ->> Publisher: The instream video ad is rendered
```
-## Alternate mechanism
+[Full-sized diagram](.//img/instream-video-ad-render-time.png)
+
+## Alternative approach
In another approach, the SSP can provide the render URL. The DSP sets the following render URL in the IG:
```js
const interestGroup = {
// ...
- ads: [{
- renderUrl: 'https://privacy-sandbox-demos-ssp-a.dev/video-ad.html?dspVastUri=https://privacy-sandbox-demos-dsp-a.dev/preroll.xml',
- }]
+ ads: [
+ {
+ renderUrl: 'https://privacy-sandbox-demos-ssp-a.dev/video-ad.html?dspVastUri=https://privacy-sandbox-demos-dsp-a.dev/preroll.xml',
+ metadata: {
+ seller: 'ssp-a'
+ }
+ },
+ {
+ renderUrl: 'https://privacy-sandbox-demos-ssp-b.dev/video-ad.html?dspVastUri=https://privacy-sandbox-demos-dsp-a.dev/preroll.xml',
+ metadata: {
+ seller: 'ssp-b'
+ }
+ },
+ ]
}
```
- The render URL points to the SSP’s video ad serving endpoint, and the DSP’s VAST URI is added as query params.
- The SSP is now responsible for serving the actual ad that is rendered inside the iframe, and it contains the SSP VAST XML that wraps the DSP VAST
URI.
+ - To support multiple SSPs, the buyer adds a render URL for each SSP. During the bid generation time, the buyer can filter the ads object and return
+ a render URL for the matching seller.
- When that ad wins the auction, the browser makes a request to the render URL which is the SSP's ad serving endpoint `/video-ad.html` with the DSP's
VAST URI set in the query params
- SSP’s HTML document is rendered in the ad iframe and parses the DSP's VAST URI from the query params
- The code inside SSP's video-ad.html wraps the DSP's VAST URI with its own VAST
- The finalized VAST XML is post-messaged out of the creative frame to the video player
-To support multiple SSPs, the SSP's video ad serving endpoint can be substituted with a macro:
-`https://%%SSP_VIDEO_AD%%?dspVastUri=https://privacy-sandbox-demos-dsp-a.dev/preroll.xml` .
-
-We will add a demo for this alternate approach in the future.
-
diff --git a/services/news/tsconfig.json b/services/news/tsconfig.json
index c08cb344..737857ba 100644
--- a/services/news/tsconfig.json
+++ b/services/news/tsconfig.json
@@ -6,7 +6,7 @@
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
- "skipLibCheck": true,
+ "skipLibCheck": true
},
- "exclude": ["src/public"],
+ "exclude": ["src/public"]
}
diff --git a/services/shop/tsconfig.json b/services/shop/tsconfig.json
index ab41abbb..6f91aab8 100644
--- a/services/shop/tsconfig.json
+++ b/services/shop/tsconfig.json
@@ -7,6 +7,6 @@
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
- "skipLibCheck": true,
- },
+ "skipLibCheck": true
+ }
}
diff --git a/services/topics-server/tsconfig.json b/services/topics-server/tsconfig.json
index 115261cf..c7ad80bc 100644
--- a/services/topics-server/tsconfig.json
+++ b/services/topics-server/tsconfig.json
@@ -6,6 +6,6 @@
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
- "skipLibCheck": true,
- },
+ "skipLibCheck": true
+ }
}
diff --git a/services/topics/tsconfig.json b/services/topics/tsconfig.json
index 115261cf..c7ad80bc 100644
--- a/services/topics/tsconfig.json
+++ b/services/topics/tsconfig.json
@@ -6,6 +6,6 @@
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
- "skipLibCheck": true,
- },
+ "skipLibCheck": true
+ }
}
diff --git a/services/travel/tsconfig.json b/services/travel/tsconfig.json
index e21ce02a..ff6e0782 100644
--- a/services/travel/tsconfig.json
+++ b/services/travel/tsconfig.json
@@ -7,6 +7,6 @@
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
- "skipLibCheck": true,
- },
+ "skipLibCheck": true
+ }
}
diff --git a/setup.sh b/setup.sh
new file mode 100644
index 00000000..526ee842
--- /dev/null
+++ b/setup.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+npm install
+
+npm run cert
+
+cd services/home
+
+npm install
+
+npm run build
+
+cd ../..
+
+sudo npm run start