Skip to content

Commit

Permalink
Merge pull request #6 from microsoft/service_alignment_updates
Browse files Browse the repository at this point in the history
Update polyfill to align with prototype service updates.
  • Loading branch information
Brandr0id authored May 20, 2021
2 parents 179d857 + d3d33c8 commit cb17c7a
Show file tree
Hide file tree
Showing 11 changed files with 401 additions and 130 deletions.
5 changes: 5 additions & 0 deletions Polyfill/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.vs/
Release/
bin/
node_modules/
obj/
1 change: 1 addition & 0 deletions Polyfill/Parakeet Polyfill.njsproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
</Content>
</ItemGroup>
<ItemGroup>
<TypeScriptCompile Include="lib\Geo.ts" />
<TypeScriptCompile Include="lib\InterestGroups.ts" />
<TypeScriptCompile Include="lib\AdInterests.ts" />
<TypeScriptCompile Include="lib\AdProperties.ts" />
Expand Down
10 changes: 10 additions & 0 deletions Polyfill/Parakeet.Polyfill.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import { AdProperties } from './lib/AdProperties';
import { AdTargeting } from './lib/AdTargeting';
import { AdRequestConfig } from './lib/AdRequestConfig';
import { Geo } from './lib/Geo';

// Imports for joining interest groups.
import { AdInterests } from './lib/AdInterests';
Expand All @@ -38,6 +39,11 @@ declare global {
new(other?: AdTargeting): AdTargeting;
};

var Geo: {
prototype: Geo;
new(other?: Geo): Geo;
};

var AdRequestConfig: {
prototype: AdRequestConfig;
new(other?: AdRequestConfig): AdRequestConfig;
Expand Down Expand Up @@ -66,6 +72,10 @@ if (!globalThis.AdTargeting) {
globalThis.AdTargeting = AdTargeting;
}

if (!globalThis.Geo) {
globalThis.Geo = Geo;
}

if (!globalThis.AdRequestConfig) {
globalThis.AdRequestConfig = AdRequestConfig;
}
Expand Down
24 changes: 19 additions & 5 deletions Polyfill/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ flow:
- [AdRequestConfig](#adrequestconfig)
- [AdTargeting](#adtargeting)
- [AnonymizedSignals](#anonymizedsignals)
- [Geo](#geo)
- [Methods](#methods)
- [Navigator.createAdRequest](#navigatorcreateadrequest)
- [Navigator.joinParakeetInterestGroup](#navigatorjoinparakeetinterestgroup)
Expand Down Expand Up @@ -184,7 +185,20 @@ export class AdTargeting {
// contextual signals made available at the time of the request.
interests?: string[];
// Geolocation information the requesting site may be aware of.
geolocation?: number[];
geolocation?: Geo;
}
```

###### Geo
Intended to represent the geolocation data for the desired ad. This is built to
follow the [OpenRTB](https://developers.google.com/authorized-buyers/rtb/openrtb-guide#geo)
Geo data format.
```typescript
export class Geo {
// Latitude from -90.0 to +90.0, where negative is south.
lat?: number;
// Longitude from -180.0 to +180.0, where negative is west.
lon?: number;
}
```

Expand Down Expand Up @@ -376,10 +390,10 @@ navigator.createAdRequest({
"Lawn Mowers",
"Shoes"
],
"geolocation": [
47.6397316,
-122.1419026
]
"geolocation": {
"lat": 47.6397316,
"lon": -122.1419026
}
},
"anonymizedProxiedSignals": [
"coarse-geolocation",
Expand Down
13 changes: 3 additions & 10 deletions Polyfill/lib/AdRequestConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,9 @@ export class AdRequestConfig {
}

toRequestBody(): string {
let json = JSON.stringify(this);
// Modify our properties to match the service expectations.
json = json.replace('proxiedAnonymizingOrigin', 'proxied-anonymizing-origin');
json = json.replace('adProperties', 'ad-properties');
json = json.replace('publisherCode', 'publisher-code');
json = json.replace('publisherAdUnit', 'publisher-ad-unit');
json = json.replace('anonymizedProxiedSignals', 'anonymized-proxied-signals');
json = json.replace('fallbackSource', 'fallback-source');

return json;
// Currently no special processing is required so we can simply stringify
// this object and return as-is.
return JSON.stringify(this);
}

// Stores any joined AdInterests, not setable by callers and will be
Expand Down
10 changes: 6 additions & 4 deletions Polyfill/lib/AdTargeting.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// Copyright (C) Microsoft Corporation. All rights reserved.

import { Geo } from './Geo';

export class AdTargeting {
/**
* A list of interests specific to a given ad request. These may include
Expand All @@ -9,18 +11,18 @@ export class AdTargeting {
/**
* Geolocation information the requesting site may be aware of.
*/
geolocation?: number[];
geolocation?: Geo;

constructor(other?: AdTargeting) {
if (other) {
this.interests = Array.isArray(other.interests) ? other.interests.slice() : [];
this.geolocation = Array.isArray(other.geolocation) ? other.geolocation.slice() : [];
this.geolocation = new Geo(other.geolocation);
} else {
this.interests = [];
this.geolocation = [];
this.geolocation = new Geo();
}
}
}

AdTargeting.prototype.interests = [];
AdTargeting.prototype.geolocation = [];
AdTargeting.prototype.geolocation = Geo.prototype;
27 changes: 27 additions & 0 deletions Polyfill/lib/Geo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (C) Microsoft Corporation. All rights reserved.

// Representations of relevant Geo fields. This should reflect the OpenRTB
// schema: https://developers.google.com/authorized-buyers/rtb/openrtb-guide#geo
export class Geo {
/**
* Latitude from -90.0 to +90.0, where negative is south.
*/
lat?: number;
/**
* Longitude from -180.0 to +180.0, where negative is west.
*/
lon?: number;

constructor(other?: Geo) {
if (other) {
this.lat = other.lat;
this.lon = other.lon;
} else {
this.lat = undefined;
this.lon = undefined;
}
}
}

Geo.prototype.lat = undefined;
Geo.prototype.lon = undefined;
39 changes: 36 additions & 3 deletions Polyfill/lib/InterestGroups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,47 @@ export function GetInterestGroups() {
throw new TypeError("Error retrieving stored interests. Clear localStorage.");
}

// We want to generate a format for PARAKEET to be able to process per-reader.
// e.g.
// reader1: {
// interests: {
// origin1: [interest1, interest2, ...],
// origin2: [interest1, interestA, ...],
// }
// },
// reader2: {
// ...

let joinedInterests: { [x: string]: { [x: string]: { [x: string]: string[]; }; }; } = {};
const currentTimeInSeconds = (new Date().getTime() / 1000);
Object.keys(storedInterests).forEach(function (namespacedInterestGroup) {
Object.keys(storedInterests[namespacedInterestGroup]["interests"]).forEach(function (interest: string) {
if (storedInterests[namespacedInterestGroup]["interests"][interest].expiration <= currentTimeInSeconds) {
storedInterests[namespacedInterestGroup]["interests"][interest] = {};
// If this specific interest is not yet expired we can add it to our list.
if (storedInterests[namespacedInterestGroup]["interests"][interest].expiration > currentTimeInSeconds) {
// Make sure to add this for each reader specified.
Object.keys(storedInterests[namespacedInterestGroup]["interests"][interest].readers).forEach(function (reader) {
const readerName = storedInterests[namespacedInterestGroup]["interests"][interest].readers[reader];
// Ensure our root reader node exists.
if (!joinedInterests[readerName]) {
joinedInterests[readerName] = {};
}

// Ensure we have an 'interests' index to look/add to.
if (!joinedInterests[readerName]["interests"]) {
joinedInterests[readerName]["interests"] = {};
}

// This may be the first time we're seeing this specific origin, so ensure it is available.
if (!joinedInterests[readerName]["interests"][namespacedInterestGroup]) {
joinedInterests[readerName]["interests"][namespacedInterestGroup] = [];
}

// Now add this interest within the origin (namespace) for the given reader.
joinedInterests[readerName]["interests"][namespacedInterestGroup].push(interest);
});
}
});
});

return storedInterests;
return joinedInterests;
}
Loading

0 comments on commit cb17c7a

Please sign in to comment.