-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Overtone RTD Module : initial release #12681
Open
CKBrennan
wants to merge
4
commits into
prebid:master
Choose a base branch
from
overtone-ai:overtone-circleci
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { submodule } from '../src/hook.js'; | ||
import { ajaxBuilder } from '../src/ajax.js'; | ||
import { safeJSONParse, logMessage as _logMessage } from '../src/utils.js'; | ||
|
||
export const OVERTONE_URL = 'https://prebid-1.overtone.ai/contextual'; | ||
|
||
const logMessage = (...args) => { | ||
_logMessage('Overtone', ...args); | ||
}; | ||
|
||
export async function fetchContextData(url = window.location.href) { | ||
const pageUrl = encodeURIComponent(url); | ||
const requestUrl = `${OVERTONE_URL}?URL=${pageUrl}&InApp=False`; | ||
const request = window.ajaxBuilder || ajaxBuilder(); | ||
|
||
return new Promise((resolve, reject) => { | ||
logMessage('Sending request to:', requestUrl); | ||
request(requestUrl, { | ||
success: (response) => { | ||
const data = safeJSONParse(response); | ||
logMessage('Fetched data:', data); | ||
|
||
if (!data || typeof data.status !== 'number') { | ||
reject(new Error('Invalid response format')); | ||
return; | ||
} | ||
|
||
switch (data.status) { | ||
case 1: // Success | ||
resolve({ categories: data.categories || [] }); | ||
break; | ||
case 3: // Fail | ||
case 4: // Ignore | ||
resolve({ categories: [] }); | ||
break; | ||
default: | ||
reject(new Error(`Unexpected response status: ${data.status}`)); | ||
} | ||
}, | ||
error: (err) => { | ||
logMessage('Error during request:', err); | ||
reject(err); | ||
}, | ||
}); | ||
}); | ||
} | ||
|
||
function init(config) { | ||
logMessage('init', config); | ||
return true; | ||
} | ||
|
||
export const overtoneRtdProvider = { | ||
name: 'overtone', | ||
init: init, | ||
getBidRequestData: function (bidReqConfig, callback) { | ||
fetchContextData() | ||
.then((contextData) => { | ||
if (contextData) { | ||
logMessage('Fetched context data', contextData); | ||
bidReqConfig.ortb2Fragments.global.site.ext = { | ||
...bidReqConfig.ortb2Fragments.global.site.ext, | ||
data: contextData, | ||
}; | ||
} | ||
callback(); | ||
}) | ||
.catch((error) => { | ||
logMessage('Error fetching context data', error); | ||
callback(); | ||
}); | ||
}, | ||
}; | ||
|
||
submodule('realTimeData', overtoneRtdProvider); | ||
|
||
export const overtoneModule = { | ||
fetchContextData, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
# Overtone Rtd Provider | ||
|
||
## Overview | ||
|
||
Module Name: Overtone Rtd Provider | ||
|
||
Module Type: Rtd Provider | ||
|
||
Maintainer: [email protected] | ||
|
||
The Overtone Real-Time Data (RTD) Module is a plug-and-play Prebid.js adapter designed to provide contextual classification results on the publisher’s page through Overtone’s contextual API. | ||
|
||
|
||
## Downloading and Configuring the Overtone RTD Module | ||
|
||
Navigate to https://docs.prebid.org/download.html and select the box labeled Overtone Prebid Contextual Evaluation. If Prebid.js is already installed on your site, ensure other necessary modules and adapters are selected. Upon clicking the "Get Prebid.js" button, a customized Prebid.js version will be built with your selections. | ||
|
||
Direct link to the Overtone module in the Prebid.js repository: | ||
|
||
The client must provide Overtone with all the addresses using the Prebid module to whitelist those domains. Failure to whitelist addresses will result in an invalid request to the Overtone Contextual API. | ||
|
||
|
||
## Functionality | ||
|
||
At a high level, the Overtone RTD Module makes requests to the Overtone Contextual API during page load. It fetches and categorizes content for each page, which is then available for targeting in Prebid.js. Contextual data includes content classifications, which help advertisers make informed decisions about ad placements. | ||
|
||
|
||
## Available Classifications | ||
|
||
Content Categories: | ||
|
||
Key: categories | ||
|
||
Possible Values: Various identifiers such as ovtn_004, ovtn_104, etc. | ||
|
||
Description: Content Categories represent Overtone’s classification of page content based on its contextual analysis. | ||
|
||
Please contact [email protected] for more information about our exact categories in brand safety, type, and tone. | ||
|
||
|
||
## Configuration Highlight | ||
|
||
The configuration for the Overtone RTD module in Prebid.js might resemble the following: | ||
|
||
pbjs.setConfig({ | ||
realTimeData: { | ||
dataProviders: [{ | ||
name: 'overtone', | ||
params: { | ||
|
||
} | ||
}] | ||
} | ||
}); | ||
|
||
|
||
## API Response Handling | ||
|
||
The Overtone RTD module processes responses from the Overtone Contextual API. A typical response might include the following: | ||
|
||
Status: Indicates the API request status (1 for success, 3 for fail, 4 for ignore). | ||
|
||
Categories: An array of classification identifiers. | ||
|
||
For example: | ||
|
||
{ | ||
"categories": ["ovtn_004", "ovtn_104", "ovtn_309", "ovtn_202"], | ||
"status": 1 | ||
} | ||
|
||
The module ensures that these values are integrated into Prebid.js’s targeting configuration for the current page. | ||
|
||
|
||
## Testing and Validation | ||
|
||
The functionality of the Overtone RTD module can be validated using the associated test suite provided in overtoneRtdProvider_spec.mjs. The test suite simulates different API response scenarios to verify module behavior under varied conditions. | ||
|
||
Example Test Cases: | ||
|
||
Successful Data Retrieval: | ||
|
||
Input: URL with valid classification data. | ||
|
||
Expected Output: Categories array populated with identifiers. | ||
|
||
Failed Request: | ||
|
||
Input: URL resulting in a failure. | ||
|
||
Expected Output: Empty categories array. | ||
|
||
Ignored URL: | ||
|
||
Input: URL to be ignored by the API. | ||
|
||
Expected Output: Empty categories array. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { expect } from 'chai'; | ||
import sinon from 'sinon'; | ||
import { overtoneModule } from '../../../modules/overtoneRtdProvider.js'; | ||
import { logMessage } from '../../../src/utils.js'; | ||
|
||
const TEST_URLS = { | ||
success: 'https://www.theguardian.com/film/2024/nov/15/duncan-cowles-silent-men-interview', | ||
fail: 'https://www.nytimes.com', | ||
ignore: 'https://wsj.com', | ||
}; | ||
|
||
describe('Overtone RTD Submodule with Test URLs', function () { | ||
this.timeout(120000); | ||
|
||
let fetchContextDataStub; | ||
|
||
beforeEach(function () { | ||
fetchContextDataStub = sinon.stub(overtoneModule, 'fetchContextData').callsFake(async (url) => { | ||
if (url === TEST_URLS.success) { | ||
return { categories: ['ovtn_004', 'ovtn_104', 'ovtn_309', 'ovtn_202'], status: 1 }; | ||
} | ||
if (url === TEST_URLS.fail) { | ||
return { categories: [], status: 3 }; | ||
} | ||
if (url === TEST_URLS.ignore) { | ||
return { categories: [], status: 4 }; | ||
} | ||
throw new Error('Unexpected URL in test'); | ||
}); | ||
}); | ||
|
||
afterEach(function () { | ||
fetchContextDataStub.restore(); | ||
}); | ||
|
||
it('should fetch and return categories for the success URL', async function () { | ||
const data = await overtoneModule.fetchContextData(TEST_URLS.success); | ||
logMessage(data); | ||
expect(data).to.deep.equal({ | ||
categories: ['ovtn_004', 'ovtn_104', 'ovtn_309', 'ovtn_202'], | ||
status: 1, | ||
}); | ||
}); | ||
|
||
it('should return the expected structure for the fail URL', async function () { | ||
const data = await overtoneModule.fetchContextData(TEST_URLS.fail); | ||
expect(data).to.deep.equal({ | ||
categories: [], | ||
status: 3, | ||
}); | ||
}); | ||
|
||
it('should return the expected structure for the ignore URL', async function () { | ||
const data = await overtoneModule.fetchContextData(TEST_URLS.ignore); | ||
expect(data).to.deep.equal({ | ||
categories: [], | ||
status: 4, | ||
}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. looks like just testing the fetchContextData function would be useful to test the ortb2Fragments part of the getBidRequestData as well to cover more lines. |
||
}); | ||
}); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not think this is needed. Can you confirm / let me know why it is.