Skip to content
This repository has been archived by the owner on Mar 27, 2024. It is now read-only.

Commit

Permalink
Merge pull request #54 from AirGrid/release/v0.0.0-dev.13
Browse files Browse the repository at this point in the history
release: v0.0.0-dev.13 MASTER
  • Loading branch information
ydennisy authored Sep 23, 2020
2 parents eca0c70 + ea1027e commit f178abe
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 113 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-test-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:

build-and-publish:
name: Publish to NPM
if: ${{ github.event_name == 'release' && endsWith(github.ref, '/master') }}
if: ${{ github.event_name == 'release' }}
needs: build-and-test
runs-on: ubuntu-latest

Expand Down
118 changes: 27 additions & 91 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,75 +71,60 @@ _Note: using the above URLs will always fetch the latest version, which could co

## Usage 🤓

### Full Flow
### Summary

EdgeKit will execute the following high level flow:

1. **Check for GDPR compliance.**
The IAB has an [API](https://cdn.edkt.io/sdk/edgekit.min.js) to check for GDPR compliance.
Edgekit provides a simplified wrapper around this API in order to check for compliance. A list of
vendor ids is passed to the function.

You can find the list of vendors and their ids that are participating in the Transparency and
Consent Framework [here](https://iabeurope.eu/vendor-list-tcf-v2-0/).

Quoting the definition from [IAB policy site](https://cdn.edkt.io/sdk/edgekit.min.js), a vendor
is:

> “Vendor” means a company that participates in the delivery of digital advertising within a Publisher’s website, app, or other digital content, to the extent that company is not acting as a Publisher or CMP, and that either accesses an end user’s device or processes personal data about end users visiting the Publisher’s content and adheres to the Policies...
2. **Register, run and store user defined `pageFeatureGetters`.**
In this step the library will fetch `keywords` to describe the current page load, which will be stored locally to create a history of the pages viewed by the user visiting your site.
In this step the library will run getters that fetch page features describing the current page load, which will be stored locally to create a history of the pages viewed by the user visiting your site.
3. **Run audience definitions against the local page views.**
The library now checks the users local history to see if they match any of the audience definitions, storing any matched audiences.
4. **Make matched audiences available to bidding.**
The final step is to pass the newly defined audience signals to third party bidders, for example via Prebid.

#### Page Features

A page feature is a list of keywords that describe a pages content.
### Full Flow

EdgeKit requires pageFeatureGetters to be passed into the run method that will allow EdgeKit to evaluate the page. A pageFeatureGetter is an object that has a name and and an async function that resolves to a keyword list.
#### Page Feature Getters

```typescript
const examplePageFeatureGetter = {
name: 'example',
func: (): Promise<string[]> => { ... }
}
```
A page feature is a value that describe a pages content. The features can be something concrete like
a list of keywords on a page, or something more abstract like a vector. [Learn
more](./docs/features.md)

The following is a working example of a pageFeatureGetter that gets the meta data keywords from the head of the HTML.

##### HTML
#### Audience Definitions

```html
<meta name="keywords" content="goal,liverpool,football,stadium" />
```
In EdgeKit an audience refers to a group of users you would like to identify based on a feature, the
frequency of the user seeing the feature and how long ago or recently they saw it. [Learn
more](./docs/audiences.md)

##### JS pageFeatureGetter

```typescript
const getHtmlKeywords = {
name: 'keywords',
func: (): Promise<string[]> => {
const tag = <HTMLElement>(
document.head.querySelector('meta[name="keywords"]')
);
const keywordString = tag.getAttribute('content') || '';
const keywords = keywordString.toLowerCase().split(',');
return Promise.resolve(keywords);
},
};
```
#### Vendor Ids

Vendors are companies that are participating in the Transparency and Consent Framework. Quoting the
definition from [IAB policy site](https://iabeurope.eu/iab-europe-transparency-consent-framework-policies), a vendor is:

> “Vendor” means a company that participates in the delivery of digital advertising within a Publisher’s website, app, or other digital content, to the extent that company is not acting as a Publisher or CMP, and that either accesses an end user’s device or processes personal data about end users visiting the Publisher’s content and adheres to the Policies...
You can find the list of vendors (including `Airgrid LTD`) and their ids
[here](https://iabeurope.eu/vendor-list-tcf-v2-0/).


#### Running Edgekit

##### JS EdgeKit Run
Edgekit is run by calling the `edkt.run` function with page feature getters, audience definitions
and vendor ids:

```typescript
import { edkt } from '@airgrid/edgekit';

// If GDPR applies and consent has not been established then this function won't do anything
edkt.run({
pageFeatureGetters: [getHtmlKeywords],
pageFeatureGetters: ...,
audienceDefinitions: ...,
vendorIds: ..., // vendor ids to check for consent
});
Expand All @@ -149,61 +134,12 @@ Alternatively, pass in a flag to omit the GDPR check if it's not necessary for y

```typescript
edkt.run({
pageFeatureGetters: [getHtmlKeywords],
pageFeatureGetters: ...,
audienceDefinitions: ...,
omitGdprConsent: true
});
```

#### Audience Evaluation

In EdgeKit an audience refers to a group of users you would like to identify based on a list of keywords, the frequency of the user seeing one of the keywords and how long ago or recently they saw it.

```typescript
export const exampleAudience: AudienceDefinition = {
// Unique Identifier
id: '1234',
// Name of the Audience
name: 'Interest | typeOfIntrest',
// Time To Live - How long after matching the Audience are you part of it
ttl: TTL_IN_SECS,
// How long into the past should EdgeKit Look to match you to the audience
lookBack: LOOK_BACK_IN_SECS,
// Number of times the pageFeatureGetter must match a keyword to the keywords listed below
occurrences: OCCURRENCES,
// The version number of the audience for caching
version: 1,
// The query property to look up, this is the name of the key that will be looked up in the stored page view features object
queryProperty: 'keywords',
// The name of the function to use for filtering the page view features
queryFilterComparisonType: 'arrayIntersects',
// The value to pass into the function determined by the queryFilterComparisonType along with the page view feature (if it exists)
queryValue: ['sport', 'football'],
};
```

EdgeKit comes with a range of audiences that you can use as examples or to get started straight away in your application.

To use the the built in audiences you can import them from EdgeKit along with 'edkt'

```typescript
// use all built in audiences
import { edkt, allAudienceDefinitions } from '@airgrid/edgekit';

edkt.run({
pageFeatureGetters: [...],
audienceDefinitions: allAudienceDefinitions,
});

// use only the built in sport audience
import { edkt, sportInterestAudience } from '@airgrid/edgekit';

edkt.run({
pageFeatureGetters: [...],
audienceDefinitions: [sportInterestAudience],
});

```

#### Bidding Integration

Expand Down
116 changes: 96 additions & 20 deletions docs/audiences.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
# EdgeKit | Audiences
# EdgeKit | Audience Definitions

In EdgeKit an audience refers to a group of users you would like to identify based on a list of keywords, the frequency of the user seeing one of the keywords and how long ago or recently they saw it.
In EdgeKit an audience refers to a group of users you would like to identify based on a feature, the
frequency of the user seeing the feature and how long ago or recently they saw it.

## Usage

Suppose that Edgekit is run with the page feature getters in the example from the [features
doc](./features.md) and the following audience definition:

```typescript
const TTL_IN_SECS = 60 * 60 * 24; // 1 day in seconds
const LOOK_BACK_IN_SECS = 60 * 60 * 24 * 7; // 1 week in seconds
const OCCURRENCES = 2;

export const exampleAudience: AudienceDefinition = {
// Unique Identifier
id: '1234',
Expand All @@ -17,7 +25,7 @@ export const exampleAudience: AudienceDefinition = {
// Number of times the pageFeatureGetter must match a keyword to the keywords listed below
occurrences: OCCURRENCES,
// The version number of the audience for caching
version: 1
version: 1,
// The query property to look up, this is the name of the key that will be looked up in the stored page view features object
queryProperty: 'keywords',
// The name of the function to use for filtering the page view features
Expand All @@ -27,9 +35,93 @@ export const exampleAudience: AudienceDefinition = {
};
```


### What the engine will do


#### 1. Filter the page views

The engine will filter the page views based on the provided `query*` values in the audience definition:

##### Audience Definition `queryProperty`

The `queryProperty` is set to `keywords`, so it will look up the features object on the stored
page views to see if there is a feature with this name.

Since this example will run the feature getter from the [features doc](./features.md), the
page views will look something like:

```js
> JSON.parse(localStorage.getItem('edkt_page_views'))
[
{
"ts": 1600858202179,
"features": {
"keywords": [
"goal",
"liverpool",
"football",
"stadium"
]
}
}
]
```

And since `queryProperty` is set to `'keywords'`, it will look up `features[queryProperty]` on each
page view and in this case return:

```js
['goal', 'liverpool', 'football', 'stadium']
```


##### Audience Definition `queryFilterComparisonType` and `queryValue`

The engine will run the query filter function `arrayIntersects` (the `queryFilterComparisonType`)
on the fetched features and the values provided by `queryValue`.

For this example, the filter will look something like this:

```js
features.arrayIntersects(['goal', 'liverpool', 'football', 'stadium'], ['sport', 'football'])
```

The `arrayIntersects` filter function checks if there is a set intersection. The two sets do
intersect in this case (`['football']`) so there is a match.

#### 2. Check if there are _enough_ filtered page views

In the second step, the engine will check if there are _enough_ of the filtered page views to match
on the audience definition

In this case, the audience definition sets the number of `occurrences` to _2_ and the `lookBack` to
_1 week_, which means that there should be _more than 2_ of these filtered page views _in the past
week_ in order to match on this audience definition.

The `ttl` provided for this defintion says the the match is only good for _1 day_.


## Passing Matched Audiences to a Bidder

The matched audience definitions are stored in local storage under `edkt_matched_audiences`. These
definitions can be sent to a bidder such as Prebid.


## Built in Audiences

EdgeKit comes with a range of audiences that you can use as examples or to get started straight away in your application.

To use the the built in audiences you can import them from EdgeKit along with 'edkt'
the following audiences are built into edkt and can be used in your projects.

```typescript
import { sportInterestAudience,
travelInterestAudience,
automotiveInterestAudience } from '@airgrid/edgekit';
```

For example:

```typescript
// use all built in audiences
Expand All @@ -50,20 +142,4 @@ edkt.run({

```

## Built in Audiences

the following audiences are built into edkt and can be used in your projects.

```typescript
import { sportInterestAudience,
travelInterestAudience,
automotiveInterestAudience } from '@airgrid/edgekit';
```

The following audiences

* sportInterestAudience
* travelInterestAudience
* automotiveInterestAudience

for a full list of keywords see ```src/audiences/interest/.../keywords.ts```
For a full list of keywords see [```src/audiences/interest/.../keywords.ts```](https://github.com/AirGrid/edgekit/blob/develop/src/audiences/interest/sport/keywords.ts) for each built-in definition.
69 changes: 69 additions & 0 deletions docs/features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# EdgeKit | Page Features

A page feature is a value that describes a pages content. The features can be something concrete
like a list of keywords on a page, or something more abstract like a vector.

EdgeKit requires `pageFeatureGetters` to be passed into the run method that will allow EdgeKit to
evaluate the page. A page feature getter is an object that has a name and and an async function that
resolves to a value.


## Example

The following is a working example of a `pageFeatureGetter` that gets the meta data keywords from
the head of the HTML:

```typescript
const getHtmlKeywords = {
name: 'keywords',
func: (): Promise<string[]> => {
const tag = <HTMLElement>(
document.head.querySelector('meta[name="keywords"]')
);
const keywordString = tag.getAttribute('content') || '';
const keywords = keywordString.toLowerCase().split(',');
return Promise.resolve(keywords);
},
};
```

If this `getHtmlKeywords` feature getter is passed to Edgekit with a page that looks like this:

```html
<html>
<head>
<meta name="keywords" content="goal,liverpool,football,stadium" />
...
</head>
<body>
...
</body>
</html>
```

Then Edgekit will store this feature, and any other features that were provided, in local storage as
a _page view_:

```js
> JSON.parse(localStorage.getItem('edkt_page_views'))
[
{
"ts": 1600858202179,
"features": {
"keywords": [
"goal",
"liverpool",
"football",
"stadium"
]
}
}
]
```

The `name` that was provided in the page feature getter definition is the key where it will be
stored in the features object (in this case `keywords`).

The audience definitions that are passed into Edgekit define whether or not the page views match the
audience. If any of the audiences match then they will also get stored in local storage. [Learn
more about audiences](./audiences.md)
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@airgrid/edgekit",
"version": "0.0.0-dev.12",
"version": "0.0.0-dev.13",
"homepage": "https://edgekit.org/",
"author": "AirGrid <https://airgrid.io>",
"license": "MIT",
Expand Down

0 comments on commit f178abe

Please sign in to comment.