Skip to content

Commit ff56019

Browse files
authored
Mobkoi User ID module: Initial Release (prebid#12733)
* feat: max-848 Prebid: setup development harness. max-849: Prebid: Make prebid RTB ORTB request to /bid (#1) harness](https://mobkoi.atlassian.net/browse/MAX-848) Set up a local development environment for testing and iterating on Prebid customization changes. Sub-tasks: Install Prebid.js dependencies. Create a custom Prebid.js Adapter (mobkoiBidAdapter) and build a custom Prebid.js package to serve locally (the custom Prebid.js package is available to serve to a local webpage). Initialize Ad Service Bid endpoint, ensuring it can serve dummy bid objects to the client. Initialize Ad Server Ad endpoint to serve dummy ads/creatives that display on the sample website. Set up a sample website for end-to-end testing, including page load, Prebid.js, Ad Service Bid endpoint, returning bids to the front-end, Ad Server Ad endpoint, and loading ads on the page. /bid](https://mobkoi.atlassian.net/browse/MAX-849) Update Prebid.js to create ORTB-formatted bid requests for the /bid endpoint. Sub-tasks: Modify Prebid request formatting to ORTB. Validate bid responses from /bid with ORTB formatting. Integrate the new ORTB bid request structure in the /bid endpoint base on the data provided by Prebid.js. Create unit tests. feat: max-852: Prebid: Log bid win to adserver (prebid#3) > Related PRs mobkoi/adserver#6 adserver](https://mobkoi.atlassian.net/browse/MAX-852) Implement logging of bid wins directly to the ad server. Sub-tasks: Capture winning bid events in the Prebid.js custom adapter in various steps of biding process. feat: max-853: Prebid: Log bid loss to adserver (prebid#4) adserver](https://mobkoi.atlassian.net/browse/MAX-853) Implement logging of failed bid events for monitoring purposes. Sub-tasks: Initialise a Prebid custom analytic adapter. Capture bid failure events within Prebid.js during various steps of the bidding process Initialise the endpoint for receiving bid loss signals. Logs will log into Grafana, but this will be done in a separate ticket feat: max-876: Prebid: Analytic Adapter Log debug info to adserver (prebid#5) > Related PR: mobkoi/adserver#10 adserver](https://mobkoi.atlassian.net/browse/MAX-876) Add logging for debugging information to assist with monitoring and troubleshooting. Sub-tasks Record events at different stages of bid processing on the client side via the custom analytic adapter Save event messages locally on the client. Tag each message with one of three levels: info, warn, or debug. feat: writing unit tests for mobkoi adapters (prebid#6) Co-authored-by: nvkftw <kevin.gallet@mobkoi.com> updated doc description added the missing mobkoiBidAdapter md small fix for our unit test added intergration with mobkoi getuid and setuid endpoint double encoded the setuid callback added mobkoiIdSystem module got a working smartadserver sync url from provided example got a working equativ url before rollback to ajax call for equativ intergration WIP testing droping pixel in iframe feat: max-970: Prebid.js Bidder Adapter: Retrieve Adapter Parameters from Bid Configuration Object (prebid#8) Configuration Object](https://mobkoi.atlassian.net/browse/MAX-970) At this stage, we are only focused on bid win events, so there is no need for analytics adapter integration yet. To streamline the publisher's configuration for our custom bid adapter integration, we retrieve adapter parameters directly from the bid configuration object instead of using "bidderConfiguration." updated bid adapter doc wip equativ pixel in an iframe approvated concept cookie sync work on client side code tidy up for the working cookie solution removed the need for cookieName param matches the backend endpoint name changes feat: max-956: We need the placement ID from Tag and HB Connector to be past to the AdServer (prebid#9) the AdServer](https://mobkoi.atlassian.net/browse/MAX-956) removed unexpected code transfer the user id to ortb2 request body and set the field to null if not avaiable fixed a minor bug enabed consent string added unit tests for mobkoi ID system module fixed a minor bug removed the code that wrapping URL in URL objects. It just make things complicated fixed the publisher ID in macro issue clean up branch for offical PR pass the expiration value when setting storage using the storage manager updated id system module md pass expire setting to storage * code tidy up * switch to getStorageManager instead of getCoreStorageManager * add mobkoiIdSystem to modules/.submodules.json file
1 parent e04bfc2 commit ff56019

File tree

4 files changed

+407
-0
lines changed

4 files changed

+407
-0
lines changed

modules/.submodules.json

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"lockrAIMIdSystem",
3030
"lotamePanoramaIdSystem",
3131
"merkleIdSystem",
32+
"mobkoiIdSystem",
3233
"mwOpenLinkIdSystem",
3334
"mygaruIdSystem",
3435
"naveggIdSystem",

modules/mobkoiIdSystem.js

+144
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
/**
2+
* This module adds mobkoiId support to the User ID module
3+
* The {@link module:modules/userId} module is required.
4+
* @module modules/mobkoiIdSystem
5+
* @requires module:modules/userId
6+
*/
7+
8+
import { submodule } from '../src/hook.js';
9+
import { getStorageManager } from '../src/storageManager.js';
10+
import { MODULE_TYPE_UID } from '../src/activities/modules.js';
11+
import { logError, logInfo, deepAccess, insertUserSyncIframe } from '../src/utils.js';
12+
13+
const GVL_ID = 898;
14+
const MODULE_NAME = 'mobkoiId';
15+
export const PROD_AD_SERVER_BASE_URL = 'https://adserver.maximus.mobkoi.com';
16+
export const EQUATIV_BASE_URL = 'https://sync.smartadserver.com';
17+
export const EQUATIV_NETWORK_ID = '5290';
18+
/**
19+
* !IMPORTANT: This value must match the value in mobkoiAnalyticsAdapter.js
20+
* The name of the parameter that the publisher can use to specify the ad server endpoint.
21+
*/
22+
const PARAM_NAME_AD_SERVER_BASE_URL = 'adServerBaseUrl';
23+
24+
export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME });
25+
26+
export const mobkoiIdSubmodule = {
27+
name: MODULE_NAME,
28+
gvlid: GVL_ID,
29+
30+
decode(value) {
31+
return value ? { [MODULE_NAME]: value } : undefined;
32+
},
33+
34+
getId(userSyncOptions, gdprConsent) {
35+
logInfo('Getting Equativ SAS ID.');
36+
37+
if (!storage.cookiesAreEnabled()) {
38+
logError('Cookies are not enabled. Module will not work.');
39+
return {
40+
id: null
41+
};
42+
}
43+
44+
const storageName = userSyncOptions && userSyncOptions.storage && userSyncOptions.storage.name;
45+
if (!storageName) {
46+
logError('Storage name is not defined. Module will not work.');
47+
return {
48+
id: null
49+
};
50+
}
51+
52+
const existingId = storage.getCookie(storageName);
53+
54+
if (existingId) {
55+
logInfo(`Found "${storageName}" from local cookie: "${existingId}"`);
56+
return { id: existingId };
57+
}
58+
59+
logInfo(`Cannot found "${storageName}" in local cookie with name.`);
60+
return {
61+
callback: () => {
62+
return new Promise((resolve, _reject) => {
63+
utils.requestEquativSasId(
64+
userSyncOptions,
65+
gdprConsent,
66+
(sasId) => {
67+
if (!sasId) {
68+
logError('Equativ SAS ID is empty');
69+
resolve({ id: null });
70+
return;
71+
}
72+
73+
logInfo(`Fetched Equativ SAS ID: "${sasId}"`);
74+
storage.setCookie(storageName, sasId, userSyncOptions.storage.expires);
75+
logInfo(`Stored Equativ SAS ID in local cookie with name: "${storageName}"`);
76+
resolve({ id: sasId });
77+
}
78+
);
79+
});
80+
}
81+
};
82+
},
83+
};
84+
85+
submodule('userId', mobkoiIdSubmodule);
86+
87+
export const utils = {
88+
requestEquativSasId(syncUserOptions, gdprConsent, onCompleteCallback) {
89+
logInfo('Start requesting Equativ SAS ID');
90+
const adServerBaseUrl = deepAccess(
91+
syncUserOptions,
92+
`params.${PARAM_NAME_AD_SERVER_BASE_URL}`) || PROD_AD_SERVER_BASE_URL;
93+
94+
const equativPixelUrl = utils.buildEquativPixelUrl(syncUserOptions, gdprConsent);
95+
logInfo('Equativ SAS ID request URL:', equativPixelUrl);
96+
97+
const url = adServerBaseUrl + '/pixeliframe?' +
98+
'pixelUrl=' + encodeURIComponent(equativPixelUrl) +
99+
'&cookieName=sas_uid';
100+
101+
/**
102+
* Listen for messages from the iframe
103+
*/
104+
window.addEventListener('message', function(event) {
105+
switch (event.data.type) {
106+
case 'MOBKOI_PIXEL_SYNC_COMPLETE':
107+
const sasUid = event.data.syncData;
108+
logInfo('Parent window Sync completed. SAS ID:', sasUid);
109+
onCompleteCallback(sasUid);
110+
break;
111+
case 'MOBKOI_PIXEL_SYNC_ERROR':
112+
logError('Parent window Sync failed:', event.data.error);
113+
onCompleteCallback(null);
114+
break;
115+
}
116+
});
117+
118+
insertUserSyncIframe(url, () => {
119+
logInfo('insertUserSyncIframe loaded');
120+
});
121+
122+
// Return the URL for testing purposes
123+
return url;
124+
},
125+
126+
/**
127+
* Build a pixel URL that will be placed in an iframe to fetch the Equativ SAS ID
128+
*/
129+
buildEquativPixelUrl(syncUserOptions, gdprConsent) {
130+
logInfo('Generating Equativ SAS ID request URL');
131+
const adServerBaseUrl =
132+
deepAccess(
133+
syncUserOptions,
134+
`params.${PARAM_NAME_AD_SERVER_BASE_URL}`) || PROD_AD_SERVER_BASE_URL;
135+
136+
const gdprConsentString = gdprConsent && gdprConsent.gdprApplies ? gdprConsent.consentString : '';
137+
const smartServerUrl = EQUATIV_BASE_URL + '/getuid?' +
138+
`url=` + encodeURIComponent(`${adServerBaseUrl}/getPixel?value=`) + '[sas_uid]' +
139+
`&gdpr_consent=${gdprConsentString}` +
140+
`&nwid=${EQUATIV_NETWORK_ID}`;
141+
142+
return smartServerUrl;
143+
}
144+
};

modules/mobkoiIdSystem.md

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
## Mobkoi User ID Submodule
2+
3+
For assistance setting up your module please contact us at platformteam@mobkoi.com.
4+
5+
### Prebid Params
6+
7+
Individual params may be set for the IDx Submodule.
8+
```
9+
pbjs.setConfig({
10+
userSync: {
11+
userIds: [{
12+
name: 'mobkoiId',
13+
storage: {
14+
name : 'mobkoi_uid',
15+
type : 'cookie',
16+
expires : 30
17+
}
18+
}]
19+
}
20+
});
21+
```
22+
## Parameter Descriptions for the `userSync` Configuration Section
23+
The below parameters apply only to the Mobkoi integration.
24+
25+
| Param under usersync.userIds[] | Scope | Type | Description | Example |
26+
| --- | --- | --- | --- | --- |
27+
| name | Required | String | ID of the module - `"mobkoiId"` | `"mobkoiId"` |
28+
| storage.name | Required | String | The name of the cookie local storage where the user ID will be stored. | `"mobkoi_uid"` |
29+
| storage.type | Required | String | Must be "`cookie`". This is where the results of the user ID will be stored. | `"cookie"` |
30+
| storage.expires | Required | Integer | How long (in days) the user ID information will be stored. | `30` |
31+
32+
## Serving the Custom Build Locally
33+
34+
To serve the custom build locally, use the following command:
35+
36+
```sh
37+
gulp serve-fast --modules=consentManagementTcf,tcfControl,mobkoiBidAdapter,mobkoiIdSystem,userId
38+
```

0 commit comments

Comments
 (0)