Repository navigation
analytics: troubleshooting fields captured at auction end in V2 prebid analytics - #377
Conversation
| */ | ||
| private cacheState(): Record<string, number> { | ||
| const { dcn } = this.optableInstance; | ||
| if (!dcn) return {}; |
There was a problem hiding this comment.
cacheState() reads window.localStorage directly. The SDK's own storage goes through LocalStorageProxy (lib/core/regs/storage.ts), which returns null when consent.deviceAccess is false. So analytics reads device storage that the SDK treats as off-limits, for example a targeting cache left from an earlier visit with consent. Suggest checking consent the same way:
if (!dcn || !dcn.consent?.deviceAccess) return {};| } | ||
| const origin = typeof performance !== "undefined" ? performance.timeOrigin : undefined; | ||
| if (typeof timestamp === "number" && origin) capture.t0 = Math.round(timestamp - origin); | ||
| capture.consent = this.consentFlags(bidderRequests[0]); |
There was a problem hiding this comment.
Nit: consent comes from bidderRequests[0] only. An auction with no bidder requests reports 0, which looks the same as "nothing applies". That's fine for troubleshooting, but worth a line in analytics.md.
| const { timestamp, bidderRequests = [] } = event; | ||
| const capture: Record<string, number> = {}; | ||
|
|
||
| const slotKey = |
There was a problem hiding this comment.
Nit: slotSeq keys on the first ad unit of the auction only. A multi-unit auction, like the usual page-load auction, increments only that unit's count. This matches V1, but the .md wording "Earlier auctions of the same ad unit" overstates it. Maybe "earlier auctions whose first ad unit is this one", or count every ad unit in the auction.
| // Per-bidder delivery as a bitmask over optableSources (bit i = optableSources[i]). | ||
| // Omitted when the bidder received every source, so the usual case adds nothing. | ||
| const auctionSources = witnessData.optableSources as string[]; | ||
| const fullMask = auctionSources.length && auctionSources.length <= 30 ? 2 ** auctionSources.length - 1 : 0; |
There was a problem hiding this comment.
Nit: om is silently skipped when there are more than 30 sources. That's unreachable in practice, but a short comment saying why the cap exists (e.g. keeping the mask in 32-bit int range for downstream bitwise ops) would help the next reader.
jplaroche
left a comment
There was a problem hiding this comment.
mostly nitpicking stuff, can release without it
7f24d83 to
50a7ae4
Compare
Why
V1 sends
slotSeq,t0,consent,cacheAge/idsMsand the per-bidderommask; V2 sends none of them. V2 builds its payloadbidWinTimeoutafter auction end, so the page-dependent values can't be read intoWitness.What Changed
slotSeq,t0,consentandcacheAge/idsMsare captured intrackAuctionEndand merged into the payload on both the timer and thevisibilitychangebeacon paths.cacheAgereads this SDK's own targeting key (OPTABLE_TARGETING_*) and its:tssibling, instead of V1's configurablecacheKey.consentbit 16 comes from atcf2Enforcementhook, live and on replay.omwhen it didn't receive every auction-level Optable source.How to Test
.mdalongside the code (for examplelib/addons/<addon>.md) and the matching README section. New addons ship with a new.md.Notes
Nothing downstream reads these fields yet: the DCN fact job and bid_analytics ignore them.
Breaking change
Requires release