Skip to content

Commit 9517550

Browse files
Datawrkz Analytics Adapter : initial release (prebid#13738)
* feat(analytics): added Datawrkz analytics adapter * fix(analytics): lint fixes for Datawrkz Analytics Adapter * fix(analytics): lint fixes for Datawrkz Analytics Adapter --------- Co-authored-by: Monis Qadri <monis0395@users.noreply.github.com>
1 parent 9ce2c82 commit 9517550

3 files changed

Lines changed: 428 additions & 0 deletions

File tree

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
import adapterManager from '../src/adapterManager.js';
2+
import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js';
3+
import { EVENTS } from '../src/constants.js';
4+
import { logInfo, logError } from '../src/utils.js';
5+
6+
let ENDPOINT = 'https://prebid-api.highr.ai/analytics';
7+
const auctions = {};
8+
9+
const datawrkzAnalyticsAdapter = Object.assign(adapter({ url: ENDPOINT, analyticsType: 'endpoint' }),
10+
{
11+
track({ eventType, args }) {
12+
logInfo('[DatawrkzAnalytics] Tracking event:', eventType, args);
13+
14+
switch (eventType) {
15+
case EVENTS.AUCTION_INIT: {
16+
const auctionId = args?.auctionId;
17+
if (!auctionId) return;
18+
19+
auctions[auctionId] = {
20+
auctionId,
21+
timestamp: new Date().toISOString(),
22+
domain: window.location.hostname || 'unknown',
23+
adunits: {}
24+
};
25+
break;
26+
}
27+
28+
case EVENTS.BID_REQUESTED: {
29+
const auctionId = args?.auctionId;
30+
const auction = auctions[auctionId];
31+
if (!auction) return;
32+
33+
args.bids.forEach(bid => {
34+
const adunit = bid.adUnitCode;
35+
if (!auction.adunits[adunit]) {
36+
auction.adunits[adunit] = { bids: [] };
37+
}
38+
39+
const exists = auction.adunits[adunit].bids.some(b => b.bidder === bid.bidder);
40+
if (!exists) {
41+
auction.adunits[adunit].bids.push({
42+
bidder: bid.bidder,
43+
requested: true,
44+
responded: false,
45+
won: false,
46+
timeout: false,
47+
cpm: 0,
48+
currency: '',
49+
timeToRespond: 0,
50+
adId: '',
51+
width: 0,
52+
height: 0
53+
});
54+
}
55+
});
56+
break;
57+
}
58+
59+
case EVENTS.BID_RESPONSE: {
60+
const auctionId = args?.auctionId;
61+
const auction = auctions[auctionId];
62+
if (!auction) return;
63+
64+
const adunit = auction.adunits[args.adUnitCode];
65+
if (adunit) {
66+
const match = adunit.bids.find(b => b.bidder === args.bidder);
67+
if (match) {
68+
match.responded = true;
69+
match.cpm = args.cpm;
70+
match.currency = args.currency;
71+
match.timeToRespond = args.timeToRespond;
72+
match.adId = args.adId
73+
match.width = args.width
74+
match.height = args.height
75+
}
76+
}
77+
break;
78+
}
79+
80+
case EVENTS.BID_TIMEOUT: {
81+
const { auctionId, adUnitCode, bidder } = args;
82+
const auctionTimeout = auctions[auctionId];
83+
if (!auctionTimeout) return;
84+
85+
const adunitTO = auctionTimeout.adunits[adUnitCode];
86+
if (adunitTO) {
87+
adunitTO.bids.forEach(b => {
88+
if (b.bidder === bidder) {
89+
b.timeout = true;
90+
}
91+
});
92+
}
93+
break;
94+
}
95+
96+
case EVENTS.BID_WON: {
97+
const auctionId = args?.auctionId;
98+
const auction = auctions[auctionId];
99+
if (!auction) return;
100+
101+
const adunit = auction.adunits[args.adUnitCode];
102+
if (adunit) {
103+
const match = adunit.bids.find(b => b.bidder === args.bidder);
104+
if (match) match.won = true;
105+
}
106+
break;
107+
}
108+
109+
case EVENTS.AD_RENDER_SUCCEEDED: {
110+
const { bid, adId, doc } = args || {};
111+
112+
const payload = {
113+
eventType: EVENTS.AD_RENDER_SUCCEEDED,
114+
domain: window.location.hostname || 'unknown',
115+
bidderCode: bid?.bidderCode,
116+
width: bid?.width,
117+
height: bid?.height,
118+
cpm: bid?.cpm,
119+
currency: bid?.currency,
120+
auctionId: bid?.auctionId,
121+
adUnitCode: bid?.adUnitCode,
122+
adId,
123+
successDoc: JSON.stringify(doc),
124+
failureReason: null,
125+
failureMessage: null,
126+
}
127+
128+
try {
129+
fetch(ENDPOINT, {
130+
method: 'POST',
131+
body: JSON.stringify(payload),
132+
headers: { 'Content-Type': 'application/json' }
133+
});
134+
} catch (e) {
135+
logError('[DatawrkzAnalytics] Failed to send AD_RENDER_SUCCEEDED event', e, payload);
136+
}
137+
138+
break;
139+
}
140+
141+
case EVENTS.AD_RENDER_FAILED: {
142+
const { reason, message, bid, adId } = args || {};
143+
144+
const payload = {
145+
eventType: EVENTS.AD_RENDER_FAILED,
146+
domain: window.location.hostname || 'unknown',
147+
bidderCode: bid?.bidderCode,
148+
width: bid?.width,
149+
height: bid?.height,
150+
cpm: bid?.cpm,
151+
currency: bid?.currency,
152+
auctionId: bid?.auctionId,
153+
adUnitCode: bid?.adUnitCode,
154+
adId,
155+
successDoc: null,
156+
failureReason: reason,
157+
failureMessage: message
158+
}
159+
160+
try {
161+
fetch(ENDPOINT, {
162+
method: 'POST',
163+
body: JSON.stringify(payload),
164+
headers: { 'Content-Type': 'application/json' }
165+
});
166+
} catch (e) {
167+
logError('[DatawrkzAnalytics] Failed to send AD_RENDER_FAILED event', e, payload);
168+
}
169+
170+
break;
171+
}
172+
173+
case EVENTS.AUCTION_END: {
174+
const auctionId = args?.auctionId;
175+
const auction = auctions[auctionId];
176+
if (!auction) return;
177+
178+
setTimeout(() => {
179+
const adunitsArray = Object.entries(auction.adunits).map(([code, data]) => ({
180+
code,
181+
bids: data.bids
182+
}));
183+
184+
const payload = {
185+
eventType: 'auction_data',
186+
auctionId: auction.auctionId,
187+
timestamp: auction.timestamp,
188+
domain: auction.domain,
189+
adunits: adunitsArray
190+
};
191+
192+
try {
193+
fetch(ENDPOINT, {
194+
method: 'POST',
195+
body: JSON.stringify(payload),
196+
headers: { 'Content-Type': 'application/json' }
197+
});
198+
} catch (e) {
199+
logError('[DatawrkzAnalytics] Sending failed', e, payload);
200+
}
201+
202+
delete auctions[auctionId];
203+
}, 2000); // Wait 2 seconds for BID_WON to happen
204+
205+
break;
206+
}
207+
208+
default:
209+
break;
210+
}
211+
}
212+
}
213+
);
214+
215+
datawrkzAnalyticsAdapter.originEnableAnalytics = datawrkzAnalyticsAdapter.enableAnalytics;
216+
217+
datawrkzAnalyticsAdapter.enableAnalytics = function (config) {
218+
datawrkzAnalyticsAdapter.originEnableAnalytics(config);
219+
logInfo('[DatawrkzAnalytics] Enabled with config:', config);
220+
};
221+
222+
adapterManager.registerAnalyticsAdapter({
223+
adapter: datawrkzAnalyticsAdapter,
224+
code: 'datawrkzanalytics'
225+
});
226+
227+
export default datawrkzAnalyticsAdapter;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Overview
2+
3+
**Module Name:** Datawrkz Analytics Adapter
4+
**Module Type:** Analytics Adapter
5+
**Maintainer:** ambily@datawrkz.com
6+
**Technical Support** likhith@datawrkz.com
7+
8+
---
9+
10+
## Description
11+
12+
Analytics adapter for Datawrkz — captures Prebid.js auction data and sends it to Datawrkz analytics server for reporting and insights.
13+
14+
---
15+
16+
## Settings
17+
18+
Enable the adapter using:
19+
20+
```js
21+
pbjs.enableAnalytics({
22+
provider: 'datawrkzanalytics'
23+
});

0 commit comments

Comments
 (0)