Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 59 additions & 60 deletions lib/addons/prebid/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,78 +4,77 @@ This addon integrates Optable analytics with Prebid.js, allowing you to send auc

## Installation

1. **Configure Analytics**
Use the following code snippet to enable analytics and configure the integration withing your Optable SDK wrapper:

```js
import OptablePrebidAnalytics from "./analytics";

// ...
const tenant = "my_tenant";
const analyticsSample = sessionStorage.optableEnableAnalytics || 0.1;
window.optable.runAnalytics = analyticsSample > Math.random();
// ...

window.optable.customAnalytics = function () {
const customAnalyticsObject = {};
// ...
return customAnalyticsObject;
};

// ...
if (window.optable.runAnalytics && tenant) {
window.optable[`${tenant}_analytics`] = new window.optable.SDK({
host: "na.edge.optable.co",
node: "analytics",
site: "analytics",
readOnly: true,
cookies: false,
});

window.optable.analytics = new OptablePrebidAnalytics(window.optable[`${tenant}_analytics`], {
analytics: true,
tenant,
debug: !!sessionStorage.optableDebug,
samplingRate: 0.75,
});
window.optable.analytics.hookIntoPrebid(window.pbjs);
}
// ...
```

- Replace 'my_tenant' with your Optable tenant name.
- Optionally, implement `window.optable.customAnalytics` to add custom key-value pairs to each analytics event.
### Quick start: `initPrebidAnalytics`

`initPrebidAnalytics` bootstraps the integration in one call: it constructs
`OptablePrebidAnalytics` around an SDK instance you already created and hooks it
into the Prebid.js instance you pass. It returns the analytics instance, or `null`
when no Prebid.js instance is provided.

```ts
import OptableSDK from "@optable/web-sdk";
import { initPrebidAnalytics } from "@optable/web-sdk/lib/addons/prebid/analytics";

const sdk = new OptableSDK({ host: "na.edge.optable.co", node: "analytics", site: "analytics" });

initPrebidAnalytics({
// An already-initialized Optable SDK instance
sdkInstance: sdk,
// The Prebid.js instance to hook into
pbjsInstance: window.pbjs,
// Forwarded to the OptablePrebidAnalytics constructor
analytics: {
samplingRate: 0.1,
debug: !!sessionStorage.optableDebug,
// Any OptablePrebidAnalyticsConfig option is forwarded, e.g. samplingVolume.
},
});
```

## Usage
`initPrebidAnalytics` reuses the SDK instance you already set up for
targeting/identify rather than creating its own. The tenant reported in every
payload is read from that instance's `node`.

### Manual setup

For full control, construct the collector yourself and hook it into Prebid.js:

- **Sampling**:
The `analyticsSample` variable controls the sampling rate. Set it to a float between 0 and 1 to control what fraction of users send analytics.
```js
import OptablePrebidAnalytics from "@optable/web-sdk/lib/addons/prebid/analytics";

const analytics = new OptablePrebidAnalytics(sdk, {
analytics: true,
debug: !!sessionStorage.optableDebug,
samplingRate: 0.75,
});
analytics.hookIntoPrebid(window.pbjs);
```

- **Debugging**:
Set `sessionStorage.optableDebug` to `true` to force analytics to run and enable debug logging.
The payload tenant is read from the SDK instance's `node`.

## Usage

- **Custom Analytics Data**:
Implement `window.optable.customAnalytics` to return an object with custom data to be included in analytics events.
- **Sampling**: `samplingRate` (0–1) controls the fraction of events/sessions sent.
- **Debugging**: set `sessionStorage.optableDebug` to enable debug logging.
- **Custom fields**: set `window.optable.customAnalytics` to an async function
returning an object; its keys are merged into every auction payload.

## API

### `initPrebidAnalytics(options)`

Bootstraps the integration and returns the `OptablePrebidAnalytics` instance, or `null` when no Prebid.js instance is provided.

- `options.sdkInstance`: An already-initialized Optable SDK instance. The tenant reported in the payload is read from its `node`.
- `options.pbjsInstance`: The Prebid.js instance to hook into (e.g. `window.pbjs`).
- `options.analytics`: Config forwarded to the `OptablePrebidAnalytics` constructor (`samplingRate`, `debug`, …).

### `OptablePrebidAnalytics`

- **Constructor**:
`new OptablePrebidAnalytics(sdkInstance, options)`
- `sdkInstance`: An instance of the Optable SDK.
- `options`: Object with options such as `debug`, `analytics`, and `tenant`.
- `options`: Object with options such as `debug`, `analytics`, and `samplingRate`. The payload tenant is derived from the SDK instance's `node`.

- **hookIntoPrebid(pbjs)**:
Hooks the analytics into the provided Prebid.js instance.

## Example

```js
window.optable.customAnalytics = function () {
return {
pageType: "homepage",
userSegment: "premium",
};
};
```
133 changes: 133 additions & 0 deletions lib/addons/prebid/analytics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Prebid Analytics Addon

This addon collects Prebid.js auction data and reports it to the Optable Witness
API. It hooks into `auctionEnd` and `bidWon` events, replays any events that
fired before the hook attached, tags bidder requests with Optable EID metadata
(matchers/sources), and sends a structured `optable.prebid.auction` payload.

It exposes two things:

- `initPrebidAnalytics(options)` — a bootstrap helper that creates the analytics
SDK instance, constructs the collector, and hooks it into Prebid for you. Use
this unless you need to manage those pieces yourself.
- `OptablePrebidAnalytics` — the collector class, for advanced setups.

## Usage

### Basic setup (recommended)

```js
import OptableSDK from "@optable/web-sdk";
import { initPrebidAnalytics } from "@optable/web-sdk/lib/addons/prebid/analytics";

const sdk = new OptableSDK({ host: "na.edge.optable.co", node: "my-tenant", site: "my-site" });

const analytics = initPrebidAnalytics({
sdkInstance: sdk,
pbjsInstance: window.pbjs,
analytics: {
samplingRate: 0.1,
},
});
```

`initPrebidAnalytics` takes an already-initialized Optable SDK instance and the
Prebid.js instance to hook into, and returns the analytics instance (or `null`
when no Prebid.js instance is provided). The tenant reported in every payload is
read from the SDK instance's `node`.

### With split-test assignment

The addon reports a per-bid `splitTestAssignment`, read verbatim from the bid's
`ortb2Imp.ext.optable.splitTestAssignment` (it does no transformation). Use the
[`setupAB` addon](../abTestAssignment.md) to assign a variant and stamp that field
onto every bid; the value then appears in the payload as
`bidderRequests[].bids[].splitTestAssignment`.

### Passing an explicit Prebid instance

`pbjsInstance` is the Prebid.js instance to hook into — pass `window.pbjs`, or any
other instance when Prebid lives elsewhere. Hooking is deferred via `pbjs.que`
automatically when `pbjs.onEvent` is not yet available, so you do not need to wrap
the call yourself.

```js
const analytics = initPrebidAnalytics({
sdkInstance: sdk,
pbjsInstance: myPrebidInstance,
});
```

### Custom payload fields

Set `window.optable.customAnalytics` to an async function returning an object; its
keys are merged into every auction payload:

```js
window.optable.customAnalytics = async () => ({ experiment: "floor-v2" });
```

### Advanced: managing the collector directly

```js
import OptablePrebidAnalytics from "@optable/web-sdk/lib/addons/prebid/analytics";

const sdk = new OptableSDK({
host: "na.edge.optable.co",
node: "my-tenant",
site: "my-site",
readOnly: true,
cookies: false,
});

const analytics = new OptablePrebidAnalytics(sdk, {
analytics: true,
samplingRate: 0.1,
});

analytics.hookIntoPrebid(window.pbjs);
```

The tenant reported in the payload is taken from the SDK instance's `node`.

## API

### `initPrebidAnalytics(options)`

**Options**

| Option | Type | Default | Description |
| -------------- | ------------------------------ | -------- | --------------------------------------------------------------------------------------------------- |
| `sdkInstance` | `OptableSDK` | required | An already-initialized Optable SDK instance. The payload tenant is read from its `node`. |
| `pbjsInstance` | `object` | required | The Prebid.js instance to hook into (e.g. `window.pbjs`). |
| `analytics` | `OptablePrebidAnalyticsConfig` | — | Analytics behavior forwarded to the collector (see below). `analytics: true` is applied by default. |

Returns the `OptablePrebidAnalytics` instance, or `null` when no Prebid instance is provided.

### `OptablePrebidAnalyticsConfig`

| Option | Type | Default | Description |
| ---------------- | ------------------------ | --------- | ------------------------------------------------------------------------------------------------------------------- |
| `analytics` | `boolean` | — | Master switch. When falsy, events are logged (in debug) but not sent to Witness. `initPrebidAnalytics` sets `true`. |
| `debug` | `boolean` | `false` | When true, logs collector activity to the console. |
| `bidWinTimeout` | `number` | `10000` | Milliseconds to wait after `auctionEnd` before sending, to collect `bidWon` events. |
| `samplingRate` | `number` | `1` | Fraction of events/sessions sampled (0–1). `<= 0` sends nothing; `>= 1` sends everything. |
| `samplingVolume` | `"session"` \| `"event"` | `"event"` | `"event"` re-rolls sampling per auction; `"session"` decides once per session. |
| `samplingSeed` | `string` | — | Deterministic sampling seed (e.g. a user id) instead of random sampling. |
| `samplingRateFn` | `() => boolean` | — | Custom sampling predicate; overrides the other sampling options when set. |

### `OptablePrebidAnalytics` instance

| Member | Type | Description |
| ---------------- | -------------------- | --------------------------------------------------------------------------------------------------------------- |
| `isInitialized` | `boolean` | `true` once the constructor has run. |
| `hookIntoPrebid` | `(pbjs?) => boolean` | Attaches event hooks. Defers via `pbjs.que` when `onEvent` is not ready. Returns `false` when Prebid is absent. |
| `clearData` | `() => void` | Clears stored auction/missed-event state (useful in tests). |

## Payload

Each sampled auction sends an `optable.prebid.auction` event with, among others:
`bidderRequests` (with per-bid `status`, `cpm`, `size`, `splitTestAssignment`),
`optableMatchers`, `optableSources`, `optableTargetingDone`, `bidWon`, `missed`,
`url`, `tenant`, `prebidjsVersion`, `sessionDepth`, `pageAuctionsCount`,
`originSlug`, and the parsed `userAgent`/`device`.
Loading
Loading