@glomex/integration-analytics 1.1486.1 → 1.1487.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.
@@ -1,4 +1,4 @@
1
- import type { IntegrationElement } from '@glomex/integration-web-component';
1
+ import { type IntegrationElement } from '@glomex/integration-web-component';
2
2
  import { BaseEventMapper } from '../base-event-mapper.js';
3
3
  import type { NielsenAdMetadata, NielsenContentMetadata, NielsenInstance } from './nielsen-types.js';
4
4
  export declare class NielsenEventMapper extends BaseEventMapper {
@@ -1,3 +1,4 @@
1
+ import { PlaybackMode } from '@glomex/integration-web-component';
1
2
  import { BaseEventMapper } from '../base-event-mapper.js';
2
3
  /**
3
4
  * Transform metadata to Nielsen format
@@ -144,7 +145,14 @@ export class NielsenEventMapper extends BaseEventMapper {
144
145
  get #transformedContentMetadata() {
145
146
  return transformMetadata(this.#contentMetadata);
146
147
  }
148
+ get #isLive() {
149
+ return this.integration.source?.playbackMode === PlaybackMode.LIVE;
150
+ }
147
151
  get #currentTimeInMilliseconds() {
152
+ // For livestreams, Nielsen requires UTC timestamp per AGF spec
153
+ if (this.#isLive) {
154
+ return this.integration.wallClockTime * 1000;
155
+ }
148
156
  const currentTime = this.integration.currentTime ?? 0;
149
157
  return Math.floor(currentTime * 1000);
150
158
  }
@@ -116,13 +116,17 @@ export function createDeAdMetadataBuilder(options) {
116
116
  const channelName = integration.content?.channel?.name ?? '';
117
117
  // Universal Ad ID for campaign identification (c1)
118
118
  const universalAdId = ad.universalAdIds?.[0]?.id;
119
+ // Web only flag must match content's web-only status per AGF spec
120
+ // "N" if content matches linear TV (has externalId or is livestream), "Y" if web-only
121
+ const externalId = integration.content?.additionalIds?.externalId;
122
+ const webOnly = externalId || isLive ? 'N' : 'Y';
119
123
  return {
120
124
  assetid: truncate(ad.id ?? '', 64),
121
125
  type: adRollType,
122
126
  length: durationInSeconds.toString(),
123
127
  title: truncate(ad.id ?? '', 255),
124
128
  nol_c1: universalAdId ? truncate(universalAdId, 252) : undefined,
125
- nol_c2: 'Y', // optional but always provided
129
+ nol_c2: webOnly, // must match content's web-only status per AGF spec
126
130
  nol_c4: adRollType, // optional but always provided
127
131
  nol_c10: truncate(channelName, 251), // 255 - 4 for "p10,"
128
132
  nol_c11: truncate(ad.id ?? '', 251), // 255 - 4 for "p11,"
@@ -15,6 +15,8 @@ export interface SensicOptions {
15
15
  * @example 'de' - Germany
16
16
  */
17
17
  country: string;
18
+ /** Log level for Sensic SDK console output */
19
+ logLevel?: 'none' | 'error' | 'warn' | 'info' | 'log' | 'debug';
18
20
  /** Optional callback for warning messages */
19
21
  warnCallback?: (error: Error) => void;
20
22
  /**
@@ -52,15 +54,6 @@ export interface SensicOptions {
52
54
  */
53
55
  buildStreamId?: (streamId: string) => string;
54
56
  }
55
- /** @deprecated Use SensicOptions instead */
56
- export interface SensicProviderOptions {
57
- /** Sensic media identifier */
58
- media: string;
59
- /** Platform type: 'web' or 'tv' */
60
- platform: 'web' | 'tv';
61
- /** Optional callback for warning messages */
62
- warnCallback?: (error: Error) => void;
63
- }
64
57
  /**
65
58
  * Connects Sensic analytics integration to a turbo player integration.
66
59
  *
@@ -30,7 +30,7 @@ const IAB_VENDOR_SENSIC = '758';
30
30
  * ```
31
31
  */
32
32
  export const connectToSensic = (integration, options) => {
33
- const { media, platform, country, warnCallback } = options;
33
+ const { media, platform, country, logLevel, warnCallback } = options;
34
34
  const scriptUrl = buildSensicScriptUrl(country, platform);
35
35
  let initializationPromise;
36
36
  let currentMapper;
@@ -51,7 +51,8 @@ export const connectToSensic = (integration, options) => {
51
51
  initializationPromise = initSensicS2S({
52
52
  media,
53
53
  url: scriptUrl,
54
- type: 'WEB'
54
+ type: 'WEB',
55
+ logLevel
55
56
  }).catch((error) => {
56
57
  onWarn(error instanceof Error ? error : new Error(String(error)));
57
58
  return undefined;
@@ -26,7 +26,7 @@ export class SensicEventMapper extends BaseEventMapper {
26
26
  return;
27
27
  this.#isLive = this.integration.source?.playbackMode === PlaybackMode.LIVE;
28
28
  // Create agent with position callback
29
- this.#agent = this.#sensicSdk.getAgent(() => this.#isLive ? undefined : this.#currentTimeInMilliseconds);
29
+ this.#agent = this.#sensicSdk.getAgent(this.#isLive ? undefined : () => this.#currentTimeInMilliseconds);
30
30
  }
31
31
  onContentImpression() {
32
32
  this.#triggerPlay(this.#currentTimeInMilliseconds);
@@ -96,8 +96,8 @@ export class SensicEventMapper extends BaseEventMapper {
96
96
  if (!this.#agent)
97
97
  return;
98
98
  const customParams = this.#buildCustomParams() ?? {};
99
- const contentId = 'default'; // Always 'default' as per integration guide
100
99
  const isAd = this.isInAd;
100
+ const contentId = isAd ? 'ad' : 'default';
101
101
  const streamId = this.#buildStreamId
102
102
  ? this.#buildStreamId()
103
103
  : (() => {
@@ -1,80 +1,147 @@
1
1
  /**
2
2
  * Sensic S2S (Server-to-Server) TypeScript Definitions
3
- * Types for the GfK Sensic streaming measurement SDK
4
- * @see https://at-config.sensic.net/s2s-web.js
3
+ * Types aligned with official @gfksensic/s2s-js package (v1.1.3)
4
+ * @see https://npmreg.sensic.net/@gfksensic/s2s-js
5
5
  */
6
6
  /**
7
- * Options passed to play methods for screen and volume state
7
+ * Configuration for initializing the Sensic SDK via script loading.
8
+ * Based on InterfaceS2sTagConf from official package, with required `url` for script loading.
8
9
  */
9
- export interface SensicOptions {
10
+ export interface SensicConfig {
11
+ /** Media identifier provided by Sensic */
12
+ media: string;
13
+ /** Application type (e.g., 'WEB', 'APP', 'TV') */
14
+ type: string;
15
+ /** URL to the Sensic S2S script (required for script loading) */
16
+ url: string;
17
+ /** Application identifier */
18
+ ai?: string;
19
+ /** Device type (e.g., 'TABLET', 'SMARTPHONE', 'SMART-TV', 'UNKNOWN') */
20
+ device?: string;
21
+ /** Override TCF-based consent determination */
22
+ optin?: boolean;
23
+ /** Log level for SDK console output */
24
+ logLevel?: 'none' | 'error' | 'warn' | 'info' | 'log' | 'debug';
25
+ /** Custom log URL */
26
+ logUrl?: string;
27
+ /** External IDs for cross-device tracking */
28
+ extID?: {
29
+ [extIDName: string]: string;
30
+ };
31
+ /** Enable crash reporting */
32
+ crashReporting?: boolean;
33
+ }
34
+ /**
35
+ * Options passed to play methods for screen, volume, and speed state
36
+ * Matches InterfaceEventPlayOptions from official package
37
+ */
38
+ export interface SensicPlayOptions {
10
39
  /** Fullscreen state: '1' for fullscreen, '0' for not fullscreen */
11
- screen: string;
12
- /** Volume level as string (0-100) */
13
- volume: string;
40
+ screen?: string;
41
+ /** Volume level as string (0-100), or '-1' if not accessible */
42
+ volume?: string;
43
+ /** Playback speed (default is 1) */
44
+ speed?: number;
14
45
  }
15
46
  /**
16
47
  * Custom parameters sent with each play event.
17
48
  * The specific keys and values depend on the integration.
18
49
  */
19
50
  export type SensicCustomParams = Record<string, string>;
51
+ export interface PlayStreamLiveResult {
52
+ contentId: boolean;
53
+ streamStart: boolean;
54
+ streamOffset: boolean;
55
+ streamId: boolean;
56
+ options: boolean;
57
+ customParams: boolean;
58
+ }
59
+ export interface PlayStreamOnDemandResult {
60
+ contentId: boolean;
61
+ streamId: boolean;
62
+ options: boolean;
63
+ customParams: boolean;
64
+ }
65
+ export interface StopResult {
66
+ stop: boolean;
67
+ }
68
+ export interface VolumeResult {
69
+ volume: boolean;
70
+ }
71
+ export interface ScreenResult {
72
+ screen: boolean;
73
+ }
20
74
  /**
21
75
  * Sensic streaming agent instance for tracking playback
76
+ * Matches S2SAgent from official package
22
77
  */
23
78
  export interface SensicAgent {
24
- /**
25
- * Update the volume state
26
- * @param volume - Volume level as string (0-100)
27
- */
28
- volume: (volume: string) => void;
29
- /**
30
- * Update the fullscreen state
31
- * @param isFullscreen - '1' for fullscreen, '0' for not fullscreen
32
- */
33
- screen: (isFullscreen: string) => void;
34
79
  /**
35
80
  * Start tracking a live stream
36
- * @param contentId - Content identifier (usually 'default')
37
- * @param contentStart - Content start time (usually empty string)
81
+ * @param contentId - Content identifier (usually 'default' for content, 'ad' for ads)
82
+ * @param streamStart - ISO 8601 date string of content start, or empty string for current time
38
83
  * @param streamOffset - Offset from live edge in milliseconds
39
- * @param streamId - Stream/content title
40
- * @param options - Screen and volume options
84
+ * @param streamId - Stream identifier (must be unique per stream)
85
+ * @param options - Screen, volume, and speed options
41
86
  * @param customParams - Custom tracking parameters
87
+ * @returns Validation result for each parameter
42
88
  */
43
- playStreamLive: (contentId: string, contentStart: string, streamOffset: number, streamId: string, options: SensicOptions, customParams: Record<string, string>) => void;
89
+ playStreamLive: (contentId: string, streamStart: string, streamOffset: number, streamId: string, options: SensicPlayOptions, customParams: object) => PlayStreamLiveResult;
44
90
  /**
45
- * Start tracking an on-demand stream
46
- * @param contentId - Content identifier (usually 'default')
47
- * @param streamId - Stream/content title
48
- * @param position - Current playback position in milliseconds
49
- * @param options - Screen and volume options
91
+ * Start tracking an on-demand stream (without explicit position)
92
+ * Position will be determined from streamPositionCallback
93
+ * @param contentId - Content identifier (usually 'default' for content, 'ad' for ads)
94
+ * @param streamId - Stream identifier (must be unique per stream)
95
+ * @param options - Screen, volume, and speed options
50
96
  * @param customParams - Custom tracking parameters
97
+ * @returns Validation result for each parameter
51
98
  */
52
- playStreamOnDemand: (contentId: string, streamId: string, position: number, options: SensicOptions, customParams: Record<string, string>) => void;
99
+ playStreamOnDemand(contentId: string, streamId: string, options: SensicPlayOptions, customParams: object): PlayStreamOnDemandResult;
100
+ /**
101
+ * Start tracking an on-demand stream (with explicit position)
102
+ * @param contentId - Content identifier (usually 'default' for content, 'ad' for ads)
103
+ * @param streamId - Stream identifier (must be unique per stream)
104
+ * @param streamPosition - Current playback position in milliseconds
105
+ * @param options - Screen, volume, and speed options
106
+ * @param customParams - Custom tracking parameters
107
+ * @returns Validation result for each parameter
108
+ */
109
+ playStreamOnDemand(contentId: string, streamId: string, streamPosition: number, options: SensicPlayOptions, customParams: object): PlayStreamOnDemandResult;
53
110
  /**
54
111
  * Stop tracking playback
55
- * @param position - Current playback position in milliseconds (undefined for live)
112
+ * @param streamPosition - Current playback position in milliseconds (optional, uses callback if not provided)
113
+ * @returns Validation result
56
114
  */
57
- stop: (position?: number) => void;
58
- }
59
- /**
60
- * Configuration for initializing the Sensic SDK
61
- */
62
- export interface SensicConfig {
63
- /** Media identifier provided by Sensic */
64
- media: string;
65
- /** URL to the Sensic S2S script */
66
- url: string;
67
- /** Device type (e.g., 'WEB') */
68
- type: string;
115
+ stop: (streamPosition?: number) => StopResult;
116
+ /**
117
+ * Update the volume state
118
+ * @param volume - Volume level as string (0-100), or '-1' if not accessible
119
+ * @returns Validation result
120
+ */
121
+ volume: (volume: string) => VolumeResult;
122
+ /**
123
+ * Update the fullscreen state
124
+ * @param screen - '1' for fullscreen, '0' for not fullscreen
125
+ * @returns Validation result
126
+ */
127
+ screen: (screen: string) => ScreenResult;
128
+ /**
129
+ * Set or update the stream position callback
130
+ * @param callback - Function that returns current position in milliseconds
131
+ */
132
+ setStreamPositionCallback?: (callback: () => number) => void;
69
133
  }
70
134
  /**
71
- * Global Sensic SDK interface
135
+ * Global Sensic SDK interface (available on window.gfkS2s after script load)
72
136
  */
73
137
  export interface SensicGlobal {
74
138
  /**
75
139
  * Get a streaming agent for tracking playback
76
- * @param agentArg - Callback that returns current position (undefined for live)
140
+ * @param callback - Callback that returns current position in milliseconds (undefined for live)
141
+ * @param pId - Optional player identifier
77
142
  * @returns A SensicAgent instance for tracking
78
143
  */
79
- getAgent: (agentArg: () => number | undefined) => SensicAgent;
144
+ getAgent: (callback?: () => number | undefined, pId?: string) => SensicAgent;
145
+ /** Array of active agents */
146
+ agents?: SensicAgent[];
80
147
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Sensic S2S (Server-to-Server) TypeScript Definitions
3
- * Types for the GfK Sensic streaming measurement SDK
4
- * @see https://at-config.sensic.net/s2s-web.js
3
+ * Types aligned with official @gfksensic/s2s-js package (v1.1.3)
4
+ * @see https://npmreg.sensic.net/@gfksensic/s2s-js
5
5
  */
6
6
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glomex/integration-analytics",
3
- "version": "1.1486.1",
3
+ "version": "1.1487.0",
4
4
  "description": "Analytics integrations for the turbo player",
5
5
  "documentation": "https://docs.glomex.com",
6
6
  "homepage": "https://glomex.com",
@@ -63,5 +63,5 @@
63
63
  "access": "public"
64
64
  },
65
65
  "license": "MIT",
66
- "gitHead": "60e468bf5548cb0fa6d38e9ae0435ccdd589f5fa"
66
+ "gitHead": "efe6bfb544aebc668df8d533f1660273a1447294"
67
67
  }