npm package: @sbxcloud/sbx-events-ts
Description: Sbx library to create events on sbx for different apps
Author: sbxcloud
Latest version: 1.0.5

# sbx-events-ts

Librería para construir la estructura de eventos que se enviará a un servicio de eventos externo. Esta librería NO envía los eventos; solo te ayuda a armar el payload con la metadata necesaria (app, módulo, user agent, etc.).

Importante: siempre debes inicializar el monitor de eventos con init() y crear la instancia de la clase con el formato indicado. De lo contrario, habrá errores.

## Instalación

- npm: `npm install sbx-events-ts`
- yarn: `yarn add sbx-events-ts`

## Conceptos clave

- name: nombre de la aplicación principal. Ej: "crm_web".
- module: subaplicación o módulo dentro de la app. Ej: "sbx-crm-omnichannel", "sbx-crm-studio", etc.

Ambos son obligatorios al construir la clase. Si no se proveen, el constructor lanzará un error.

## Inicialización obligatoria

Debes crear una única instancia de TrackEvent y llamar a init() al iniciar tu app (bootstrap). Ejemplo recomendado:

```ts
// monitor/TrackEventMonitor.ts
import { TrackSbxEvent } from 'sbx-events-ts/core/TrackEventClass';

export const TrackEventMonitor = new TrackSbxEvent({
  name: 'crm_web',
  module: 'sbx-crm-omnichannel',
});

// Inicializar (idealmente al arrancar la app)
await TrackEventMonitor.init({ detectDevice: true });
```

Notas:
- Si no llamas a init(), la metadata de user agent e información de dispositivo no se establecerá y puede provocar errores en el servicio que consume el evento.
- detectDevice por defecto es true. En entornos SSR o Node donde no hay `navigator`, puedes usar `init({ detectDevice: false })`.

## Uso básico: construir un evento (simplificado)

Una vez inicializado, puedes seguir este patrón simplificado (ejemplo real):

```ts
import { TrackSbxEvent } from 'sbx-events-ts';

export const TrackEventMonitor = new TrackSbxEvent({
  name: 'crm_web',
  module: 'sbx-crm-omnichannel',
});

// En algún punto donde conoces al usuario y otros metadatos
let metadataExtra: { [key: string]: string | undefined } = {
  user_key: user.user_key || undefined,
  user_email: user.email,
};

TrackEventMonitor.setMetadataExtra({ ...metadataExtra });
TrackEventMonitor.setUser({
  user_id: user.user_id || user.id,
});

// Utilidad para construir eventos
type SbxEvent = { props: { [key: string]: any }; name: string; extra?: { [key: string]: any } };

export const sendSbxEvent = ({ props, name, extra }: SbxEvent) => {
  return TrackEventMonitor.getEventData({
    props: { ...props },
    // Puedes omitir "extra" si no lo necesitas
    metadata: { name, ...extra }, // cualquier campo adicional en metadata se fusiona en meta.extra
  });
};
```

// eventPayload tiene la forma:
// {
//   props: { ... },
//   extra: { ... },
//   meta: {
//     name: 'crm.contact.create',
//     extra: {
//       trackCode: {
//         app: { name: 'crm_web', module: 'sbx-crm-omnichannel' },
//         ip?: string,
//         user_agent?: string,
//         user_agent_info?: any
//       },
//       pathname?: string,
//       ...args
//     },
//     user?: number,
//     created: Date
//   }
// }

// Enviar al servicio externo
await miClienteHTTP.post('/events', eventPayload);
```

La función getEventData no envía nada: solo construye el objeto listo para enviar. Esto permite que tú decidas qué cliente HTTP usar, manejo de errores, reintentos, etc.

## API disponible

Clase TrackEvent (importar desde 'sbx-events-ts/core/TrackEventClass'):
- constructor(app: { name: string; module: string }): obliga a definir nombre y módulo de la app.
- init(options?: { detectDevice?: boolean }): detecta device y user agent (si es posible en el entorno) y marca el monitor como listo.
- getEventData({ props, extra, metadata }): devuelve el payload del evento.
- setUser({ user_id: number }): asigna el usuario a la metadata del evento.
- getUser(): obtiene el user_id actual almacenado en la instancia.
- setUserIp(ip: string): establece la IP dentro de trackCode.
- setUserAgent(ua: string): establece el UA manualmente (si lo necesitas).
- setUserAgentInfo(info: any): establece la info de UA manualmente.
- setMetadataExtra(data: any): fusiona datos adicionales dentro de meta.extra.
- log(): imprime en consola la metadata y props actuales (útil para debugging).

## Ejemplo de patrón de uso en una app

```ts
// monitor/TrackEventMonitor.ts
import { TrackSbxEvent } from 'sbx-events-ts/core/TrackEventClass';

export const TrackEventMonitor = new TrackSbxEvent({
  name: 'crm_web',
  module: 'sbx-crm-omnichannel',
});

export async function initEvents() {
  await TrackEventMonitor.init({ detectDevice: true });
}
```

```ts
// main.ts (bootstrap de la app)
import { initEvents } from './monitor/TrackEventMonitor';

await initEvents();
```

```ts
// donde quieras construir y enviar un evento
import { TrackEventMonitor } from './monitor/TrackEventMonitor';

const payload = TrackEventMonitor.getEventData({
  props: { action: 'lead_updated', lead_id: 555 },
  metadata: { name: 'crm.lead.update' },
});

await miClienteHTTP.post('/events', payload);
```

## Errores comunes

- Error: "App name is required" o "App module is required":
  - Asegúrate de crear el monitor con `{ name: 'crm_web', module: 'sbx-crm-...' }`.
- No se registra user agent o device:
  - Verifica que llamaste a `await TrackEventMonitor.init()` y que tu entorno permite acceder a `navigator.userAgent`. En SSR, usar `init({ detectDevice: false })`.

## Tipos

- AppData: `{ name: string; module: string }`
- EventMeta: `{ name?: string; extra?: { trackCode: { app: AppData; ip?: string; user_agent?: string; user_agent_info?: any }; pathname?: string }; user?: number; created?: Date; from_beta?: boolean }`

## Notas finales

- Esta librería no realiza la publicación del evento. Eres responsable de enviar el payload devuelto por `getEventData` al servicio correspondiente.
- Mantén una única instancia de TrackEvent compartida en tu app para conservar contexto (usuario, ip, etc.).