# @turbo-player/integration-analytics

A unified analytics integration package for the [turbo player](https://www.npmjs.com/package/@turbo-player/integration-web-component). This package provides adapters for various analytics providers including NPAW/Youbora, Comscore, Nielsen, and Sensic.

## Installation

```bash
npm install @turbo-player/integration-analytics
```

## Available Adapters

### NPAW/Youbora

[NPAW analytics](https://npaw.com/) integration for video analytics and quality of experience monitoring.

```typescript
import { connectToNpaw } from '@turbo-player/integration-analytics/npaw';


const integration = document.querySelector('my-integration');

// Simple setup for NPAW analytics (that also handles consent)
const { npawPlugin, destroy } = connectToNpaw(integration, {
  accountCode: 'your-npaw-account-code'
});
```

#### Advanced NPAW Configuration

```typescript
import { connectToNpaw } from '@turbo-player/integration-analytics/npaw';

const { npawPlugin, destroy } = connectToNpaw(integration, {
  accountCode: 'your-npaw-account-code',
  appName: 'my-app',
  appVersion: '1.0.0'
});

npawPlugin.setAnalyticsOptions({
  userId: 'my-user-id',
  'content.customDimensions': {
    tenant: 'my-tenant'
  }
});

// Clean up when done
destroy();
```

#### Direct NPAW Integration

```typescript
import { NpawTurboPlayerAdapter } from '@turbo-player/integration-analytics/npaw';
import NpawPlugin from 'npaw-plugin';

const npawPlugin = new NpawPlugin('your-npaw-account-code');
npawPlugin.registerAdapterFromClass(integration, NpawTurboPlayerAdapter);
```

### Comscore

[Comscore Streaming Analytics](https://www.comscore.com/) integration for measuring streaming video consumption.

```typescript
import { connectToComscore } from '@turbo-player/integration-analytics/comscore';


const integration = document.querySelector('my-integration');

// Connect Comscore analytics
const disconnect = connectToComscore(integration, {
  publisherId: 'your-publisher-id',
  publisherName: 'Your Publisher Name'
});

// Clean up when done
disconnect();
```

#### Comscore Configuration Options

| Option | Type | Required | Description |
|--------|------|----------|-------------|
| `publisherId` | `string` | Yes | Your Comscore publisher ID |
| `publisherName` | `string` | Yes | Your publisher name (e.g., "Joyn") |
| `debug` | `boolean` | No | Enable debug mode for implementation validation |
| `warnCallback` | `(error: Error) => void` | No | Custom callback for warning messages |
| `configureContentMetadata` | `(metadata) => metadata \| null` | No | Customize content metadata before tracking |

#### Advanced Comscore Configuration

```typescript
import { connectToComscore } from '@turbo-player/integration-analytics/comscore';

const disconnect = connectToComscore(integration, {
  publisherId: 'your-publisher-id',
  publisherName: 'Your Publisher Name',
  debug: true,
  warnCallback: (error) => {
    console.warn('Comscore warning:', error.message);
  },
  configureContentMetadata: (metadata) => {
    // Customize metadata or return null to skip tracking
    metadata.setGenreName('Sports');
    return metadata;
  }
});
```

#### Comscore Consent Requirements

Comscore tracking only occurs when the user has given consent according to IAB TCF:
- **Purpose 1** consent (Store and/or access information on a device)
- **Vendor 77** consent (Comscore)

### Nielsen

[Nielsen Digital Content Ratings](https://www.nielsen.com/solutions/audience-measurement/streaming-measurement/) integration for streaming measurement.

```typescript
import { connectToNielsen } from '@turbo-player/integration-analytics/nielsen';


const integration = document.querySelector('my-integration');

// Connect Nielsen analytics
const disconnect = connectToNielsen(integration, {
  appId: 'your-app-id',
  country: 'de'
});

// Clean up when done
disconnect();
```

#### Nielsen Configuration Options

| Option | Type | Required | Description |
|--------|------|----------|-------------|
| `appId` | `string` | Yes | Nielsen App ID (starts with 'P' for production, 'T' for test) |
| `country` | `string` | Yes | Two-letter country code for country-specific metadata mapping (e.g., 'de' for Germany) |
| `debug` | `boolean` | No | Enable Nielsen SDK debug mode |
| `warnCallback` | `(error: Error) => void` | No | Custom callback for warning messages |
| `configureContentMetadata` | `(metadata) => metadata \| null` | No | Extend/modify content metadata for tracking |
| `configureAdMetadata` | `(metadata) => metadata` | No | Extend/modify ad metadata for tracking |

#### Supported Countries

Nielsen uses country-specific metadata mappings:
- `'de'` - Germany (uses AGF-specific custom variables)
- Other country codes - Base metadata only (`assetid`, `type`, `program`, `title`, `length` for content; `assetid`, `type` for ads)

For Germany (`country: 'de'`), the following metadata is automatically built:
- **Content metadata**: `assetid`, `program`, `title`, `length`, `nol_c0` (part number), `nol_c2` (web only flag), `nol_c5` (page URL), `nol_c7` (video ID), `nol_c9` (video title), `nol_c10` (publisher), `nol_c12` (video type), `nol_c15` (format ID), `nol_c18` (livestream flag)
- **Ad metadata**: `assetid`, `type`, `length`, `title`, `nol_c1` (universal ad ID), `nol_c2`, `nol_c4` (ad form), `nol_c10`, `nol_c11` (ad ID), `nol_c12`, `nol_c17` (placement type), `nol_c18`

For unsupported country codes, only base metadata is provided. Use `configureContentMetadata` and `configureAdMetadata` to add country-specific fields manually:

```typescript
const disconnect = connectToNielsen(integration, {
  appId: 'your-app-id',
  country: 'fr', // No built-in mapping for France
  configureContentMetadata: (baseMetadata) => {
    // baseMetadata contains: assetid, type, program, title, length
    return {
      ...baseMetadata,
      program: integration.content?.show?.name ?? '',
      // Add France-specific fields as needed
    };
  },
  configureAdMetadata: (baseMetadata) => {
    // baseMetadata contains: assetid, type
    return {
      ...baseMetadata,
      title: integration.currentAd?.title ?? ''
    };
  }
});
```

#### Advanced Nielsen Configuration

The `configureContentMetadata` and `configureAdMetadata` callbacks receive country-specific metadata that is automatically built from integration data. You can extend or modify this metadata:

```typescript
import { connectToNielsen } from '@turbo-player/integration-analytics/nielsen';

const disconnect = connectToNielsen(integration, {
  appId: 'your-app-id',
  country: 'de',
  debug: true,
  warnCallback: (error) => {
    console.warn('Nielsen warning:', error.message);
  },
  configureContentMetadata: (metadata) => {
    // metadata contains country-specific fields (e.g., AGF fields for 'de')
    // Return null to skip tracking this content
    if (!integration.content) return null;
    
    return {
      ...metadata,
      // Add custom fields or override existing ones
      subbrand: 'abc' // VCID provided by Nielsen
    };
  },
  configureAdMetadata: (metadata) => {
    // metadata contains country-specific ad fields
    return {
      ...metadata,
      subbrand: 'abc'
    };
  }
});
```

#### Nielsen Consent

Nielsen does not require consent checks and uses a synchronous stub pattern. Events are queued until the SDK loads from CDN.

### Sensic (GfK)

[Sensic](https://sensic.net/) (formerly GfK) integration for streaming measurement in Germany and Austria.

```typescript
import { connectToSensic } from '@turbo-player/integration-analytics/sensic';


const integration = document.querySelector('my-integration');

// Connect Sensic analytics
const disconnect = connectToSensic(integration, {
  media: 'your-media-id',
  platform: 'web',
  country: 'de'
});

// Clean up when done
disconnect();
```

#### Sensic Configuration Options

| Option | Type | Required | Description |
|--------|------|----------|-------------|
| `media` | `string` | Yes | Sensic media identifier |
| `platform` | `'web' \| 'tv'` | Yes | Platform type |
| `country` | `string` | Yes | Two-letter country code (e.g., `'de'`, `'at'`) |
| `warnCallback` | `(error: Error) => void` | No | Custom callback for warning messages |
| `buildCustomParams` | `(customParams) => Record<string, string> \| null` | No | Extend/modify custom parameters for tracking |
| `buildStreamId` | `(streamId) => string` | No | Extend/modify stream ID for tracking |

#### Advanced Sensic Configuration

The `buildCustomParams` and `buildStreamId` callbacks receive country-specific values as input and are called on each stream start (VoD content, live content, and linear ads). Use `integration.content` for content data or `integration.currentAd` for ad data:

```typescript
import { connectToSensic } from '@turbo-player/integration-analytics/sensic';

const disconnect = connectToSensic(integration, {
  media: 'your-media-id',
  platform: 'web',
  country: 'at',
  warnCallback: (error) => {
    console.warn('Sensic warning:', error.message);
  },
  buildCustomParams: (customParams) => {
    // customParams contains country-specific params (e.g., AT params for Austria)
    // Return null to skip tracking this stream
    return {
      ...customParams,
      genre: integration.content?.genre ?? '',
      showId: integration.content?.show?.id ?? ''
    };
  },
  buildStreamId: (streamId) => {
    // streamId contains country-specific stream ID
    return streamId || integration.content?.id ?? '';
  }
});
```

#### Sensic Consent Requirements

Sensic tracking only occurs when the user has given consent according to IAB TCF:
- **Vendor 758** consent (Sensic)

#### Supported Countries

Sensic loads country-specific measurement scripts:
- `'de'` - Germany (`https://de-config.sensic.net/s2s-web.js`)
- `'at'` - Austria (`https://at-config.sensic.net/s2s-web.js`)

For TV platforms, the CTV variant is loaded automatically (e.g., `https://de-config.sensic.net/ctv/s2s-web.js`).

## Features

- 🎯 **Easy Integration**: Simple setup with turbo player
- 📊 **Multiple Providers**: Support for NPAW, Comscore, Nielsen, and Sensic (all certified by the providers)
- 🔧 **Smart Metadata Mapping**: Automatically maps player content metadata to each analytics provider's format, with full support for custom overrides
- 📱 **Cross-Platform**: Works with web, mobile web, and embedded players
- 🔒 **Consent Handling**: Built-in consent management support with IAB TCF compliance
- 🎬 **Comprehensive Tracking**: Tracks content and linear ad playback (preroll, midroll, postroll)

## License

[MIT](https://mit-license.org/)
