@metodokorexmk/tracking 1.0.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.
@@ -0,0 +1,869 @@
1
+ /**
2
+ * Tipos e interfaces compartidas para @metodokorexmk/tracking
3
+ */
4
+ /**
5
+ * Configuración principal del tracking.
6
+ * Se pasa a `initGA()` para inicializar el sistema.
7
+ */
8
+ interface TrackingConfig {
9
+ /** ID de Google Analytics 4 (ej: 'G-XXXXXXX') */
10
+ trackingId?: string;
11
+ /**
12
+ * Función personalizada para resolver el GA Tracking ID dinámicamente.
13
+ * Recibe la URL actual y debe devolver el ID correspondiente.
14
+ * Si se proporciona, tiene prioridad sobre `trackingId`.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * resolveTrackingId: (url) => {
19
+ * if (url.startsWith('/kin')) return 'G-KIN-ID'
20
+ * return localStorage.getItem('user_GA_id') || 'G-DEFAULT'
21
+ * }
22
+ * ```
23
+ */
24
+ resolveTrackingId?: (currentPath: string) => string;
25
+ /** ID de Google Tag Manager (ej: 'GTM-XXXXXXX'). Si se proporciona, se inyecta GTM automáticamente. */
26
+ gtmId?: string;
27
+ /** Habilitar anonimización de IP en GA4 */
28
+ anonymizeIp?: boolean;
29
+ /** Modo debug: imprime eventos en consola */
30
+ debug?: boolean;
31
+ }
32
+ /**
33
+ * Configuración del LandingTracker (orquestador de sesión).
34
+ */
35
+ interface LandingTrackerConfig {
36
+ /** Ruta de la landing page (ej: '/kin', '/racha') */
37
+ pagePath: string;
38
+ /** Nombre legible de la landing (ej: 'Kin Landing Page') */
39
+ pageName: string;
40
+ /** ID de Google Tag Manager (opcional) */
41
+ gtmId?: string;
42
+ /** Habilitar tracking de scroll (milestones 25/50/75/100%). Default: true */
43
+ enableScrollTracking?: boolean;
44
+ /** Habilitar tracking automático de clicks en CTAs. Default: true */
45
+ enableCTATracking?: boolean;
46
+ /** Habilitar tracking de tiempo en página. Default: true */
47
+ enableTimeTracking?: boolean;
48
+ /** Habilitar tracking de tiempo por sección (IntersectionObserver). Default: true */
49
+ enableSectionTracking?: boolean;
50
+ /** Habilitar auto-tracking de formularios. Default: true */
51
+ enableFormTracking?: boolean;
52
+ /** Habilitar heatmap de clicks (coordenadas X/Y). Default: false */
53
+ enableHeatmap?: boolean;
54
+ /** Sufijo personalizado para eventos (ej: '_kin' para 'cta_click_kin'). Default: '' */
55
+ eventSuffix?: string;
56
+ }
57
+ /**
58
+ * Parámetros UTM capturados de la URL.
59
+ */
60
+ interface UTMParams {
61
+ utm_source?: string;
62
+ utm_medium?: string;
63
+ utm_campaign?: string;
64
+ utm_term?: string;
65
+ utm_content?: string;
66
+ }
67
+ /**
68
+ * Datos de identificación del visitante capturados.
69
+ */
70
+ interface VisitorData {
71
+ userId?: string;
72
+ userName?: string;
73
+ utmParams?: UTMParams;
74
+ entryTime: number;
75
+ entryUrl: string;
76
+ }
77
+ /**
78
+ * Estadísticas de reproducción de un video.
79
+ * Compartido entre todos los adaptadores (Wistia, Voomly, HTML5).
80
+ */
81
+ interface VideoStats {
82
+ /** Tiempo total reproducido en segundos */
83
+ timeWatched: number;
84
+ /** Si el video fue completado (≥90-95%) */
85
+ completed: boolean;
86
+ /** Timestamp de la última actualización */
87
+ lastUpdate: number;
88
+ }
89
+ /**
90
+ * Estado interno detallado de tracking de un video.
91
+ * Usado internamente por VideoTracker.
92
+ */
93
+ interface VideoTrackingState {
94
+ videoId: string;
95
+ startTime: number;
96
+ totalWatchTime: number;
97
+ playCount: number;
98
+ pauseCount: number;
99
+ seekCount: number;
100
+ completionPercentage: number;
101
+ lastPlayTimestamp: number;
102
+ isPlaying: boolean;
103
+ currentTime: number;
104
+ duration: number;
105
+ pauseTimes: number[];
106
+ seekEvents: Array<{
107
+ from: number;
108
+ to: number;
109
+ }>;
110
+ progressMilestones: Set<number>;
111
+ playbackSpeed: number;
112
+ }
113
+ /**
114
+ * Opciones para los hooks de video en React.
115
+ */
116
+ interface UseVideoTrackingOptions {
117
+ /** ID único del video */
118
+ videoId: string;
119
+ /** Referencia al elemento <video> HTML (solo para HTML5) */
120
+ videoElement?: HTMLVideoElement | null;
121
+ /** Callback cuando el video se completa */
122
+ onComplete?: () => void;
123
+ /** Callback en milestones de progreso (25, 50, 75) */
124
+ onProgress?: (percentage: number) => void;
125
+ }
126
+ /**
127
+ * Callback para actualizaciones de video.
128
+ */
129
+ type VideoUpdateCallback = (stats: VideoStats) => void;
130
+ /**
131
+ * Objeto retornado por los adaptadores de video (Wistia, Voomly).
132
+ */
133
+ interface VideoTrackerHandle {
134
+ /** Obtener estadísticas actuales */
135
+ getStats: () => VideoStats;
136
+ /** Registrar callback de actualización. Retorna función para desregistrar. */
137
+ onUpdate: (cb: VideoUpdateCallback) => () => void;
138
+ /** Detener tracking y limpiar listeners */
139
+ stop: () => void;
140
+ }
141
+ /**
142
+ * Payload genérico de un evento de tracking.
143
+ */
144
+ interface TrackingEventData {
145
+ [key: string]: unknown;
146
+ }
147
+ /**
148
+ * Datos de un click capturado para heatmap.
149
+ */
150
+ interface ClickData {
151
+ x: number;
152
+ y: number;
153
+ element: string;
154
+ section: string;
155
+ timestamp: number;
156
+ viewportWidth: number;
157
+ viewportHeight: number;
158
+ }
159
+ /**
160
+ * Resumen de sesión al salir de la página.
161
+ */
162
+ interface SessionSummary {
163
+ duration: number;
164
+ scrollDepth: number;
165
+ clicks: number;
166
+ sectionsViewed: string[];
167
+ videoWatchTime: number;
168
+ formInteractions: number;
169
+ }
170
+ /**
171
+ * Configuración del cliente HTTP para persistencia.
172
+ * Se pasa a `initTrackingAPI()`.
173
+ */
174
+ interface TrackingAPIConfig {
175
+ /** URL base del API (ej: 'https://api.korex.com/api/v1') */
176
+ baseUrl: string;
177
+ /** Función que retorna el token de autenticación (ej: de localStorage) */
178
+ getAuthToken?: () => string | null;
179
+ /** Headers adicionales para cada petición */
180
+ getCustomHeaders?: () => Record<string, string>;
181
+ }
182
+ /**
183
+ * Modelo de tracking lead del backend.
184
+ */
185
+ interface TrackingLead {
186
+ id: number;
187
+ userName: string;
188
+ userEmail: string;
189
+ entryDate: string;
190
+ accessUrl: string;
191
+ videoTimeWatched: number;
192
+ videoCompleted: boolean;
193
+ leadId: number | null;
194
+ leadName: string;
195
+ leadEmail: string;
196
+ leadPhone: string;
197
+ leadStatus: string;
198
+ leadOrigin: string | null;
199
+ leadMessage: string | null;
200
+ leadRoledesired: string | null;
201
+ referringUserId: number | null;
202
+ status: boolean;
203
+ whatsappSent: boolean;
204
+ nameForm: string | null;
205
+ msgForm: string | null;
206
+ fieldData?: string;
207
+ leadPlatform?: string | null;
208
+ leadCampaign?: string | null;
209
+ createdAt: string;
210
+ dwellTime?: number;
211
+ }
212
+ /**
213
+ * Datos procesados de lead con tracking (respuesta de GET /leads/{id}/with-tracking).
214
+ */
215
+ interface LeadTrackingData {
216
+ videoVisto: boolean;
217
+ tiempoReproducido: string;
218
+ envioWhatsapp: boolean;
219
+ accessUrl?: string;
220
+ nameForm?: string;
221
+ msgForm?: string;
222
+ platform?: string;
223
+ aliasName?: string;
224
+ trackingId?: number;
225
+ videoTimeWatched?: number;
226
+ dwellTime?: number;
227
+ }
228
+ /**
229
+ * Datos de formulario para enviar con un lead.
230
+ */
231
+ interface LeadFormData {
232
+ nombre: string;
233
+ correo: string;
234
+ telefono: string;
235
+ countryLada?: string;
236
+ [key: string]: unknown;
237
+ }
238
+ /**
239
+ * Parámetros extraídos de la URL para detección de origen.
240
+ */
241
+ interface UrlParams {
242
+ userId: string;
243
+ idCampana: string;
244
+ utmContent: string;
245
+ fbclid: string;
246
+ nombreNetworker: string;
247
+ whatsapp: string;
248
+ pipelineId: string;
249
+ funnelId?: string;
250
+ metricId?: string;
251
+ utmSource?: string;
252
+ utmMedium?: string;
253
+ utmCampaign?: string;
254
+ leadCampaing?: string;
255
+ isOrganico?: boolean;
256
+ }
257
+ /**
258
+ * Resultado de la detección de origen de un lead.
259
+ */
260
+ interface LeadOrigin {
261
+ type: 'facebook' | 'organic';
262
+ endpoint: string;
263
+ params: UrlParams;
264
+ hasCampaign: boolean;
265
+ }
266
+ /**
267
+ * Respuesta del API al crear/enviar un tracking lead.
268
+ */
269
+ interface TrackingLeadResponse {
270
+ colaboradorAsignado?: {
271
+ telefono: string;
272
+ nombre: string;
273
+ [key: string]: unknown;
274
+ } | null;
275
+ trackingId?: number | string | null;
276
+ leadId?: number | string | null;
277
+ [key: string]: unknown;
278
+ }
279
+ /**
280
+ * Respuesta procesada de submitTrackingLead.
281
+ */
282
+ interface SubmitTrackingLeadResponse {
283
+ ok: boolean;
284
+ status: number;
285
+ data: TrackingLeadResponse | null;
286
+ }
287
+ /**
288
+ * Opciones adicionales al construir el body de la petición de lead.
289
+ */
290
+ interface BuildRequestBodyOptions {
291
+ nameForm?: string;
292
+ msgForm?: string;
293
+ status?: string;
294
+ whatsappSent?: boolean;
295
+ dwellTime?: number;
296
+ videoTimeWatched?: number;
297
+ videoCompleted?: boolean;
298
+ additionalFields?: Record<string, unknown>;
299
+ }
300
+ /**
301
+ * Configuración del DwellTimeTracker.
302
+ */
303
+ interface DwellTimeConfig {
304
+ /** ID del tracking data en el backend */
305
+ trackingDataId: number | string;
306
+ /** Habilitar tracking (default: true) */
307
+ enabled?: boolean;
308
+ /** Callback al enviar exitosamente */
309
+ onSuccess?: () => void;
310
+ /** Callback en caso de error */
311
+ onError?: (error: Error) => void;
312
+ }
313
+ declare global {
314
+ interface Window {
315
+ gtag?: (...args: unknown[]) => void;
316
+ dataLayer?: unknown[];
317
+ _wq?: Array<{
318
+ id: string;
319
+ onReady: (video: unknown) => void;
320
+ }>;
321
+ }
322
+ }
323
+
324
+ /**
325
+ * Core de Google Analytics 4
326
+ * Inicialización, tracking de eventos y captura de datos del visitante.
327
+ * Desacoplado de cualquier framework (Next.js, React, etc.)
328
+ */
329
+
330
+ /**
331
+ * Obtiene el GA Tracking ID actual.
332
+ * Si se configuró un `resolveTrackingId`, lo usa dinámicamente.
333
+ * Si no, usa el `trackingId` fijo de la config.
334
+ */
335
+ declare const getGATrackingId: () => string;
336
+ /**
337
+ * Inicializa Google Analytics con la configuración proporcionada.
338
+ *
339
+ * @example
340
+ * ```ts
341
+ * // Con ID fijo
342
+ * initGA({ trackingId: 'G-XXXXXXX' })
343
+ *
344
+ * // Con resolución dinámica
345
+ * initGA({
346
+ * resolveTrackingId: (path) => {
347
+ * if (path.startsWith('/kin')) return 'G-KIN-ID'
348
+ * return localStorage.getItem('user_GA_id') || 'G-DEFAULT'
349
+ * }
350
+ * })
351
+ * ```
352
+ */
353
+ declare const initGA: (config?: TrackingConfig) => void;
354
+ /**
355
+ * Reinicializa GA con un nuevo Tracking ID.
356
+ * Útil cuando el ID cambia dinámicamente (ej. login del usuario).
357
+ */
358
+ declare const reinitGA: (newTrackingId: string) => void;
359
+ /**
360
+ * Verificar si GA está inicializado
361
+ */
362
+ declare const isGAInitialized: () => boolean;
363
+ /**
364
+ * Extrae los parámetros UTM de la URL actual.
365
+ */
366
+ declare const captureUTMParams: () => UTMParams | null;
367
+ /**
368
+ * Captura el `user_id` desde la URL (?user_id=xxx).
369
+ * Lo cachea internamente para enviarlo en todos los eventos.
370
+ */
371
+ declare const captureUserIdFromURL: () => string | null;
372
+ /**
373
+ * Resuelve el nombre del usuario desde múltiples fuentes.
374
+ * Prioridad: URL > localStorage > null
375
+ */
376
+ declare const getUserName: () => string | null;
377
+ /**
378
+ * Obtiene el user_id cacheado.
379
+ */
380
+ declare const getUserId: () => string | null;
381
+ /**
382
+ * Establece manualmente el user_id (ej. después de login).
383
+ */
384
+ declare const setUserId: (userId: string) => void;
385
+ /**
386
+ * Establece manualmente el user_name.
387
+ */
388
+ declare const setUserName: (userName: string) => void;
389
+ /**
390
+ * Envía un pageview a GA4.
391
+ * Automáticamente incluye UTM params y user_id si están disponibles.
392
+ */
393
+ declare const trackPageView: (path: string) => void;
394
+ /**
395
+ * Envía un evento personalizado a GA4.
396
+ * Usa envío dual: `window.gtag()` + `ReactGA.event()`.
397
+ * Siempre incluye `user_id` y `user_name` como parámetros.
398
+ *
399
+ * @example
400
+ * ```ts
401
+ * trackEvent('CTA', 'click', 'Botón Hero', undefined, { section: 'hero' })
402
+ * ```
403
+ */
404
+ declare const trackEvent: (category: string, action: string, label?: string, value?: number, additionalData?: TrackingEventData) => void;
405
+ /**
406
+ * Resetea el estado interno (útil para tests y re-inicialización).
407
+ */
408
+ declare const resetAnalytics: () => void;
409
+
410
+ /**
411
+ * Google Tag Manager — Carga e inyección vanilla (sin Next.js)
412
+ * Proporciona pushToDataLayer e injectGTMScript.
413
+ */
414
+ /**
415
+ * Inyecta el script de Google Tag Manager en el <head> del documento.
416
+ * Equivalente al componente <Script> de Next.js, pero framework-agnostic.
417
+ *
418
+ * @param gtmId - ID de GTM (ej: 'GTM-5GMQNFMN')
419
+ *
420
+ * @example
421
+ * ```ts
422
+ * injectGTMScript('GTM-5GMQNFMN')
423
+ * ```
424
+ */
425
+ declare const injectGTMScript: (gtmId: string) => void;
426
+ /**
427
+ * Envía un evento al dataLayer de GTM.
428
+ *
429
+ * @param eventName - Nombre del evento
430
+ * @param data - Datos adicionales del evento
431
+ *
432
+ * @example
433
+ * ```ts
434
+ * pushToDataLayer('page_view', { page_path: '/kin' })
435
+ * pushToDataLayer('cta_click', { button_text: 'Únete', section: 'hero' })
436
+ * ```
437
+ */
438
+ declare const pushToDataLayer: (eventName: string, data?: Record<string, unknown>) => void;
439
+
440
+ /**
441
+ * VideoTracker — Tracking avanzado de video para GA4
442
+ * Gestiona el estado de reproducción por video y emite eventos a Google Analytics.
443
+ * Framework-agnostic (no requiere React).
444
+ */
445
+
446
+ declare class VideoTracker {
447
+ private videos;
448
+ private watchTimeIntervals;
449
+ /**
450
+ * Inicializa el tracking para un video.
451
+ */
452
+ initVideo(videoId: string): void;
453
+ /**
454
+ * Tracking de evento play.
455
+ */
456
+ trackPlay(videoId: string, currentTime?: number): void;
457
+ /**
458
+ * Tracking de evento pause.
459
+ */
460
+ trackPause(videoId: string, currentTime: number, duration?: number): void;
461
+ /**
462
+ * Tracking de evento seek (saltar en el timeline).
463
+ */
464
+ trackSeek(videoId: string, fromTime: number, toTime: number): void;
465
+ /**
466
+ * Tracking de progreso (milestones: 25%, 50%, 75%).
467
+ */
468
+ trackProgress(videoId: string, percentage: number, currentTime: number): void;
469
+ /**
470
+ * Tracking de completación del video (≥95%).
471
+ */
472
+ trackComplete(videoId: string, totalDuration: number): void;
473
+ /**
474
+ * Tracking de fin del video (evento ended nativo).
475
+ */
476
+ trackEnd(videoId: string): void;
477
+ /**
478
+ * Tracking de cambio de velocidad de reproducción.
479
+ */
480
+ trackSpeedChange(videoId: string, speed: number): void;
481
+ /**
482
+ * Tracking de pantalla completa.
483
+ */
484
+ trackFullscreen(videoId: string, isFullscreen: boolean): void;
485
+ /**
486
+ * Tracking de no interacción (el usuario está en la página pero no interactúa con el video).
487
+ */
488
+ trackNoInteraction(videoId: string, timeOnPage: number): void;
489
+ /**
490
+ * Obtiene el estado actual de un video.
491
+ */
492
+ getState(videoId: string): VideoTrackingState | undefined;
493
+ /**
494
+ * Limpia el tracking de un video específico.
495
+ */
496
+ cleanup(videoId: string): void;
497
+ /**
498
+ * Limpia todo el tracking.
499
+ */
500
+ cleanupAll(): void;
501
+ private getOrCreateState;
502
+ private startWatchTimeTracking;
503
+ private stopWatchTimeTracking;
504
+ }
505
+ /**
506
+ * Instancia singleton del VideoTracker.
507
+ * Usar cuando se necesita una sola instancia global.
508
+ */
509
+ declare const videoTracker: VideoTracker;
510
+
511
+ /**
512
+ * Funciones genéricas de tracking de eventos para GA4.
513
+ * Cada función es una abstracción de `trackEvent()` con categoría y acción predefinidas.
514
+ */
515
+
516
+ declare const trackCTAClick: (buttonName: string, section: string, additionalData?: TrackingEventData) => void;
517
+ declare const trackFormStart: (formName: string) => void;
518
+ declare const trackFormFieldComplete: (formName: string, fieldName: string) => void;
519
+ declare const trackFormSubmit: (formName: string, success: boolean, additionalData?: TrackingEventData) => void;
520
+ declare const trackFormValidationError: (formName: string, fieldName: string, errorMessage: string) => void;
521
+ declare const trackConversion: (conversionType: string, value?: number, additionalData?: TrackingEventData) => void;
522
+ declare const trackSocialClick: (platform: string, action: string, additionalData?: TrackingEventData) => void;
523
+ declare const trackFAQExpand: (question: string, index: number) => void;
524
+ declare const trackImageClick: (imageName: string, section: string) => void;
525
+ declare const trackTimeInSection: (sectionName: string, seconds: number) => void;
526
+ declare const trackSectionClick: (section: string) => void;
527
+ declare const trackScrollTo: (section: string) => void;
528
+ declare const trackPricingCardClick: (productName: string, price: number | string, additionalData?: TrackingEventData) => void;
529
+ declare const trackContactClick: (method: string) => void;
530
+ declare const trackShare: (platform: string, content: string) => void;
531
+ declare const trackDownload: (fileName: string, fileType: string) => void;
532
+
533
+ /**
534
+ * Adaptador de video Wistia
535
+ * Detecta automáticamente el SDK de Wistia y se enlaza a sus eventos.
536
+ * Framework-agnostic.
537
+ */
538
+
539
+ /**
540
+ * Inicia tracking de un video Wistia por su Media ID.
541
+ * Detecta si el player es Wistia nativo o un <video> HTML5.
542
+ * Retorna un handle con getStats(), onUpdate() y stop().
543
+ *
544
+ * @example
545
+ * ```ts
546
+ * const tracker = await trackWistiaByMediaId('abc123')
547
+ * tracker.onUpdate((stats) => {
548
+ * console.log(stats.timeWatched, stats.completed)
549
+ * })
550
+ * // Al desmontar:
551
+ * tracker.stop()
552
+ * ```
553
+ */
554
+ declare const trackWistiaByMediaId: (mediaId: string) => Promise<VideoTrackerHandle | null>;
555
+
556
+ /**
557
+ * Adaptador de video Voomly
558
+ * Usa 3 estrategias complementarias para trackear videos embebidos de Voomly.
559
+ * Framework-agnostic.
560
+ */
561
+
562
+ /**
563
+ * Inicia tracking de un video Voomly por su Embed ID.
564
+ * Usa 3 estrategias complementarias:
565
+ * 1. Scan periódico del DOM (cada 2s) buscando <video> dentro del embed
566
+ * 2. Polling de respaldo (cada 1s) leyendo .currentTime
567
+ * 3. Eventos globales de window (voomly:video:*)
568
+ *
569
+ * @example
570
+ * ```ts
571
+ * const tracker = await trackVoomlyByEmbedId('my-voomly-id')
572
+ * tracker.onUpdate((stats) => console.log(stats))
573
+ * // IMPORTANTE: llamar stop() al desmontar para evitar memory leaks
574
+ * tracker.stop()
575
+ * ```
576
+ */
577
+ declare const trackVoomlyByEmbedId: (embedId: string) => Promise<VideoTrackerHandle | null>;
578
+
579
+ /**
580
+ * Adaptador de video HTML5 nativo
581
+ * Tracking puro de elementos <video> sin dependencia de React.
582
+ */
583
+
584
+ /**
585
+ * Inicia tracking de un elemento <video> HTML5 nativo.
586
+ * Escucha eventos estándar del Video API del navegador.
587
+ *
588
+ * @example
589
+ * ```ts
590
+ * const video = document.querySelector('video')
591
+ * const tracker = trackHTML5Video('hero-video', video)
592
+ * tracker.onUpdate((stats) => console.log(stats))
593
+ * // Al desmontar:
594
+ * tracker.stop()
595
+ * ```
596
+ */
597
+ declare const trackHTML5Video: (videoId: string, videoElement: HTMLVideoElement) => VideoTrackerHandle;
598
+
599
+ /**
600
+ * LandingTracker — Orquestador de sesión completa
601
+ * Inicializa y gestiona scroll tracking, click heatmap, section dwell time,
602
+ * form auto-tracking y sesión start/end.
603
+ * Framework-agnostic.
604
+ */
605
+
606
+ declare class LandingTracker {
607
+ private config;
608
+ private isInitialized;
609
+ private sessionStartTime;
610
+ private scrollMilestonesReached;
611
+ private clicks;
612
+ private sectionTimers;
613
+ private observers;
614
+ private listeners;
615
+ /**
616
+ * Inicializa el tracking de la landing con la configuración dada.
617
+ */
618
+ init(config: LandingTrackerConfig): void;
619
+ /**
620
+ * Destruye el tracker y limpia todos los observers y listeners.
621
+ */
622
+ destroy(): void;
623
+ /** Trackear click en un CTA */
624
+ trackCTAClick(buttonName: string, section: string, additionalData?: Record<string, unknown>): void;
625
+ /** Trackear conversión */
626
+ trackConversion(type: string, value?: number, additionalData?: Record<string, unknown>): void;
627
+ /** Trackear click en FAQs */
628
+ trackFAQExpand(question: string, index: number): void;
629
+ /** Trackear click social */
630
+ trackSocialClick(platform: string, action: string): void;
631
+ /** Trackear click en imagen */
632
+ trackImageClick(imageName: string, section: string): void;
633
+ /** Trackear scroll a sección */
634
+ trackScrollTo(section: string): void;
635
+ /** Trackear share */
636
+ trackShare(platform: string, content: string): void;
637
+ /** Trackear descarga */
638
+ trackDownload(fileName: string, fileType: string): void;
639
+ /** Obtener datos de la sesión actual */
640
+ getSessionData(): {
641
+ duration: number;
642
+ clicks: number;
643
+ scrollMilestones: number[];
644
+ };
645
+ private captureInitialData;
646
+ private trackSessionStart;
647
+ private getEventName;
648
+ private pushGTMEvent;
649
+ private addListener;
650
+ private initScrollTracking;
651
+ private initCTATracking;
652
+ private initTimeTracking;
653
+ private initSectionTracking;
654
+ private initFormTracking;
655
+ private initClickHeatmap;
656
+ }
657
+ /**
658
+ * Factory function para crear un LandingTracker.
659
+ *
660
+ * @example
661
+ * ```ts
662
+ * const tracker = createLandingTracker({
663
+ * pagePath: '/kin',
664
+ * pageName: 'Kin Landing Page',
665
+ * gtmId: 'GTM-5GMQNFMN',
666
+ * })
667
+ * // Al desmontar:
668
+ * tracker.destroy()
669
+ * ```
670
+ */
671
+ declare const createLandingTracker: (config: LandingTrackerConfig) => LandingTracker;
672
+
673
+ /**
674
+ * API Client — Cliente HTTP configurable para persistencia al backend.
675
+ * Framework-agnostic. Usa fetch nativo.
676
+ *
677
+ * @example
678
+ * ```ts
679
+ * import { initTrackingAPI } from '@metodokorexmk/tracking';
680
+ *
681
+ * initTrackingAPI({
682
+ * baseUrl: 'https://api.korex.com/api/v1',
683
+ * getAuthToken: () => localStorage.getItem('access_token'),
684
+ * });
685
+ * ```
686
+ */
687
+
688
+ /**
689
+ * Inicializa el cliente HTTP para la capa de persistencia.
690
+ * Debe llamarse antes de usar funciones de lead submission, dwell time o queries.
691
+ */
692
+ declare const initTrackingAPI: (config: TrackingAPIConfig) => void;
693
+ /**
694
+ * Verifica si el API client ha sido inicializado.
695
+ */
696
+ declare const isTrackingAPIInitialized: () => boolean;
697
+
698
+ /**
699
+ * Lead Submission — Creación y actualización de leads en el backend.
700
+ * Migrado de lead-origin-detector.ts, framework-agnostic.
701
+ */
702
+
703
+ /**
704
+ * Extrae todos los parámetros relevantes de la URL.
705
+ *
706
+ * @param url - URL opcional (si no se proporciona, usa window.location)
707
+ * @returns Objeto con todos los parámetros extraídos
708
+ */
709
+ declare const extractUrlParams: (url?: string) => UrlParams;
710
+ /**
711
+ * Detecta el origen del lead basándose en los parámetros de la URL.
712
+ * Facebook Ads: tiene fbclid O campaign_id
713
+ * Orgánico: tiene whatsapp Y NO tiene fbclid Y NO tiene campaign_id
714
+ */
715
+ declare const detectLeadOrigin: (url?: string) => LeadOrigin;
716
+ /**
717
+ * Construye el body de la petición según el tipo de origen.
718
+ */
719
+ declare const buildTrackingRequestBody: (params: UrlParams, formData: LeadFormData, origin: LeadOrigin, options?: BuildRequestBodyOptions) => Record<string, unknown>;
720
+ /**
721
+ * Envía el lead al endpoint correcto según su origen.
722
+ */
723
+ declare const submitTrackingLead: (body: Record<string, unknown>, origin: LeadOrigin) => Promise<SubmitTrackingLeadResponse>;
724
+ /**
725
+ * Función completa: detecta origen, construye body y envía el lead.
726
+ *
727
+ * @example
728
+ * ```ts
729
+ * const result = await submitLead(
730
+ * { nombre: 'Juan', correo: 'juan@mail.com', telefono: '+34600...' },
731
+ * { nameForm: 'Formulario Kin', videoCompleted: true },
732
+ * );
733
+ * ```
734
+ */
735
+ declare const submitLead: (formData: LeadFormData, options?: BuildRequestBodyOptions, url?: string) => Promise<SubmitTrackingLeadResponse>;
736
+ /**
737
+ * Actualiza un lead existente mediante PATCH.
738
+ */
739
+ declare const updateTrackingLead: (trackingId: number | string, updates: Record<string, unknown>) => Promise<boolean>;
740
+ /**
741
+ * Marca un lead como "WhatsApp enviado".
742
+ */
743
+ declare const markWhatsAppSent: (leadId: number | string) => Promise<boolean>;
744
+ /**
745
+ * Construye un msgForm como JSON stringificado.
746
+ */
747
+ declare const buildMsgFormJSON: (mensaje: string, datosAdicionales?: Record<string, unknown>) => string;
748
+
749
+ /**
750
+ * DwellTimeTracker — Tracking de tiempo de permanencia con envío periódico al backend.
751
+ * Migrado de dwell-time.ts (~960 líneas → ~280 líneas limpias).
752
+ * Framework-agnostic.
753
+ */
754
+
755
+ /**
756
+ * Clase que mide el tiempo de permanencia del usuario en una página
757
+ * y lo envía periódicamente al backend de tracking.
758
+ *
759
+ * Características:
760
+ * - Envío automático cada 30 segundos
761
+ * - Pausa automática cuando la pestaña se oculta
762
+ * - sendBeacon en beforeunload para máxima confiabilidad
763
+ * - Retry de updates pendientes via sessionStorage
764
+ * - Tracking de video integrado (videoTimeWatched, videoCompleted)
765
+ */
766
+ declare class DwellTimeTracker {
767
+ private startTime;
768
+ private trackingDataId;
769
+ private enabled;
770
+ private onSuccess?;
771
+ private onError?;
772
+ private intervalId;
773
+ private isSending;
774
+ private videoTimeWatched;
775
+ private videoCompleted;
776
+ private videoTrackingStopped;
777
+ private lastDwellTimeSent;
778
+ private lastVideoTimeSent;
779
+ private pausedTime;
780
+ private pauseStartTime;
781
+ private boundBeforeUnload;
782
+ private boundVisibilityChange;
783
+ constructor();
784
+ /**
785
+ * Inicia el tracking del tiempo de permanencia.
786
+ */
787
+ start(config: DwellTimeConfig): void;
788
+ /**
789
+ * Detiene el tracking y envía el tiempo acumulado.
790
+ */
791
+ stop(): void;
792
+ /**
793
+ * Obtiene el tiempo transcurrido en segundos (restando tiempo pausado).
794
+ */
795
+ getElapsedTime(): number;
796
+ /**
797
+ * Actualiza manualmente el tiempo del video.
798
+ * Llamar desde el VideoTracker u otros adaptadores.
799
+ */
800
+ updateVideoTime(videoTimeWatched: number, videoCompleted?: boolean): void;
801
+ /**
802
+ * Actualiza el trackingDataId (útil cuando se obtiene después del registro).
803
+ */
804
+ updateTrackingId(trackingDataId: number | string): void;
805
+ /**
806
+ * Limpia todos los listeners y timers.
807
+ */
808
+ destroy(): void;
809
+ private checkLocalStorageForId;
810
+ private sendDwellTime;
811
+ private handleBeforeUnload;
812
+ private handleVisibilityChange;
813
+ private sendDwellTimeWithBeacon;
814
+ private savePendingUpdate;
815
+ private retryPendingUpdates;
816
+ private clearPendingUpdate;
817
+ private cleanupListeners;
818
+ private cleanup;
819
+ }
820
+ declare const dwellTimeTracker: DwellTimeTracker;
821
+ /**
822
+ * Inicia el tracking del tiempo de permanencia.
823
+ */
824
+ declare const startDwellTimeTracking: (config: DwellTimeConfig) => void;
825
+ /**
826
+ * Detiene el tracking y envía el tiempo acumulado.
827
+ */
828
+ declare const stopDwellTimeTracking: () => void;
829
+
830
+ /**
831
+ * Tracking Queries — Consultas GET al backend de tracking.
832
+ * Migrado de TrackingService.ts y LeadTrackingService.ts.
833
+ * Framework-agnostic.
834
+ */
835
+
836
+ /**
837
+ * Obtiene los datos de un tracking lead por su ID.
838
+ *
839
+ * @example
840
+ * ```ts
841
+ * const tracking = await getTrackingById(123);
842
+ * console.log(tracking.videoTimeWatched, tracking.dwellTime);
843
+ * ```
844
+ */
845
+ declare const getTrackingById: (trackingId: number | string) => Promise<TrackingLead>;
846
+ /**
847
+ * Obtiene un lead con sus datos de tracking asociados.
848
+ * Procesa la respuesta para extraer videoVisto, tiempoReproducido, etc.
849
+ *
850
+ * @example
851
+ * ```ts
852
+ * const data = await getLeadWithTracking('456');
853
+ * console.log(data.videoVisto, data.dwellTime);
854
+ * ```
855
+ */
856
+ declare const getLeadWithTracking: (leadId: string) => Promise<LeadTrackingData>;
857
+ /**
858
+ * Genera un link de tracking para un funnel.
859
+ *
860
+ * @example
861
+ * ```ts
862
+ * const { link } = await generateTrackingLink(1, 'mi-dominio.com');
863
+ * ```
864
+ */
865
+ declare const generateTrackingLink: (funnelId: number, customDomain: string) => Promise<{
866
+ link: string;
867
+ }>;
868
+
869
+ export { type BuildRequestBodyOptions, type ClickData, type DwellTimeConfig, DwellTimeTracker, LandingTracker, type LandingTrackerConfig, type LeadFormData, type LeadOrigin, type LeadTrackingData, type SessionSummary, type SubmitTrackingLeadResponse, type TrackingAPIConfig, type TrackingConfig, type TrackingEventData, type TrackingLead, type TrackingLeadResponse, type UTMParams, type UrlParams, type UseVideoTrackingOptions, type VideoStats, VideoTracker, type VideoTrackerHandle, type VideoTrackingState, type VideoUpdateCallback, type VisitorData, buildMsgFormJSON, buildTrackingRequestBody, captureUTMParams, captureUserIdFromURL, createLandingTracker, detectLeadOrigin, dwellTimeTracker, extractUrlParams, generateTrackingLink, getGATrackingId, getLeadWithTracking, getTrackingById, getUserId, getUserName, initGA, initTrackingAPI, injectGTMScript, isGAInitialized, isTrackingAPIInitialized, markWhatsAppSent, pushToDataLayer, reinitGA, resetAnalytics, setUserId, setUserName, startDwellTimeTracking, stopDwellTimeTracking, submitLead, submitTrackingLead, trackCTAClick, trackContactClick, trackConversion, trackDownload, trackEvent, trackFAQExpand, trackFormFieldComplete, trackFormStart, trackFormSubmit, trackFormValidationError, trackHTML5Video, trackImageClick, trackPageView, trackPricingCardClick, trackScrollTo, trackSectionClick, trackShare, trackSocialClick, trackTimeInSection, trackVoomlyByEmbedId, trackWistiaByMediaId, updateTrackingLead, videoTracker };