Identificar usuarios - Device Data Collector

La librería Conekta Device Data Collector permite obtener un sessionId único que identifica a un usuario mediante el fingerprint de su dispositivo. Este sessionId es útil para análisis de fraude, seguimiento de sesiones y seguridad.

📋 Tabla de Contenidos


Instalación

NPM / Yarn

npm install conekta-device-data-collector
# o
yarn add conekta-device-data-collector

CDN

<script src="https://unpkg.com/conekta-device-data-collector/dist/index.umd.min.js"></script>

Configuración Básica

La librería requiere una configuración mínima para funcionar:

const config = {
  publicKey: 'key_xxxxxxxxxxxxxxxxxxxx', // Tu public key de Conekta
  metadata: {
    source: 'my_company',
    page: 'checkout'
  }
};

Parámetros de Configuración

ParámetroTipoRequeridoDescripción
publicKeystring✅ SíTu public key de Conekta
metadataobject❌ NoMetadatos adicionales para el tracking

Obtener Session ID

El proceso para obtener el sessionId consta de dos pasos:

  1. Inicializar el collector con init()
  2. Obtener el session ID con getSessionId()
// 1. Inicializar
await conektaDeviceDataCollector.init(config);

// 2. Obtener Session ID
const sessionId = conektaDeviceDataCollector.getSessionId();
console.log('Session ID:', sessionId);
⚠️

Importante: Debes llamar a init() antes de usar getSessionId(). El sessionId se genera automáticamente si no proporcionas uno personalizado.


Ejemplos por Framework

Vanilla JavaScript (CDN)

Este es el método más simple para integrar la librería sin un bundler.

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Device Data Collector - CDN</title>
</head>
<body>
    <h1>Obtener Session ID</h1>
    <button id="initBtn">Inicializar Collector</button>
    <button id="getSessionBtn" disabled>Obtener Session ID</button>
    <p id="sessionId"></p>

    <!-- Cargar la librería desde CDN -->
    <script src="https://unpkg.com/conekta-device-data-collector/dist/index.umd.min.js"></script>
    
    <script>
        const config = {
            publicKey: 'key_xxxxxxxxxxxxxxxxxxxx',
            metadata: {
                source: 'my_company',
                page: 'checkout'
            }
        };

        let isInitialized = false;

        // Inicializar el collector
        document.getElementById('initBtn').addEventListener('click', async () => {
            try {
                await ConektaDeviceDataCollector.init(config);
                isInitialized = true;
                document.getElementById('getSessionBtn').disabled = false;
                console.log('✅ Collector inicializado correctamente');
            } catch (error) {
                console.error('❌ Error al inicializar:', error);
            }
        });

        // Obtener Session ID
        document.getElementById('getSessionBtn').addEventListener('click', () => {
            if (!isInitialized) {
                console.error('El collector no ha sido inicializado');
                return;
            }

            try {
                const sessionId = ConektaDeviceDataCollector.getSessionId();
                document.getElementById('sessionId').textContent = `Session ID: ${sessionId}`;
                console.log('🆔 Session ID:', sessionId);
            } catch (error) {
                console.error('❌ Error al obtener Session ID:', error);
            }
        });

        // Opcional: Inicializar automáticamente al cargar la página
        window.addEventListener('load', async () => {
            try {
                await ConektaDeviceDataCollector.init(config);
                isInitialized = true;
                document.getElementById('getSessionBtn').disabled = false;
            } catch (error) {
                console.error('Error al inicializar:', error);
            }
        });
    </script>
</body>
</html>

React

Ejemplo completo usando React con hooks.

import { useEffect, useState } from 'react';
import conektaDeviceDataCollector from 'conekta-device-data-collector';

const config = {
  publicKey: 'key_xxxxxxxxxxxxxxxxxxxx',
  metadata: {
    source: 'my_company',
    page: 'checkout'
  }
};

function App() {
  const [sessionId, setSessionId] = useState<string>('');
  const [isInitialized, setIsInitialized] = useState<boolean>(false);
  const [error, setError] = useState<string | null>(null);

  // Inicializar el collector al montar el componente
  useEffect(() => {
    const initializeCollector = async () => {
      try {
        await conektaDeviceDataCollector.init(config);
        setIsInitialized(true);
        setError(null);
      } catch (err) {
        setError(err instanceof Error ? err.message : 'Error desconocido');
        console.error('Error al inicializar collector:', err);
      }
    };

    initializeCollector();

    // Cleanup: destruir el collector al desmontar
    return () => {
      conektaDeviceDataCollector.destroy();
    };
  }, []);

  // Función para obtener el Session ID
  const getSessionId = () => {
    try {
      if (!isInitialized) {
        setError('El collector no ha sido inicializado');
        return;
      }

      const id = conektaDeviceDataCollector.getSessionId();
      setSessionId(id);
      setError(null);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Error al obtener Session ID');
      console.error('Error al obtener Session ID:', err);
    }
  };

  return (
    <div>
      <h1>Conekta Device Data Collector</h1>
      
      <div>
        <p>Estado: {isInitialized ? '✅ Inicializado' : '⏳ Inicializando...'}</p>
        
        <button 
          onClick={getSessionId} 
          disabled={!isInitialized}
        >
          Obtener Session ID
        </button>
        
        {sessionId && (
          <div>
            <p><strong>Session ID:</strong></p>
            <code>{sessionId}</code>
          </div>
        )}
        
        {error && (
          <div style={{ color: 'red' }}>
            <p>Error: {error}</p>
          </div>
        )}
      </div>
    </div>
  );
}

export default App;

Hook personalizado para React

Puedes crear un hook reutilizable:

import { useEffect, useState, useCallback } from 'react';
import conektaDeviceDataCollector from 'conekta-device-data-collector';

interface UseDeviceDataCollectorConfig {
  publicKey: string;
  metadata?: Record<string, any>;
  conektaDeviceCollectorUrl?: string;
}

export function useDeviceDataCollector(config: UseDeviceDataCollectorConfig) {
  const [sessionId, setSessionId] = useState<string>('');
  const [isInitialized, setIsInitialized] = useState<boolean>(false);
  const [error, setError] = useState<string | null>(null);

  const initialize = useCallback(async () => {
    try {
      await conektaDeviceDataCollector.init(config);
      setIsInitialized(true);
      setError(null);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Error desconocido');
      throw err;
    }
  }, [config]);

  const getSessionId = useCallback(() => {
    try {
      if (!isInitialized) {
        throw new Error('El collector no ha sido inicializado');
      }
      const id = conektaDeviceDataCollector.getSessionId();
      setSessionId(id);
      return id;
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : 'Error al obtener Session ID';
      setError(errorMessage);
      throw err;
    }
  }, [isInitialized]);

  useEffect(() => {
    initialize();

    return () => {
      conektaDeviceDataCollector.destroy();
    };
  }, [initialize]);

  return {
    sessionId,
    isInitialized,
    error,
    getSessionId,
    initialize
  };
}

// Uso del hook
function MyComponent() {
  const { sessionId, isInitialized, error, getSessionId } = useDeviceDataCollector({
    publicKey: 'key_xxxxxxxxxxxxxxxxxxxx',
    metadata: { source: 'my_company', page: 'checkout' }
  });

  return (
    <div>
      <button onClick={getSessionId} disabled={!isInitialized}>
        Obtener Session ID
      </button>
      {sessionId && <p>Session ID: {sessionId}</p>}
      {error && <p style={{ color: 'red' }}>Error: {error}</p>}
    </div>
  );
}

Vue.js

Ejemplo usando Vue 3 con Composition API.

<template>
  <div>
    <h1>Conekta Device Data Collector</h1>
    
    <div>
      <p>Estado: {{ isInitialized ? '✅ Inicializado' : '⏳ Inicializando...' }}</p>
      
      <button 
        @click="getSessionId" 
        :disabled="!isInitialized"
      >
        Obtener Session ID
      </button>
      
      <div v-if="sessionId">
        <p><strong>Session ID:</strong></p>
        <code>{{ sessionId }}</code>
      </div>
      
      <div v-if="error" style="color: red;">
        <p>Error: {{ error }}</p>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import conektaDeviceDataCollector from 'conekta-device-data-collector';

const config = {
  publicKey: 'key_xxxxxxxxxxxxxxxxxxxx',
  metadata: {
    source: 'my_company',
    page: 'checkout'
  }
};

const sessionId = ref<string>('');
const isInitialized = ref<boolean>(false);
const error = ref<string | null>(null);

// Inicializar el collector al montar el componente
onMounted(async () => {
  try {
    await conektaDeviceDataCollector.init(config);
    isInitialized.value = true;
    error.value = null;
  } catch (err) {
    error.value = err instanceof Error ? err.message : 'Error desconocido';
    console.error('Error al inicializar collector:', err);
  }
});

// Limpiar al desmontar
onUnmounted(() => {
  conektaDeviceDataCollector.destroy();
});

// Función para obtener el Session ID
const getSessionId = () => {
  try {
    if (!isInitialized.value) {
      error.value = 'El collector no ha sido inicializado';
      return;
    }

    const id = conektaDeviceDataCollector.getSessionId();
    sessionId.value = id;
    error.value = null;
  } catch (err) {
    error.value = err instanceof Error ? err.message : 'Error al obtener Session ID';
    console.error('Error al obtener Session ID:', err);
  }
};
</script>

Composable para Vue.js

Puedes crear un composable reutilizable:

// composables/useDeviceDataCollector.ts
import { ref, onMounted, onUnmounted } from 'vue';
import conektaDeviceDataCollector from 'conekta-device-data-collector';

interface UseDeviceDataCollectorConfig {
  publicKey: string;
  metadata?: Record<string, any>;
  conektaDeviceCollectorUrl?: string;
}

export function useDeviceDataCollector(config: UseDeviceDataCollectorConfig) {
  const sessionId = ref<string>('');
  const isInitialized = ref<boolean>(false);
  const error = ref<string | null>(null);

  const initialize = async () => {
    try {
      await conektaDeviceDataCollector.init(config);
      isInitialized.value = true;
      error.value = null;
    } catch (err) {
      error.value = err instanceof Error ? err.message : 'Error desconocido';
      throw err;
    }
  };

  const getSessionId = () => {
    try {
      if (!isInitialized.value) {
        throw new Error('El collector no ha sido inicializado');
      }
      const id = conektaDeviceDataCollector.getSessionId();
      sessionId.value = id;
      error.value = null;
      return id;
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : 'Error al obtener Session ID';
      error.value = errorMessage;
      throw err;
    }
  };

  onMounted(() => {
    initialize();
  });

  onUnmounted(() => {
    conektaDeviceDataCollector.destroy();
  });

  return {
    sessionId,
    isInitialized,
    error,
    getSessionId,
    initialize
  };
}

// Uso del composable
// <script setup>
// import { useDeviceDataCollector } from '@/composables/useDeviceDataCollector';
//
// const { sessionId, isInitialized, error, getSessionId } = useDeviceDataCollector({
//   publicKey: 'key_xxxxxxxxxxxxxxxxxxxx',
//   metadata: { source: 'my_company', page: 'checkout' }
// });
// </script>

Angular

Ejemplo usando Angular con servicios y componentes.

Servicio Angular

// services/device-data-collector.service.ts
import { Injectable } from '@angular/core';
import conektaDeviceDataCollector from 'conekta-device-data-collector';

export interface DeviceDataCollectorConfig {
  publicKey: string;
  metadata?: Record<string, any>;
  conektaDeviceCollectorUrl?: string;
}

@Injectable({
  providedIn: 'root'
})
export class DeviceDataCollectorService {
  private isInitialized = false;
  private sessionId: string | null = null;

  async initialize(config: DeviceDataCollectorConfig): Promise<void> {
    try {
      await conektaDeviceDataCollector.init(config);
      this.isInitialized = true;
    } catch (error) {
      console.error('Error al inicializar Device Data Collector:', error);
      throw error;
    }
  }

  getSessionId(): string {
    if (!this.isInitialized) {
      throw new Error('El collector no ha sido inicializado. Llama a initialize() primero.');
    }

    try {
      this.sessionId = conektaDeviceDataCollector.getSessionId();
      return this.sessionId;
    } catch (error) {
      console.error('Error al obtener Session ID:', error);
      throw error;
    }
  }

  destroy(): void {
    conektaDeviceDataCollector.destroy();
    this.isInitialized = false;
    this.sessionId = null;
  }

  getIsInitialized(): boolean {
    return this.isInitialized;
  }
}

Componente Angular

// components/device-data-collector.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { DeviceDataCollectorService } from '../services/device-data-collector.service';

@Component({
  selector: 'app-device-data-collector',
  template: `
    <div>
      <h1>Conekta Device Data Collector</h1>
      
      <div>
        <p>Estado: {{ isInitialized ? '✅ Inicializado' : '⏳ Inicializando...' }}</p>
        
        <button 
          (click)="onGetSessionId()" 
          [disabled]="!isInitialized"
        >
          Obtener Session ID
        </button>
        
        <div *ngIf="sessionId">
          <p><strong>Session ID:</strong></p>
          <code>{{ sessionId }}</code>
        </div>
        
        <div *ngIf="error" style="color: red;">
          <p>Error: {{ error }}</p>
        </div>
      </div>
    </div>
  `
})
export class DeviceDataCollectorComponent implements OnInit, OnDestroy {
  sessionId: string | null = null;
  isInitialized = false;
  error: string | null = null;

  private config = {
    publicKey: 'key_xxxxxxxxxxxxxxxxxxxx',
    metadata: {
      source: 'my_company',
      page: 'checkout'
    }
  };

  constructor(private deviceDataCollectorService: DeviceDataCollectorService) {}

  async ngOnInit(): Promise<void> {
    try {
      await this.deviceDataCollectorService.initialize(this.config);
      this.isInitialized = this.deviceDataCollectorService.getIsInitialized();
    } catch (error) {
      this.error = error instanceof Error ? error.message : 'Error desconocido';
      console.error('Error al inicializar:', error);
    }
  }

  onGetSessionId(): void {
    try {
      this.sessionId = this.deviceDataCollectorService.getSessionId();
      this.error = null;
    } catch (error) {
      this.error = error instanceof Error ? error.message : 'Error al obtener Session ID';
      console.error('Error al obtener Session ID:', error);
    }
  }

  ngOnDestroy(): void {
    this.deviceDataCollectorService.destroy();
  }
}

Módulo Angular (si usas módulos)

// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { DeviceDataCollectorComponent } from './components/device-data-collector.component';
import { DeviceDataCollectorService } from './services/device-data-collector.service';

@NgModule({
  declarations: [
    DeviceDataCollectorComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [
    DeviceDataCollectorService
  ],
  bootstrap: [DeviceDataCollectorComponent]
})
export class AppModule { }

API Reference

init(config?: Partial<DeviceDataCollectorCustomConfig>): Promise<void>

Inicializa el Device Data Collector con la configuración proporcionada.

Parámetros:

  • config (opcional): Objeto de configuración

Retorna: Promise<void>

Ejemplo:

await conektaDeviceDataCollector.init({
  publicKey: 'key_xxxxxxxxxxxxxxxxxxxx',
  metadata: { source: 'checkout' }
});

getSessionId(): string

Obtiene el Session ID actual. Debe llamarse después de init().

Retorna: string - El Session ID único del usuario

Lanza: Error si el collector no ha sido inicializado

Ejemplo:

const sessionId = conektaDeviceDataCollector.getSessionId();
console.log('Session ID:', sessionId);

on(event: string, listener: Function): void

Registra un listener para eventos del collector.

Eventos disponibles:

  • initialized: Se emite cuando el collector se inicializa correctamente
  • data_collected: Se emite cuando se recopila información del dispositivo
  • error: Se emite cuando ocurre un error

Ejemplo:

conektaDeviceDataCollector.on('initialized', (event) => {
  console.log('Collector inicializado:', event.data);
});

conektaDeviceDataCollector.on('error', (event) => {
  console.error('Error:', event.error);
});

off(event: string, listener: Function): void

Remueve un listener de eventos.

Ejemplo:

const handler = (event) => console.log(event);
conektaDeviceDataCollector.on('initialized', handler);
// ... más tarde
conektaDeviceDataCollector.off('initialized', handler);

destroy(): void

Destruye la instancia del collector y limpia recursos.

Ejemplo:

conektaDeviceDataCollector.destroy();

Manejo de Eventos

La librería emite eventos que puedes escuchar para reaccionar a diferentes estados:

// Evento: initialized
conektaDeviceDataCollector.on('initialized', (event) => {
  console.log('✅ Collector inicializado');
  console.log('Datos:', event.data);
  // event.data contiene información sobre la inicialización
});

// Evento: data_collected
conektaDeviceDataCollector.on('data_collected', (event) => {
  console.log('📊 Datos recopilados');
  console.log('Datos:', event.data);
  // event.data contiene los datos del dispositivo recopilados
});

// Evento: error
conektaDeviceDataCollector.on('error', (event) => {
  console.error('❌ Error:', event.error);
  // event.error contiene el objeto Error
});

Solución de Problemas

El Session ID es undefined o vacío

Problema: Llamas a getSessionId() antes de que init() complete.

Solución: Asegúrate de esperar a que init() se complete antes de obtener el Session ID:

// ❌ Incorrecto
conektaDeviceDataCollector.init(config);
const sessionId = conektaDeviceDataCollector.getSessionId(); // Puede ser undefined

// ✅ Correcto
await conektaDeviceDataCollector.init(config);
const sessionId = conektaDeviceDataCollector.getSessionId(); // Funciona correctamente

Error: "El collector no ha sido inicializado"

Problema: Intentas usar métodos del collector antes de inicializarlo.

Solución: Siempre inicializa el collector primero:

try {
  await conektaDeviceDataCollector.init(config);
  // Ahora puedes usar getSessionId()
  const sessionId = conektaDeviceDataCollector.getSessionId();
} catch (error) {
  console.error('Error:', error);
}

La librería no carga desde CDN

Problema: El script no se carga correctamente o hay conflictos.

Solución:

  1. Verifica que la URL del CDN sea correcta
  2. Asegúrate de que el script se carga antes de usarlo:
<script src="https://unpkg.com/conekta-device-data-collector/dist/index.umd.min.js"></script>
<script>
  // Espera a que la página cargue completamente
  window.addEventListener('load', async () => {
    await ConektaDeviceDataCollector.init(config);
  });
</script>