Skip to content

Commit

Permalink
Update GPT Endpoint + Adding Logging #72
Browse files Browse the repository at this point in the history
  • Loading branch information
Neal Malkani authored Mar 5, 2021
2 parents 650eced + b925b6a commit 2655b06
Show file tree
Hide file tree
Showing 10 changed files with 3,363 additions and 3,365 deletions.
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -434,21 +434,23 @@ NOTE: Prebid is supported for SRA. Amazon A9/TAM is not supported for SRA and w
NOTE: ArcAds SRA implementation calls enableSingleRequest() which means that when using pubads lazyLoad functions together with SRA, when the first ad slot comes within the viewport specified by the fetchMarginPercent parameter, the call for that ad and all other ad slots is made. If different behavior is desired after the initial SRA call is made, an outside lazy loading library may be used to manage the calls for regsterAd, reserveAd and other calls.
## Developer Tools
There's a series developer tools available, to get started run `yarn install`.
There's a series developer tools available, to get started run `npm install`.
| Command | Description |
| ------------- | ------------- |
| `yarn dev` | Runs the development command, watches for changes and compiles the changes down to the `dist` directory. |
| `yarn build` | Builds the project into the `dist` directory with minification. |
| `yarn docs` | Generates ESDoc documentation in the `docs` directory on-demand. |
| `yarn test` | Runs a series of unit tests with Jest. Tests are automatically validated during a pull request. |
| `yarn debug` | Starts a local http server so you can link directly to the script during development. For example `<script src="http://localhost:9000/dist/arcads.js"></script> |
| `npm run dev` | Runs the development command, watches for changes and compiles the changes down to the `dist` directory. |
| `npm run build` | Builds the project into the `dist` directory with minification. |
| `npm run docs` | Generates ESDoc documentation in the `docs` directory on-demand. |
| `npm run test` | Runs a series of unit tests with Jest. Tests are automatically validated during a pull request. |
| `npm run debug` | Starts a local http server so you can link directly to the script during development. For example `<script src="http://localhost:9000/dist/arcads.js"></script> |

### Slot Override
You can override the slot name of every advertisement on the page by appending `?adslot=` to the URL. This will override whatever is placed inside of the `slotName` field when invoking the `registerAd` method. For example, if you hit the URL `arcpublishing.com/?adslot=homepage/myad`, the full ad slot path will end up being your DFP id followed by the value: `123/homepage/myad`.

You can also debug slot names and GPT in general by typing `window.googletag.openConsole()` into the browsers developer console.

### Logging
To inspect the funtion calls taking place within the ArcAds library, you can include the `debug=true` query parameter on your page.

## Contributing
If you'd like to contribute to ArcAds please read our [contributing guide](https://github.com/washingtonpost/ArcAds/blob/master/CONTRIBUTING.md).
2 changes: 1 addition & 1 deletion dist/arcads.js

Large diffs are not rendered by default.

6,627 changes: 3,273 additions & 3,354 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "arcads",
"version": "2.0.2",
"version": "3.0.0",
"description": "ArcAds is a DFP wrapper created by Arc Publishing with publishers in mind.",
"main": "dist/arcads.js",
"scripts": {
Expand Down Expand Up @@ -50,6 +50,8 @@
"webpack-cli": "^3.0.8"
},
"dependencies": {
"anylogger": "^1.0.10",
"anylogger-console": "^1.0.0",
"esdoc": "^1.0.4",
"esdoc-standard-plugin": "^1.0.0",
"promise-polyfill": "^8.0.0"
Expand Down
34 changes: 34 additions & 0 deletions src/__tests__/util.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import anylogger from 'anylogger';
import 'anylogger-console';
import { renamePositionKey } from '../util/customTargeting';
import {debounce} from '../util/debounce.js';
import {sendLog} from '../util/log.js';

describe('The CustomTargeting.js functions', () => {
it('should take targeting and position value, and rename the key as posn', () => {
Expand Down Expand Up @@ -48,3 +51,34 @@ describe('debounce', () => {
expect(func).toHaveBeenCalledTimes(1);
});
});

describe('sendLog', () => {

test('sendLog', () => {
const location = {
...window.location,
search: '?debug=true'
};

Object.defineProperty(window, 'location', {
writable: true,
value: location
});

const DATE_TO_USE = new Date('Thu Feb 04 2021 11:04:05 GMT-0500');
global.Date = jest.fn(() => DATE_TO_USE);
anylogger.log = jest.fn();
sendLog('testFunc()', 'a test of the send log', null);
setTimeout(() => {
expect(anylogger.log).toHaveBeenCalledWith('arcads.js', [{"description": "a test of the send log", "logging from": "testFunc()", "service": "ArcAds", "slotName": null, "timestamp": "Thu Feb 04 2021 11:04:05 GMT-0500 (Eastern Standard Time)"}]);
}, 500);
});

test('sendLog if window undefined', () => {
delete global.window;
sendLog('testFunc()', 'a test of the send log', null);
setTimeout(() => {
expect(console.error).toHaveBeenCalled();
}, 500);
});
});
13 changes: 11 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { MobileDetection } from './util/mobile';
import { sendLog } from './util/log';
import { fetchBids, initializeBiddingServices } from './services/headerbidding';
import { initializeGPT, queueGoogletagCommand, refreshSlot, dfpSettings, setTargeting, determineSlotName } from './services/gpt';
import { queuePrebidCommand, addUnit } from './services/prebid';
Expand All @@ -18,7 +19,6 @@ export class ArcAds {
this.positions = [];
this.collapseEmptyDivs = options.dfp.collapseEmptyDivs;
this.adsList = [];

window.isMobile = MobileDetection;

if (this.dfpId === '') {
Expand All @@ -27,6 +27,7 @@ export class ArcAds {
'\n',
'Documentation: https://github.com/wapopartners/arc-ads#getting-started'
);
sendLog('constructor()', 'The DFP id missing from the arcads initialization script. ArcAds cannot proceed.', null);
} else {
initializeGPT();
queueGoogletagCommand(dfpSettings.bind(this, handleSlotRendered));
Expand Down Expand Up @@ -91,6 +92,7 @@ export class ArcAds {

processDisplayAd = this.displayAd.bind(this, params);
if (processDisplayAd) {
sendLog('registerAd()', 'Queuing Google Tag command for ad', slotName);
queueGoogletagCommand(processDisplayAd);
}
}
Expand All @@ -114,6 +116,9 @@ export class ArcAds {
* @param {array} collection - An array containing a list of objects containing advertisement data.
**/
registerAdCollectionSingleCall(collection, bidderTimeout = 700) {
sendLog('registerAdCollectionSingleCall()', 'Registering all reserved ads', null);


window.blockArcAdsLoad = true;
window.blockArcAdsPrebid = true;

Expand Down Expand Up @@ -186,17 +191,18 @@ export class ArcAds {
const ad = !dimensions ? window.googletag.defineOutOfPageSlot(fullSlotName, id)
: window.googletag.defineSlot(fullSlotName, parsedDimensions, id);


if (sizemap && sizemap.breakpoints && dimensions) {
const { mapping, breakpoints, correlators } = prepareSizeMaps(parsedDimensions, sizemap.breakpoints);

if (ad) {
ad.defineSizeMapping(mapping);
} else {
sendLog('displayAd()', 'No ad available to display - the div was either not defined or an ad with the same slot name already exists on the page', slotName);
return false;
}

if (sizemap.refresh) {
sendLog('displayAd()', 'Attaching resize listener to the ad with this slot name and sizemap defined', slotName);
setResizeListener({
ad,
slotName: fullSlotName,
Expand All @@ -223,6 +229,7 @@ export class ArcAds {
}

if (dimensions && bidding && ((bidding.amazon && bidding.amazon.enabled) || (bidding.prebid && bidding.prebid.enabled))) {
sendLog('displayAd()', 'Fetching bids for ad with this slot name', slotName);
fetchBids({
ad,
id,
Expand All @@ -234,6 +241,7 @@ export class ArcAds {
breakpoints: safebreakpoints
});
} else if (!window.blockArcAdsPrebid) {
sendLog('displayAd()', 'Refreshing ad with this slot name', slotName);
refreshSlot({
ad,
prerender,
Expand All @@ -254,6 +262,7 @@ export class ArcAds {
// if no ads have been accumulated to send out together
// do nothing, return
if (this.adsList && this.adsList.length < 1) {
sendLog('sendSingleCallAds()', 'No ads have been reserved on the page', null);
return false;
}
//ensure library is present and able to send out SRA ads
Expand Down
6 changes: 5 additions & 1 deletion src/services/gpt.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { appendResource } from '../util/resources';
import { expandQueryString } from '../util/query';
import { sendLog } from '../util/log';

/**
* @desc Initializes the Google Publisher tag scripts.
Expand All @@ -8,7 +9,8 @@ export function initializeGPT() {
window.googletag = window.googletag || {};
window.googletag.cmd = window.googletag.cmd || [];

appendResource('script', '//www.googletagservices.com/tag/js/gpt.js', true, true);
appendResource('script', '//securepubads.g.doubleclick.net/tag/js/gpt.js', true, true);
sendLog('initializeGPT()', 'Appended googletag script to the head tag of the page.', null);
}

/**
Expand Down Expand Up @@ -86,11 +88,13 @@ export function dfpSettings(handleSlotRenderEnded) {
window.googletag.pubads().enableAsyncRendering();

if (this.collapseEmptyDivs) {
sendLog('dfpSettings()', 'This wrapper is set to collapse any empty divs.', null);
window.googletag.pubads().collapseEmptyDivs();
}
window.googletag.enableServices();

if (handleSlotRenderEnded) {
sendLog('dfpSettings()', 'This wrapper has a function to call upon the slot render ending.', null);
window.googletag.pubads().addEventListener('slotRenderEnded', handleSlotRenderEnded);
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/services/headerbidding.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { fetchPrebidBids, queuePrebidCommand } from './prebid';
import { fetchAmazonBids, queueAmazonCommand } from './amazon';
import { refreshSlot } from './gpt';
import { sendLog } from '../util/log';

/**
* @desc Initializes all header bidding services and appends the applicable scripts to the page.
Expand All @@ -13,6 +14,7 @@ export function initializeBiddingServices({
amazon = false
}) {
if (window.arcBiddingReady) {
sendLog('initializeBiddingServices()', 'Header bidding has been previously initialized', null);
return;
}

Expand All @@ -26,6 +28,7 @@ export function initializeBiddingServices({
}
resolve('Prebid has been initialized');
} else {
sendLog('initializeBiddingServices()', 'Prebid is not enabled on this wrapper.', null);
resolve('Prebid is not enabled on the wrapper...');
}
});
Expand All @@ -45,6 +48,7 @@ export function initializeBiddingServices({
} else {
console.warn(`ArcAds: Missing Amazon account id.
Documentation: https://github.com/wapopartners/arc-ads#amazon-tama9`);
sendLog('initializeBiddingServices()', 'Amazon is not enabled on this wrapper.', null);
resolve('Amazon is not enabled on the wrapper...');
}
} else {
Expand Down
2 changes: 2 additions & 0 deletions src/services/sizemapping.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { debounce } from '../util/debounce';
import { fetchBids } from './headerbidding';
import { refreshSlot } from './gpt';
import { sendLog } from '../util/log';

/** @desc An object containing all of the size map refresh event listeners and correlators for size mapping. **/
export const sizemapListeners = {};
Expand Down Expand Up @@ -69,6 +70,7 @@ export function parseSizeMappings(sizeMappings) {

return result;
} catch (e) {
sendLog('parseSizeMappings()', 'invalid size mapping', null);
// Fallback to last size mapping supplied if there's an invalid mapping provided
return sizeMappings[sizeMappings.length - 1][1];
}
Expand Down
22 changes: 22 additions & 0 deletions src/util/log.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import anylogger from 'anylogger';
import 'anylogger-console';
/**
* @desc Determines whether or not to log based on a url param. Takes description as a parameter and returns log.
* @param {string} description - The description that should go in the log.
**/
export function sendLog(parentFunc, description, slotName) {
try {
if ((new URLSearchParams(window.location.search)).get('debug') === 'true') {
const log = anylogger('arcads.js');
log({
service: 'ArcAds',
timestamp: `${new Date()}`,
'logging from': parentFunc,
description,
slotName
});
}
} catch (error) {
console.error(error);
}
}

0 comments on commit 2655b06

Please sign in to comment.