|
12 | 12 | - [Examples](#examples)
|
13 | 13 | - [Protected Audience reporting](#protected-audience-reporting)
|
14 | 14 | - [Measuring user demographics with cross-site information](#measuring-user-demographics-with-cross-site-information)
|
| 15 | + - [Cross-site reach measurement](#cross-site-reach-measurement) |
| 16 | + - [K+ frequency measurement](#k-frequency-measurement) |
15 | 17 | - [Goals](#goals)
|
16 | 18 | - [Non-goals](#non-goals)
|
17 | 19 | - [Operations](#operations)
|
@@ -193,6 +195,57 @@ class SendDemoReportOperation {
|
193 | 195 | register("send-demo-report", SendDemoReportOperation);
|
194 | 196 | ```
|
195 | 197 |
|
| 198 | +### Cross-site reach measurement |
| 199 | + |
| 200 | +Measuring the number of users that have seen an ad. |
| 201 | + |
| 202 | +In the ad’s iframe: |
| 203 | + |
| 204 | +```js |
| 205 | +await window.sharedStorage.worklet.addModule('reach.js'); |
| 206 | +await window.sharedStorage.run('send-reach-report', { |
| 207 | + // optional one-time context |
| 208 | + data: { campaignId: '1234' }, |
| 209 | +}); |
| 210 | +``` |
| 211 | + |
| 212 | +Worklet script (i.e. `reach.js`): |
| 213 | + |
| 214 | +```js |
| 215 | +class SendReachReportOperation { |
| 216 | + async run(data) { |
| 217 | + const reportSentForCampaign = `report-sent-${data.campaignId}`; |
| 218 | + |
| 219 | + // Compute reach only for users who haven't previously had a report sent for |
| 220 | + // this campaign. Users who had a report for this campaign triggered by a |
| 221 | + // site other than the current one will be skipped. |
| 222 | + if (await sharedStorage.get(reportSentForCampaign) === 'yes') { |
| 223 | + return; // Don't send a report. |
| 224 | + } |
| 225 | + |
| 226 | + // The user agent will send the report to a default endpoint after a delay. |
| 227 | + privateAggregation.contributeToHistogram({ |
| 228 | + bucket: data.campaignId, |
| 229 | + value: 128, // A predetermined fixed value; see Scaling values. |
| 230 | + }); |
| 231 | + |
| 232 | + await sharedStorage.set(reportSentForCampaign, 'yes'); |
| 233 | + } |
| 234 | +} |
| 235 | +register('send-reach-report', SendReachReportOperation); |
| 236 | +``` |
| 237 | + |
| 238 | +### _K_+ frequency measurement |
| 239 | + |
| 240 | +By instead maintaining a counter in shared storage, the approach for cross-site |
| 241 | +reach measurement could be extended to _K_+ frequency measurement, i.e. |
| 242 | +measuring the number of users who have seen _K_ or more ads on a given browser, |
| 243 | +for a pre-chosen value of _K_. A unary counter can be maintained by calling |
| 244 | +`window.sharedStorage.append("freq", "1")` on each ad view. Then, the |
| 245 | +`send-reach-report` operation would only send a report if there are more than |
| 246 | +_K_ characters stored at the key `"freq"`. This counter could also be used to |
| 247 | +filter out ads that have been shown too frequently. |
| 248 | + |
196 | 249 | ## Goals
|
197 | 250 |
|
198 | 251 | This API aims to support a wide range of aggregation use cases, including
|
@@ -425,7 +478,7 @@ service deployed on AWS, GCP, and other platforms in the future. The specified
|
425 | 478 | origin would need to be on an allowlist maintained by the browser. If none is
|
426 | 479 | specified, a default will be used.
|
427 | 480 |
|
428 |
| -This allowlist matches the Attribution Reporting API's, available |
| 481 | +This allowlist matches the Attribution Reporting API's, available |
429 | 482 | [here](https://github.com/WICG/attribution-reporting-api/blob/main/aggregation_coordinator_origin_allowlist.md).
|
430 | 483 |
|
431 | 484 | Shared Storage callers would specify this field when calling the `run()` or
|
|
0 commit comments