@bidkernel/analytics 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analytics.global.js +1 -1
- package/dist/index.d.mts +15 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.js +420 -36
- package/dist/index.mjs +418 -36
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -24,6 +24,8 @@ __export(src_exports, {
|
|
|
24
24
|
PrebidEventDeduper: () => PrebidEventDeduper,
|
|
25
25
|
getPrebidEventKey: () => getPrebidEventKey,
|
|
26
26
|
getbidkernel: () => getbidkernel,
|
|
27
|
+
hookImaPrototype: () => hookImaPrototype,
|
|
28
|
+
initImaInterception: () => initImaInterception,
|
|
27
29
|
isTrustedEndpoint: () => isTrustedEndpoint,
|
|
28
30
|
registerPrebidAnalytics: () => registerPrebidAnalytics
|
|
29
31
|
});
|
|
@@ -998,8 +1000,264 @@ function parseBidDimensions(bid) {
|
|
|
998
1000
|
height: Number.isFinite(bid?.height) ? bid.height : 0
|
|
999
1001
|
};
|
|
1000
1002
|
}
|
|
1003
|
+
var adsLoaderListenerMap = /* @__PURE__ */ new WeakMap();
|
|
1004
|
+
function hookAdsManagerLoadedEvent(loadedEventCtor) {
|
|
1005
|
+
if (!loadedEventCtor) return;
|
|
1006
|
+
try {
|
|
1007
|
+
const loadedProto = loadedEventCtor.prototype;
|
|
1008
|
+
if (loadedProto && typeof loadedProto.getAdsManager === "function" && !loadedProto.getAdsManager.__bidkernelHooked) {
|
|
1009
|
+
const originalGetAdsManager = loadedProto.getAdsManager;
|
|
1010
|
+
const hookedGetAdsManager = function(...args) {
|
|
1011
|
+
const adsManager = originalGetAdsManager.apply(this, args);
|
|
1012
|
+
if (adsManager) {
|
|
1013
|
+
for (const instance of BidkernelPrebidAnalytics.getActiveInstances()) {
|
|
1014
|
+
try {
|
|
1015
|
+
instance.attachImaAdsManager(adsManager);
|
|
1016
|
+
} catch {
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
return adsManager;
|
|
1021
|
+
};
|
|
1022
|
+
hookedGetAdsManager.__bidkernelHooked = true;
|
|
1023
|
+
loadedProto.getAdsManager = hookedGetAdsManager;
|
|
1024
|
+
}
|
|
1025
|
+
} catch {
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
function hookAdsManagerPrototype(adsManagerCtorOrProto) {
|
|
1029
|
+
if (!adsManagerCtorOrProto) return;
|
|
1030
|
+
try {
|
|
1031
|
+
const proto = adsManagerCtorOrProto.prototype || adsManagerCtorOrProto;
|
|
1032
|
+
if (proto && typeof proto.init === "function" && !proto.init.__bidkernelHooked) {
|
|
1033
|
+
const origInit = proto.init;
|
|
1034
|
+
const hookedInit = function(...args) {
|
|
1035
|
+
for (const instance of BidkernelPrebidAnalytics.getActiveInstances()) {
|
|
1036
|
+
try {
|
|
1037
|
+
instance.attachImaAdsManager(this);
|
|
1038
|
+
} catch {
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
return origInit.apply(this, args);
|
|
1042
|
+
};
|
|
1043
|
+
hookedInit.__bidkernelHooked = true;
|
|
1044
|
+
proto.init = hookedInit;
|
|
1045
|
+
}
|
|
1046
|
+
if (proto && typeof proto.start === "function" && !proto.start.__bidkernelHooked) {
|
|
1047
|
+
const origStart = proto.start;
|
|
1048
|
+
const hookedStart = function(...args) {
|
|
1049
|
+
for (const instance of BidkernelPrebidAnalytics.getActiveInstances()) {
|
|
1050
|
+
try {
|
|
1051
|
+
instance.attachImaAdsManager(this);
|
|
1052
|
+
} catch {
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
return origStart.apply(this, args);
|
|
1056
|
+
};
|
|
1057
|
+
hookedStart.__bidkernelHooked = true;
|
|
1058
|
+
proto.start = hookedStart;
|
|
1059
|
+
}
|
|
1060
|
+
} catch {
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
function hookAdsLoader(adsLoaderCtor) {
|
|
1064
|
+
if (!adsLoaderCtor) return;
|
|
1065
|
+
try {
|
|
1066
|
+
const proto = adsLoaderCtor.prototype;
|
|
1067
|
+
if (!proto) return;
|
|
1068
|
+
if (typeof proto.addEventListener === "function" && !proto.addEventListener.__bidkernelHooked) {
|
|
1069
|
+
const origAddEventListener = proto.addEventListener;
|
|
1070
|
+
const hookedAddEventListener = function(type, listener, ...rest) {
|
|
1071
|
+
if ((type === "adsManagerLoaded" || type === (this?.AdsManagerLoadedEvent?.Type?.ADS_MANAGER_LOADED || "adsManagerLoaded")) && typeof listener === "function") {
|
|
1072
|
+
let wrappedListener = adsLoaderListenerMap.get(listener);
|
|
1073
|
+
if (!wrappedListener) {
|
|
1074
|
+
wrappedListener = function(event) {
|
|
1075
|
+
if (event && typeof event.getAdsManager === "function" && !event.getAdsManager.__bidkernelHooked) {
|
|
1076
|
+
const origGetAdsManager = event.getAdsManager;
|
|
1077
|
+
event.getAdsManager = function(...args) {
|
|
1078
|
+
const adsManager = origGetAdsManager.apply(this, args);
|
|
1079
|
+
if (adsManager) {
|
|
1080
|
+
for (const sdk of BidkernelPrebidAnalytics.getActiveInstances()) {
|
|
1081
|
+
try {
|
|
1082
|
+
sdk.attachImaAdsManager(adsManager);
|
|
1083
|
+
} catch {
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
return adsManager;
|
|
1088
|
+
};
|
|
1089
|
+
event.getAdsManager.__bidkernelHooked = true;
|
|
1090
|
+
}
|
|
1091
|
+
return listener.apply(this, arguments);
|
|
1092
|
+
};
|
|
1093
|
+
adsLoaderListenerMap.set(listener, wrappedListener);
|
|
1094
|
+
}
|
|
1095
|
+
return origAddEventListener.call(this, type, wrappedListener, ...rest);
|
|
1096
|
+
}
|
|
1097
|
+
return origAddEventListener.call(this, type, listener, ...rest);
|
|
1098
|
+
};
|
|
1099
|
+
hookedAddEventListener.__bidkernelHooked = true;
|
|
1100
|
+
proto.addEventListener = hookedAddEventListener;
|
|
1101
|
+
}
|
|
1102
|
+
if (typeof proto.removeEventListener === "function" && !proto.removeEventListener.__bidkernelHooked) {
|
|
1103
|
+
const origRemoveEventListener = proto.removeEventListener;
|
|
1104
|
+
const hookedRemoveEventListener = function(type, listener, ...rest) {
|
|
1105
|
+
const wrapped = typeof listener === "function" ? adsLoaderListenerMap.get(listener) : void 0;
|
|
1106
|
+
return origRemoveEventListener.call(this, type, wrapped || listener, ...rest);
|
|
1107
|
+
};
|
|
1108
|
+
hookedRemoveEventListener.__bidkernelHooked = true;
|
|
1109
|
+
proto.removeEventListener = hookedRemoveEventListener;
|
|
1110
|
+
}
|
|
1111
|
+
} catch {
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
function hookImaPrototype(ima) {
|
|
1115
|
+
if (!ima || typeof ima !== "object") return;
|
|
1116
|
+
try {
|
|
1117
|
+
if (ima.AdsManagerLoadedEvent) {
|
|
1118
|
+
hookAdsManagerLoadedEvent(ima.AdsManagerLoadedEvent);
|
|
1119
|
+
}
|
|
1120
|
+
const loadedDesc = Object.getOwnPropertyDescriptor(ima, "AdsManagerLoadedEvent");
|
|
1121
|
+
if (!loadedDesc || loadedDesc.configurable) {
|
|
1122
|
+
let _loadedEvent = ima.AdsManagerLoadedEvent;
|
|
1123
|
+
try {
|
|
1124
|
+
Object.defineProperty(ima, "AdsManagerLoadedEvent", {
|
|
1125
|
+
configurable: true,
|
|
1126
|
+
enumerable: true,
|
|
1127
|
+
get() {
|
|
1128
|
+
return _loadedEvent;
|
|
1129
|
+
},
|
|
1130
|
+
set(val) {
|
|
1131
|
+
_loadedEvent = val;
|
|
1132
|
+
hookAdsManagerLoadedEvent(val);
|
|
1133
|
+
}
|
|
1134
|
+
});
|
|
1135
|
+
} catch {
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
if (ima.AdsLoader) {
|
|
1139
|
+
hookAdsLoader(ima.AdsLoader);
|
|
1140
|
+
}
|
|
1141
|
+
const loaderDesc = Object.getOwnPropertyDescriptor(ima, "AdsLoader");
|
|
1142
|
+
if (!loaderDesc || loaderDesc.configurable) {
|
|
1143
|
+
let _loader = ima.AdsLoader;
|
|
1144
|
+
try {
|
|
1145
|
+
Object.defineProperty(ima, "AdsLoader", {
|
|
1146
|
+
configurable: true,
|
|
1147
|
+
enumerable: true,
|
|
1148
|
+
get() {
|
|
1149
|
+
return _loader;
|
|
1150
|
+
},
|
|
1151
|
+
set(val) {
|
|
1152
|
+
_loader = val;
|
|
1153
|
+
hookAdsLoader(val);
|
|
1154
|
+
}
|
|
1155
|
+
});
|
|
1156
|
+
} catch {
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
if (ima.AdsManager) {
|
|
1160
|
+
hookAdsManagerPrototype(ima.AdsManager);
|
|
1161
|
+
}
|
|
1162
|
+
const mgrDesc = Object.getOwnPropertyDescriptor(ima, "AdsManager");
|
|
1163
|
+
if (!mgrDesc || mgrDesc.configurable) {
|
|
1164
|
+
let _mgr = ima.AdsManager;
|
|
1165
|
+
try {
|
|
1166
|
+
Object.defineProperty(ima, "AdsManager", {
|
|
1167
|
+
configurable: true,
|
|
1168
|
+
enumerable: true,
|
|
1169
|
+
get() {
|
|
1170
|
+
return _mgr;
|
|
1171
|
+
},
|
|
1172
|
+
set(val) {
|
|
1173
|
+
_mgr = val;
|
|
1174
|
+
hookAdsManagerPrototype(val);
|
|
1175
|
+
}
|
|
1176
|
+
});
|
|
1177
|
+
} catch {
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
} catch {
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
function initImaInterception() {
|
|
1184
|
+
if (typeof window === "undefined") return;
|
|
1185
|
+
const win = window;
|
|
1186
|
+
if (win.google?.ima) {
|
|
1187
|
+
hookImaPrototype(win.google.ima);
|
|
1188
|
+
}
|
|
1189
|
+
if (win.google && typeof win.google === "object") {
|
|
1190
|
+
const imaDesc = Object.getOwnPropertyDescriptor(win.google, "ima");
|
|
1191
|
+
if (!imaDesc || imaDesc.configurable) {
|
|
1192
|
+
let _ima = win.google.ima;
|
|
1193
|
+
try {
|
|
1194
|
+
Object.defineProperty(win.google, "ima", {
|
|
1195
|
+
configurable: true,
|
|
1196
|
+
enumerable: true,
|
|
1197
|
+
get() {
|
|
1198
|
+
return _ima;
|
|
1199
|
+
},
|
|
1200
|
+
set(val) {
|
|
1201
|
+
_ima = val;
|
|
1202
|
+
hookImaPrototype(val);
|
|
1203
|
+
}
|
|
1204
|
+
});
|
|
1205
|
+
} catch {
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
const googleDesc = Object.getOwnPropertyDescriptor(win, "google");
|
|
1210
|
+
if (!googleDesc || googleDesc.configurable) {
|
|
1211
|
+
let _google = win.google;
|
|
1212
|
+
try {
|
|
1213
|
+
Object.defineProperty(win, "google", {
|
|
1214
|
+
configurable: true,
|
|
1215
|
+
enumerable: true,
|
|
1216
|
+
get() {
|
|
1217
|
+
return _google;
|
|
1218
|
+
},
|
|
1219
|
+
set(val) {
|
|
1220
|
+
_google = val;
|
|
1221
|
+
if (_google && typeof _google === "object") {
|
|
1222
|
+
if (_google.ima) {
|
|
1223
|
+
hookImaPrototype(_google.ima);
|
|
1224
|
+
}
|
|
1225
|
+
const iDesc = Object.getOwnPropertyDescriptor(_google, "ima");
|
|
1226
|
+
if (!iDesc || iDesc.configurable) {
|
|
1227
|
+
let _i = _google.ima;
|
|
1228
|
+
try {
|
|
1229
|
+
Object.defineProperty(_google, "ima", {
|
|
1230
|
+
configurable: true,
|
|
1231
|
+
enumerable: true,
|
|
1232
|
+
get() {
|
|
1233
|
+
return _i;
|
|
1234
|
+
},
|
|
1235
|
+
set(iv) {
|
|
1236
|
+
_i = iv;
|
|
1237
|
+
hookImaPrototype(iv);
|
|
1238
|
+
}
|
|
1239
|
+
});
|
|
1240
|
+
} catch {
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
});
|
|
1246
|
+
} catch {
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
if (typeof window !== "undefined") {
|
|
1251
|
+
initImaInterception();
|
|
1252
|
+
}
|
|
1001
1253
|
var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
1002
1254
|
static activeInstances = /* @__PURE__ */ new Set();
|
|
1255
|
+
static getActiveInstances() {
|
|
1256
|
+
return _BidkernelPrebidAnalytics.activeInstances;
|
|
1257
|
+
}
|
|
1258
|
+
static initImaInterception() {
|
|
1259
|
+
initImaInterception();
|
|
1260
|
+
}
|
|
1003
1261
|
config;
|
|
1004
1262
|
queue = [];
|
|
1005
1263
|
errorCount = 0;
|
|
@@ -1163,6 +1421,10 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1163
1421
|
}
|
|
1164
1422
|
this.flushTimer = setInterval(() => this.flush(), FLUSH_INTERVAL_MS);
|
|
1165
1423
|
this.resendPersistedBatches();
|
|
1424
|
+
initImaInterception();
|
|
1425
|
+
if (window.google?.ima) {
|
|
1426
|
+
hookImaPrototype(window.google.ima);
|
|
1427
|
+
}
|
|
1166
1428
|
}
|
|
1167
1429
|
}
|
|
1168
1430
|
disable() {
|
|
@@ -1643,6 +1905,72 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1643
1905
|
this.cachedWinningBids.delete(oldest.value);
|
|
1644
1906
|
}
|
|
1645
1907
|
}
|
|
1908
|
+
/**
|
|
1909
|
+
* Searches cached winning bids for an entry matching the given filters (creativeId,
|
|
1910
|
+
* adId, or mediaType), falling back to the most recent winning video bid.
|
|
1911
|
+
*/
|
|
1912
|
+
findCachedWinningBid(filter) {
|
|
1913
|
+
const now = Date.now();
|
|
1914
|
+
const isConsumed = (entry) => {
|
|
1915
|
+
return this.hasImpressionEmitted(
|
|
1916
|
+
entry.adUnitCode,
|
|
1917
|
+
void 0,
|
|
1918
|
+
entry.auctionId,
|
|
1919
|
+
entry.bidTrace.creativeId
|
|
1920
|
+
);
|
|
1921
|
+
};
|
|
1922
|
+
if (filter?.creativeId || filter?.adId) {
|
|
1923
|
+
for (const entry of Array.from(this.cachedWinningBids.values())) {
|
|
1924
|
+
if (now - entry.timestamp > CACHED_BID_TTL_MS) continue;
|
|
1925
|
+
if (filter.creativeId && (entry.bidTrace.creativeId === filter.creativeId || entry.rawBid?.creativeId === filter.creativeId) || filter.adId && (entry.rawBid?.adId === filter.adId || entry.adUnitCode === filter.adId)) {
|
|
1926
|
+
return entry;
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
let bestUnconsumedMatch;
|
|
1931
|
+
if (filter?.mediaType) {
|
|
1932
|
+
for (const entry of Array.from(this.cachedWinningBids.values())) {
|
|
1933
|
+
if (now - entry.timestamp > CACHED_BID_TTL_MS) continue;
|
|
1934
|
+
const isEntryVideo = entry.bidTrace.mediaType === filter.mediaType || entry.rawBid?.mediaType === filter.mediaType || filter.mediaType === "video" && entry.rawBid?.mediaTypes?.video !== void 0;
|
|
1935
|
+
if (isEntryVideo) {
|
|
1936
|
+
if (!isConsumed(entry)) {
|
|
1937
|
+
if (!bestUnconsumedMatch || entry.timestamp < bestUnconsumedMatch.timestamp) {
|
|
1938
|
+
bestUnconsumedMatch = entry;
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
if (bestUnconsumedMatch) return bestUnconsumedMatch;
|
|
1944
|
+
let bestFallbackMatch;
|
|
1945
|
+
for (const entry of Array.from(this.cachedWinningBids.values())) {
|
|
1946
|
+
if (now - entry.timestamp > CACHED_BID_TTL_MS) continue;
|
|
1947
|
+
const isEntryVideo = entry.bidTrace.mediaType === filter.mediaType || entry.rawBid?.mediaType === filter.mediaType || filter.mediaType === "video" && entry.rawBid?.mediaTypes?.video !== void 0;
|
|
1948
|
+
if (isEntryVideo) {
|
|
1949
|
+
if (!bestFallbackMatch || entry.timestamp > bestFallbackMatch.timestamp) {
|
|
1950
|
+
bestFallbackMatch = entry;
|
|
1951
|
+
}
|
|
1952
|
+
}
|
|
1953
|
+
}
|
|
1954
|
+
if (bestFallbackMatch) return bestFallbackMatch;
|
|
1955
|
+
}
|
|
1956
|
+
for (const entry of Array.from(this.cachedWinningBids.values())) {
|
|
1957
|
+
if (now - entry.timestamp > CACHED_BID_TTL_MS) continue;
|
|
1958
|
+
if (!isConsumed(entry)) {
|
|
1959
|
+
if (!bestUnconsumedMatch || entry.timestamp > bestUnconsumedMatch.timestamp) {
|
|
1960
|
+
bestUnconsumedMatch = entry;
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
if (bestUnconsumedMatch) return bestUnconsumedMatch;
|
|
1965
|
+
let bestRecent;
|
|
1966
|
+
for (const entry of Array.from(this.cachedWinningBids.values())) {
|
|
1967
|
+
if (now - entry.timestamp > CACHED_BID_TTL_MS) continue;
|
|
1968
|
+
if (!bestRecent || entry.timestamp > bestRecent.timestamp) {
|
|
1969
|
+
bestRecent = entry;
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
return bestRecent;
|
|
1973
|
+
}
|
|
1646
1974
|
/** Records a dedup key, evicting oldest-first at the cap. */
|
|
1647
1975
|
addImpressionKey(key) {
|
|
1648
1976
|
if (this.slotEmittedImpressionKeys.has(key)) return;
|
|
@@ -1802,14 +2130,40 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1802
2130
|
return () => {
|
|
1803
2131
|
};
|
|
1804
2132
|
}
|
|
2133
|
+
if (!adsManager.__bidkernelAttachedInstances) {
|
|
2134
|
+
try {
|
|
2135
|
+
Object.defineProperty(adsManager, "__bidkernelAttachedInstances", {
|
|
2136
|
+
value: /* @__PURE__ */ new Set(),
|
|
2137
|
+
configurable: true,
|
|
2138
|
+
writable: true
|
|
2139
|
+
});
|
|
2140
|
+
} catch {
|
|
2141
|
+
adsManager.__bidkernelAttachedInstances = /* @__PURE__ */ new Set();
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2144
|
+
if (adsManager.__bidkernelAttachedInstances.has(this)) {
|
|
2145
|
+
return () => {
|
|
2146
|
+
};
|
|
2147
|
+
}
|
|
2148
|
+
adsManager.__bidkernelAttachedInstances.add(this);
|
|
1805
2149
|
const slotId = options?.slotId || options?.adUnitCode || "video";
|
|
1806
2150
|
const adUnitCode = options?.adUnitCode || slotId;
|
|
1807
2151
|
const auctionId = options?.auctionId || "";
|
|
1808
2152
|
const transactionId = options?.transactionId || "";
|
|
1809
|
-
const getWinningBid = () => {
|
|
1810
|
-
|
|
2153
|
+
const getWinningBid = (adData) => {
|
|
2154
|
+
let cached = (auctionId ? this.getCachedBid(`${auctionId}:${adUnitCode}`) : void 0) || (auctionId && slotId !== adUnitCode ? this.getCachedBid(`${auctionId}:${slotId}`) : void 0) || (adUnitCode !== "video" ? this.getCachedBid(adUnitCode) : void 0) || (slotId !== adUnitCode && slotId !== "video" ? this.getCachedBid(slotId) : void 0);
|
|
2155
|
+
if (!cached) {
|
|
2156
|
+
cached = this.findCachedWinningBid({
|
|
2157
|
+
creativeId: adData?.creativeId,
|
|
2158
|
+
adId: adData?.adId,
|
|
2159
|
+
mediaType: "video"
|
|
2160
|
+
});
|
|
2161
|
+
}
|
|
2162
|
+
return cached;
|
|
1811
2163
|
};
|
|
2164
|
+
let adStarted = false;
|
|
1812
2165
|
const onAdStartedOrImpression = (event) => {
|
|
2166
|
+
adStarted = true;
|
|
1813
2167
|
this.log("DEBUG", "IMA AdEvent.STARTED / IMPRESSION received", event);
|
|
1814
2168
|
const ad = typeof event?.getAd === "function" ? event.getAd() : event?.ad;
|
|
1815
2169
|
const adData = {};
|
|
@@ -1820,16 +2174,20 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1820
2174
|
adData.duration = typeof ad.getDuration === "function" ? ad.getDuration() : ad.duration;
|
|
1821
2175
|
adData.advertiserName = typeof ad.getAdvertiserName === "function" ? ad.getAdvertiserName() : "";
|
|
1822
2176
|
}
|
|
1823
|
-
const cached = getWinningBid();
|
|
2177
|
+
const cached = getWinningBid(adData);
|
|
2178
|
+
const resolvedSlotId = options?.slotId && options.slotId !== "video" ? options.slotId : options?.adUnitCode && options.adUnitCode !== "video" ? options.adUnitCode : cached?.adUnitCode || options?.slotId || options?.adUnitCode || "video";
|
|
2179
|
+
const resolvedAdUnitCode = options?.adUnitCode && options.adUnitCode !== "video" ? options.adUnitCode : cached?.adUnitCode || resolvedSlotId;
|
|
2180
|
+
const resolvedAuctionId = auctionId || cached?.auctionId || "";
|
|
2181
|
+
const resolvedTransactionId = transactionId || cached?.transactionId || "";
|
|
1824
2182
|
const mergedBid = {
|
|
1825
2183
|
...cached?.rawBid || options?.bid,
|
|
1826
2184
|
mediaType: "video",
|
|
1827
2185
|
creativeId: adData.creativeId || cached?.bidTrace?.creativeId || options?.bid?.creativeId || ""
|
|
1828
2186
|
};
|
|
1829
|
-
const emitted = this.recordImpression(
|
|
1830
|
-
adUnitCode,
|
|
1831
|
-
auctionId:
|
|
1832
|
-
transactionId:
|
|
2187
|
+
const emitted = this.recordImpression(resolvedSlotId, {
|
|
2188
|
+
adUnitCode: resolvedAdUnitCode,
|
|
2189
|
+
auctionId: resolvedAuctionId,
|
|
2190
|
+
transactionId: resolvedTransactionId,
|
|
1833
2191
|
mediaType: "video",
|
|
1834
2192
|
bid: mergedBid,
|
|
1835
2193
|
metadata: {
|
|
@@ -1841,7 +2199,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1841
2199
|
});
|
|
1842
2200
|
if (emitted && options?.onImpression) {
|
|
1843
2201
|
try {
|
|
1844
|
-
options.onImpression(
|
|
2202
|
+
options.onImpression(resolvedSlotId, { ad, bid: mergedBid });
|
|
1845
2203
|
} catch (e) {
|
|
1846
2204
|
this.log("ERROR", "Error in onImpression callback", e);
|
|
1847
2205
|
}
|
|
@@ -1860,10 +2218,11 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1860
2218
|
const onAdClick = (event) => {
|
|
1861
2219
|
this.log("DEBUG", "IMA AdEvent.CLICK received", event);
|
|
1862
2220
|
const cached = getWinningBid();
|
|
2221
|
+
const resolvedAdUnitCode = options?.adUnitCode && options.adUnitCode !== "video" ? options.adUnitCode : cached?.adUnitCode || slotId;
|
|
1863
2222
|
this.enqueue(TraceEventType.CLICK, "click", {
|
|
1864
2223
|
auctionId: auctionId || cached?.auctionId,
|
|
1865
2224
|
transactionId: transactionId || cached?.transactionId,
|
|
1866
|
-
adUnitCode,
|
|
2225
|
+
adUnitCode: resolvedAdUnitCode,
|
|
1867
2226
|
bid: cached?.bidTrace || options?.bid,
|
|
1868
2227
|
metadata: {
|
|
1869
2228
|
...options?.metadata,
|
|
@@ -1877,14 +2236,16 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1877
2236
|
const msg = (err && typeof err.getMessage === "function" ? err.getMessage() : err?.message) || String(err || "IMA ad error");
|
|
1878
2237
|
const code = (err && typeof err.getErrorCode === "function" ? err.getErrorCode() : err?.code) || "";
|
|
1879
2238
|
const cached = getWinningBid();
|
|
2239
|
+
const resolvedAdUnitCode = options?.adUnitCode && options.adUnitCode !== "video" ? options.adUnitCode : cached?.adUnitCode || slotId;
|
|
1880
2240
|
this.enqueue(TraceEventType.AD_RENDER_FAILED, "adRenderFailed", {
|
|
1881
2241
|
auctionId: auctionId || cached?.auctionId,
|
|
1882
2242
|
transactionId: transactionId || cached?.transactionId,
|
|
1883
|
-
adUnitCode,
|
|
2243
|
+
adUnitCode: resolvedAdUnitCode,
|
|
1884
2244
|
bid: cached?.bidTrace || options?.bid,
|
|
1885
2245
|
metadata: {
|
|
1886
2246
|
...options?.metadata,
|
|
1887
|
-
reason: "ima_ad_error",
|
|
2247
|
+
reason: adStarted ? "ima_playback_error" : "ima_ad_error",
|
|
2248
|
+
playback_phase: adStarted ? "post_start" : "pre_start",
|
|
1888
2249
|
message: msg,
|
|
1889
2250
|
...code ? { ima_error_code: String(code) } : {}
|
|
1890
2251
|
},
|
|
@@ -1901,7 +2262,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1901
2262
|
const googleIma = typeof window !== "undefined" ? window.google?.ima : void 0;
|
|
1902
2263
|
const adEventType = googleIma?.AdEvent?.Type || {};
|
|
1903
2264
|
const adErrorEventType = googleIma?.AdErrorEvent?.Type || {};
|
|
1904
|
-
const
|
|
2265
|
+
const rawListeners = [
|
|
1905
2266
|
{ type: adEventType.STARTED || "started", handler: onAdStartedOrImpression },
|
|
1906
2267
|
{ type: adEventType.IMPRESSION || "impression", handler: onAdStartedOrImpression },
|
|
1907
2268
|
{
|
|
@@ -1917,6 +2278,14 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1917
2278
|
{ type: adEventType.CLICK || "click", handler: onAdClick },
|
|
1918
2279
|
{ type: adErrorEventType.AD_ERROR || "adError", handler: onAdError }
|
|
1919
2280
|
];
|
|
2281
|
+
const seenListenerTypes = /* @__PURE__ */ new Set();
|
|
2282
|
+
const listeners = [];
|
|
2283
|
+
for (const l of rawListeners) {
|
|
2284
|
+
if (!seenListenerTypes.has(l.type)) {
|
|
2285
|
+
seenListenerTypes.add(l.type);
|
|
2286
|
+
listeners.push(l);
|
|
2287
|
+
}
|
|
2288
|
+
}
|
|
1920
2289
|
for (const { type, handler } of listeners) {
|
|
1921
2290
|
try {
|
|
1922
2291
|
adsManager.addEventListener(type, handler);
|
|
@@ -1924,6 +2293,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1924
2293
|
}
|
|
1925
2294
|
}
|
|
1926
2295
|
const cleanup = () => {
|
|
2296
|
+
adsManager.__bidkernelAttachedInstances?.delete(this);
|
|
1927
2297
|
for (const { type, handler } of listeners) {
|
|
1928
2298
|
try {
|
|
1929
2299
|
adsManager.removeEventListener(type, handler);
|
|
@@ -2309,7 +2679,8 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2309
2679
|
const adUnitCode = data.adUnitCode || "";
|
|
2310
2680
|
const cpm = Number.isFinite(data.originalCpm) ? data.originalCpm : Number.isFinite(data.cpm) ? data.cpm : 0;
|
|
2311
2681
|
const latencyMs = Number.isFinite(data.timeToRespond) ? data.timeToRespond : 0;
|
|
2312
|
-
const
|
|
2682
|
+
const resMediaTypes = Object.keys(data.mediaTypes || {});
|
|
2683
|
+
const mediaType = data.mediaType || (data.mediaTypes?.video ? "video" : resMediaTypes.length > 0 ? resMediaTypes[0] : "banner");
|
|
2313
2684
|
if (auctionId && bidder) {
|
|
2314
2685
|
const auctionMap = this.getOrCreateAuctionOutcomes(auctionId);
|
|
2315
2686
|
const key = `${bidder}:${adUnitCode}`;
|
|
@@ -2382,13 +2753,15 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2382
2753
|
const auctionId = data.auctionId || "";
|
|
2383
2754
|
const transactionId = data.transactionId || "";
|
|
2384
2755
|
const adUnitCode = data.adUnitCode || data.adId || "";
|
|
2756
|
+
const wonMediaTypes = Object.keys(data.mediaTypes || {});
|
|
2757
|
+
const resolvedMediaType = data.mediaType || (data.mediaTypes?.video ? "video" : wonMediaTypes.length > 0 ? wonMediaTypes[0] : "banner");
|
|
2385
2758
|
const bidTrace = {
|
|
2386
2759
|
bidder: data.bidderCode || data.bidder || "",
|
|
2387
2760
|
cpm: Number.isFinite(data.originalCpm) ? data.originalCpm : Number.isFinite(data.cpm) ? data.cpm : 0,
|
|
2388
2761
|
currency: data.originalCurrency ?? data.currency ?? "USD",
|
|
2389
2762
|
...parseBidDimensions(data),
|
|
2390
2763
|
dealId: data.dealId || "",
|
|
2391
|
-
mediaType:
|
|
2764
|
+
mediaType: resolvedMediaType,
|
|
2392
2765
|
latencyMs: Number.isFinite(data.timeToRespond) ? data.timeToRespond : 0,
|
|
2393
2766
|
advertiserDomain: data.meta?.advertiserDomains?.[0] || "",
|
|
2394
2767
|
creativeId: data.creativeId || ""
|
|
@@ -2477,13 +2850,15 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2477
2850
|
const slotKey = data.adUnitCode || bid.adUnitCode || "";
|
|
2478
2851
|
const altKey = data.adId || bid.adId || "";
|
|
2479
2852
|
const cached = (auctionId && slotKey ? this.getCachedBid(`${auctionId}:${slotKey}`) : void 0) || (auctionId && altKey ? this.getCachedBid(`${auctionId}:${altKey}`) : void 0) || (slotKey ? this.getCachedBid(slotKey) : void 0) || (altKey ? this.getCachedBid(altKey) : void 0);
|
|
2853
|
+
const isVideo = mediaType === "video" || bid.mediaType === "video" || bid.mediaTypes?.video !== void 0 || cached?.bidTrace?.mediaType === "video" || cached?.rawBid?.mediaType === "video" || adUnitCode && this.slotViewabilityRecords.get(adUnitCode)?.mediaType === "video";
|
|
2854
|
+
const resolvedMediaType = isVideo ? "video" : mediaType || cached?.bidTrace?.mediaType || "banner";
|
|
2480
2855
|
const bidTrace = {
|
|
2481
2856
|
bidder: bid.bidderCode || bid.bidder || cached?.bidTrace?.bidder || "",
|
|
2482
2857
|
cpm: Number.isFinite(bid.originalCpm) ? bid.originalCpm : Number.isFinite(bid.cpm) ? bid.cpm : cached?.bidTrace?.cpm ?? 0,
|
|
2483
2858
|
currency: bid.originalCurrency ?? bid.currency ?? cached?.bidTrace?.currency ?? "USD",
|
|
2484
2859
|
...parseBidDimensions(bid).width ? parseBidDimensions(bid) : cached?.bidTrace ? { width: cached.bidTrace.width, height: cached.bidTrace.height } : parseBidDimensions(bid),
|
|
2485
2860
|
dealId: bid.dealId || cached?.bidTrace?.dealId || "",
|
|
2486
|
-
mediaType:
|
|
2861
|
+
mediaType: resolvedMediaType,
|
|
2487
2862
|
latencyMs: Number.isFinite(bid.timeToRespond) ? bid.timeToRespond : cached?.bidTrace?.latencyMs ?? 0,
|
|
2488
2863
|
advertiserDomain: bid.meta?.advertiserDomains?.[0] || cached?.bidTrace?.advertiserDomain || "",
|
|
2489
2864
|
creativeId: bid.creativeId || cached?.bidTrace?.creativeId || ""
|
|
@@ -2522,28 +2897,35 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2522
2897
|
}
|
|
2523
2898
|
}
|
|
2524
2899
|
const currentRefreshIndex = adUnitCode ? this.slotRefreshIndices.get(adUnitCode) ?? (record ? record.refreshIndex : 0) : 0;
|
|
2525
|
-
|
|
2526
|
-
adUnitCode
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
if (
|
|
2533
|
-
|
|
2900
|
+
if (!isVideo) {
|
|
2901
|
+
const alreadyEmitted = adUnitCode ? this.hasImpressionEmitted(
|
|
2902
|
+
adUnitCode,
|
|
2903
|
+
currentRefreshIndex,
|
|
2904
|
+
resolvedAuctionId,
|
|
2905
|
+
bidTrace.creativeId
|
|
2906
|
+
) : false;
|
|
2907
|
+
if (!alreadyEmitted) {
|
|
2908
|
+
if (adUnitCode) {
|
|
2909
|
+
this.markImpressionEmitted(
|
|
2910
|
+
adUnitCode,
|
|
2911
|
+
currentRefreshIndex,
|
|
2912
|
+
resolvedAuctionId,
|
|
2913
|
+
bidTrace.creativeId
|
|
2914
|
+
);
|
|
2915
|
+
}
|
|
2916
|
+
this.enqueue(TraceEventType.IMPRESSION, "impression", {
|
|
2917
|
+
auctionId: resolvedAuctionId,
|
|
2918
|
+
transactionId: resolvedTransactionId,
|
|
2534
2919
|
adUnitCode,
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
);
|
|
2920
|
+
bid: bidTrace,
|
|
2921
|
+
metadata: { refresh_index: String(currentRefreshIndex) }
|
|
2922
|
+
});
|
|
2539
2923
|
}
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
adUnitCode
|
|
2544
|
-
|
|
2545
|
-
metadata: { refresh_index: String(currentRefreshIndex) }
|
|
2546
|
-
});
|
|
2924
|
+
} else {
|
|
2925
|
+
this.log(
|
|
2926
|
+
"DEBUG",
|
|
2927
|
+
`adRenderSucceeded received for video ad unit ${adUnitCode || "unknown"}: suppressing IMPRESSION until verified video lifecycle event`
|
|
2928
|
+
);
|
|
2547
2929
|
}
|
|
2548
2930
|
if (this.config.viewabilityEnabled && typeof document !== "undefined") {
|
|
2549
2931
|
let el = null;
|
|
@@ -2579,7 +2961,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2579
2961
|
adUnitCode,
|
|
2580
2962
|
auctionId: resolvedAuctionId,
|
|
2581
2963
|
transactionId: resolvedTransactionId,
|
|
2582
|
-
mediaType,
|
|
2964
|
+
mediaType: resolvedMediaType,
|
|
2583
2965
|
bid: bidTrace,
|
|
2584
2966
|
refreshIndex: currentRefreshIndex,
|
|
2585
2967
|
emitRefreshEvent: false
|
|
@@ -3076,6 +3458,8 @@ function getbidkernel(alias = "bidkernel") {
|
|
|
3076
3458
|
PrebidEventDeduper,
|
|
3077
3459
|
getPrebidEventKey,
|
|
3078
3460
|
getbidkernel,
|
|
3461
|
+
hookImaPrototype,
|
|
3462
|
+
initImaInterception,
|
|
3079
3463
|
isTrustedEndpoint,
|
|
3080
3464
|
registerPrebidAnalytics
|
|
3081
3465
|
});
|