Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AAX Blockmeter RTD Module : Initial Release #9135

Merged
merged 9 commits into from
Oct 26, 2022
3 changes: 2 additions & 1 deletion modules/.submodules.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
],
"rtdModule": [
"1plusXRtdProvider",
"aaxBlockmeterRtdProvider",
"airgridRtdProvider",
"akamaiDapRtdProvider",
"blueconicRtdProvider",
Expand All @@ -77,4 +78,4 @@
"topicsFpdModule"
]
}
}
}
59 changes: 59 additions & 0 deletions modules/aaxBlockmeterRtdProvider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import {isEmptyStr, isStr, logError, isFn, logWarn} from '../src/utils.js';
import {submodule} from '../src/hook.js';
import { loadExternalScript } from '../src/adloader.js';

export const _config = {
MODULE: 'aaxBlockmeter',
ADSERVER_TARGETING_KEY: 'atk',
BLOCKMETER_URL: 'c.aaxads.com/aax.js',
VERSION: '1.2'
};

window.aax = window.aax || {};

function loadBlockmeter(_rtdConfig) {
if (!(_rtdConfig.params && _rtdConfig.params.pub) || !isStr(_rtdConfig.params && _rtdConfig.params.pub) || isEmptyStr(_rtdConfig.params && _rtdConfig.params.pub)) {
logError(`${_config.MODULE}: params.pub should be a string`);
return false;
}

const params = [];
params.push(`pub=${_rtdConfig.params.pub}`);
params.push(`dn=${window.location.hostname}`);

let url = _rtdConfig.params.url;
if (!url || isEmptyStr(url)) {
logWarn(`${_config.MODULE}: params.url is missing, using default url.`);
url = `${_config.BLOCKMETER_URL}?ver=${_config.VERSION}`;
}

const scriptUrl = `https://${url}&${params.join('&')}`;
loadExternalScript(scriptUrl, _config.MODULE);
return true;
}

function markAdBlockInventory(codes, _rtdConfig, _userConsent) {
return codes.reduce((targets, code) => {
targets[code] = targets[code] || {};
const getAaxTargets = () => isFn(window.aax.getTargetingData)
? window.aax.getTargetingData(code, _rtdConfig, _userConsent)
: {};
targets[code] = {
[_config.ADSERVER_TARGETING_KEY]: code,
...getAaxTargets()
};
return targets;
}, {});
}

export const aaxBlockmeterRtdModule = {
name: _config.MODULE,
init: loadBlockmeter,
getTargetingData: markAdBlockInventory,
};

function registerSubModule() {
submodule('realTimeData', aaxBlockmeterRtdModule);
}

registerSubModule();
48 changes: 48 additions & 0 deletions modules/aaxBlockmeterRtdProvider.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
## Overview

Module Name: AAX Blockmeter Realtime Data Module
Module Type: Rtd Provider
Maintainer: product@aax.media

## Description

The module enables publishers to measure traffic coming from visitors using adblockers.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this requires an account with AAX yes? Might be better to state that here, as it doesn't look like the module itself does much more than load the AAX script.


AAX can also help publishers monetize this traffic by allowing them to serve [acceptable ads](https://acceptableads.com/about/) to these adblock visitors and recover their lost revenue. [Reach out to us](https://www.aax.media/try-blockmeter/) to know more.

## Integration

Build the AAX Blockmeter Realtime Data Module into the Prebid.js package with:

```
gulp build --modules=aaxBlockmeterRtdProvider,rtdModule
```

## Configuration

This module is configured as part of the `realTimeData.dataProviders` object.

| Name | Scope | Description | Example | Type |
|:----------:|:--------:|:-----------------------------|:---------------:|:------:|
| `name` | required | Real time data module name | `'aaxBlockmeter'` | `string` |
| `params` | required | | | `Object` |
| `params.pub` | required | AAX to share pub ID, [Reach out to us](https://www.aax.media/try-blockmeter/) to know more! | `'AAX00000'` | `string` |
| `params.url` | optional | AAX Blockmeter Script Url. Defaults to `'c.aaxads.com/aax.js?ver=1.2'` | `'c.aaxads.com/aax.js?ver=1.2'` | `string` |

### Example

```javascript
pbjs.setConfig({
"realTimeData": {
"dataProviders": [
{
"name": "aaxBlockmeter",
"params": {
"pub": "AAX00000",
"url": "c.aaxads.com/aax.js?ver=1.2",
}
}
]
}
})
```
3 changes: 2 additions & 1 deletion src/adloader.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ const _approvedLoadExternalJSList = [
'inskin',
'hadron',
'medianet',
'improvedigital'
'improvedigital',
'aaxBlockmeter'
]

/**
Expand Down
58 changes: 58 additions & 0 deletions test/spec/modules/aaxBlockmeter_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import {aaxBlockmeterRtdModule} from '../../../modules/aaxBlockmeterRtdProvider.js';
import * as sinon from 'sinon';
import {assert} from 'chai';

let sandbox;
let getTargetingDataSpy;

const config = {
dataProviders: [{
'name': 'aaxBlockmeter',
'params': {
'pub': 'publisher_id',
}
}]
};

describe('aaxBlockmeter realtime module', function () {
beforeEach(function () {
sandbox = sinon.sandbox.create();
window.aax = window.aax || {};
window.aax.getTargetingData = getTargetingDataSpy = sandbox.spy();
});

afterEach(function () {
sandbox.restore();
window.aax = {};
});

it('init should return false when config is empty', function () {
assert.equal(aaxBlockmeterRtdModule.init({}), false);
});

it('init should return false when config.params id is empty', function () {
assert.equal(aaxBlockmeterRtdModule.init({params: {}}), false);
});

it('init should return true when config.params.pub is not string', function () {
assert.equal(aaxBlockmeterRtdModule.init({params: {pub: 12345}}), false);
});

it('init should return true when config.params.pub id is passed and is string typed', function () {
assert.equal(aaxBlockmeterRtdModule.init(config.dataProviders[0]), true);
});

describe('getTargetingData should work correctly', function () {
it('should return ad unit codes when ad units are present', function () {
const codes = ['code1', 'code2'];
assert.deepEqual(aaxBlockmeterRtdModule.getTargetingData(codes), {
code1: {'atk': 'code1'},
code2: {'atk': 'code2'},
});
});

it('should call aax.getTargetingData if loaded', function () {
aaxBlockmeterRtdModule.getTargetingData([], config.dataProviders[0], null);
});
});
});