Cómo integrar Metricalp con aplicaciones móviles

Desde que lanzamos Metricalp, todos siempre han preguntado por el soporte para plataformas móviles. Tenían razón, los navegadores móviles y las aplicaciones móviles están superando a la plataforma web. Por lo tanto, estamos felices de anunciar que estamos en camino de soportar plataformas móviles. Actualmente, tenemos SDKs oficiales para React Native, Android y iOS .

Te preguntarás, ¿cómo es posible usar Metricalp con una aplicación móvil sin una biblioteca oficial? La respuesta es simple, porque Metricalp ha sido diseñado de manera completamente centrada en la API. Entonces, en realidad, crear un evento Metricalp es solo una solicitud HTTP POST. Esta es la forma en la web, móvil o cualquier otra plataforma. Detrás de escena, todas las bibliotecas de integración utilizan este método, simplemente enviando una solicitud HTTP POST. Así que puedes usar Metricalp incluso con tu lavadora inteligente si quieres desde el primer día. Aquí está la solicitud HTTP POST del evento que se utiliza en la biblioteca React Native como ejemplo, y luego describiremos cada detalle de ella a continuación:

tsx
   fetch(attributes.endpoint || Metricalp.API_ENDPOINT, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            type,
            path: attributes.path || '(no establecido)',
            metr_collected_via: attributes.platform,
            metr_os_detail: attributes.os || '(no establecido)',
            metr_app_detail: attributes.app || '(no establecido)',
            metr_user_language: attributes.language || '(no establecido)',
            metr_unique_identifier: attributes.uuid || '',
            metr_bypass_ip: attributes.bypassIpUniqueness || false,
            tid: attributes.tid,
          })

Eso es todo. Puedes usar Metricalp completamente activando la solicitud HTTP POST anterior. Explicaremos los detalles y trucos independientemente de la plataforma. También prepararemos ejemplos específicos de la plataforma y finalmente lanzaremos SDKs específicos de la plataforma para todas las plataformas. Pero hasta entonces, estamos escribiendo esta documentación para permitirte usar Metricalp en tu aplicación móvil desde ahora. Además, puedes ser más flexible con este enfoque puro de solicitud HTTP POST sin un SDK. Bien, empecemos con los detalles.

Piensa que tendrás que activar una solicitud HTTP POST una y otra vez en tu aplicación. Esta solicitud tendrá algunas propiedades predeterminadas como tu ID de rastreador (tid). También definirás algunas propiedades en cada llamada. ¿Qué harías? En programación, para proteger el principio DRY (No te repitas), crearás una función, una clase o un módulo para manejar esta solicitud HTTP POST. Aquí haremos esto. Crearemos una clase singleton. Mantendrá las propiedades predeterminadas y tendrá un método para activar la solicitud HTTP POST. Colocaré la clase singleton de la biblioteca React Native aquí y la explicaré a través de ella. Puedes seguir el mismo enfoque en Java, Kotlin (Android), Objective-C, Swift (iOS) o con cualquier plataforma.

tsx
export interface ConfigurationAttributes {
  tid: string;
  platform: string;
  uuid: string;
  os?: string;
  app?: string;
  language?: string;
  endpoint?: string;
  bypassIpUniqueness?: boolean;
}
export class Metricalp {
  private static instance: Metricalp;
  private static API_ENDPOINT = 'https://event.metricalp.com';
  private attributes: ConfigurationAttributes | undefined = undefined;
  private screenDurationStartPoint = Date.now();
  private currentScreen = '';

  private constructor() {}

  public static getOrBuildInstance(): Metricalp {
    if (!Metricalp.instance) {
      Metricalp.instance = new Metricalp();
    }

    return Metricalp.instance;
  }

  public static init(
    attributes: ConfigurationAttributes,
    initialScreen?: string,
    eventAttributes: Record<string, any> = {}
  ) {
    const instance = Metricalp.getOrBuildInstance();
    instance.setAttributes(attributes);
    if (!initialScreen) {
      return Promise.resolve(true);
    }

    return Metricalp.screenViewEvent(initialScreen, eventAttributes);
  }

  public static getInstance() {
    if (!Metricalp.instance) {
      throw new Error(
        'Metricalp not initialized, please call Metricalp.init() first.'
      );
    }
    return Metricalp.instance;
  }

  public setAttributes(attributes: ConfigurationAttributes) {
    this.attributes = attributes;
  }

  public getAttributes() {
    return this.attributes;
  }

  public getCurrentScreen() {
    return this.currentScreen;
  }

  public setCurrentScreen(screen: string) {
    this.currentScreen = screen;
  }

  public setScreenDurationStartPointToNow() {
    this.screenDurationStartPoint = Date.now();
  }

  public static resetAttributes(attributes: ConfigurationAttributes) {
    const instance = Metricalp.getInstance();
    instance.setAttributes(attributes);
  }

  public static updateAttributes(attributes: ConfigurationAttributes) {
    const instance = Metricalp.getInstance();
    const currentAttributes = instance.getAttributes();
    instance.setAttributes({ ...currentAttributes, ...attributes });
  }

  public static getAllAttributes() {
    const instance = Metricalp.getInstance();
    return instance.getAttributes();
  }

  public static sendEvent(
    type: string,
    eventAttributes: Record<string, any>,
    overrideConfigurationAttributes: Partial<ConfigurationAttributes> = {}
  ) {
    const instance = Metricalp.getInstance();
    const attributes = {
      ...instance.getAttributes(),
      ...overrideConfigurationAttributes,
    };

    if (!attributes.tid) {
      throw new Error('Metricalp Error: tid not set in Metricalp attributes.');
    }

    if (!attributes.platform) {
      throw new Error(
        'Metricalp Error: platform not set in Metricalp attributes.'
      );
    }

    if (!attributes.uuid) {
      throw new Error('Metricalp Error: uuid not set in Metricalp attributes.');
    }

    return fetch(attributes.endpoint || Metricalp.API_ENDPOINT, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        ...eventAttributes,
        type,
        path: eventAttributes.path || '(not-set)',
        metr_os_detail: attributes.os || '(not-set)',
        metr_app_detail: attributes.app || '(not-set)',
        metr_user_language: attributes.language || 'unknown-unknown',
        metr_bypass_ip: attributes.bypassIpUniqueness ?? true,
        metr_collected_via: attributes.platform,
        metr_unique_identifier: attributes.uuid,
        tid: attributes.tid,
      }),
    }).then((response) => {
      if (!response.ok) {
        return false;
      }
      return true;
    });
  }

  public static screenViewEvent(
    path: string,
    eventAttributes: Record<string, any> = {},
    overrideConfigurationAttributes: Partial<ConfigurationAttributes> = {}
  ) {
    const instance = Metricalp.getInstance();
    const prevScreen = instance.getCurrentScreen();
    let screenLeaveProps = {};
    if (prevScreen) {
      screenLeaveProps = {
        leave_from_path: prevScreen,
        leave_from_duration: Date.now() - instance.screenDurationStartPoint,
      };
    }
    instance.setCurrentScreen(path);
    instance.setScreenDurationStartPointToNow();
    return Metricalp.sendEvent(
      'screen_view',
      { path, ...screenLeaveProps, ...eventAttributes },
      overrideConfigurationAttributes
    );
  }

  public static appLeaveEvent(
    eventAttributes: Record<string, any> = {},
    overrideConfigurationAttributes: Partial<ConfigurationAttributes> = {}
  ) {
    const instance = Metricalp.getInstance();
    const prevPath = instance.getCurrentScreen();
    // You can not trigger leave event without a screen view event before it
    if (!prevPath) {
      return Promise.resolve(false);
    }
    const screenDuration = Date.now() - instance.screenDurationStartPoint;
    instance.setScreenDurationStartPointToNow();
    instance.setCurrentScreen('');
    return Metricalp.sendEvent(
      'screen_leave',
      {
        path: prevPath,
        screen_duration: screenDuration,
        ...eventAttributes,
      },
      overrideConfigurationAttributes
    );
  }

  // @deprecated No more manual session exit event
  public static sessionExitEvent(
    path: string,
    eventAttributes: Record<string, any> = {},
    overrideConfigurationAttributes: Partial<ConfigurationAttributes> = {}
  ) {
    return Metricalp.sendEvent(
      'session_exit',
      { path, ...eventAttributes },
      overrideConfigurationAttributes
    );
  }

  public static customEvent(
    type: string,
    eventAttributes: Record<string, any> = {},
    overrideConfigurationAttributes: Partial<ConfigurationAttributes> = {}
  ) {
    return Metricalp.sendEvent(
      type,
      eventAttributes,
      overrideConfigurationAttributes
    );
  }
}
 

Eso es todo. La biblioteca de Metricalp para React Native es un solo archivo con unas pocas líneas. Quería decir que puedes crear la tuya propia en la plataforma, no es algo enorme. No olvides que, al final, es solo una solicitud HTTP POST.

Primero, definimos nuestra clase como singleton. Porque definiremos las propiedades predeterminadas en la inicialización y no queremos que se sobrescriban. Estos son más conceptos de programación, no directamente sobre Metricalp, pero es bueno mencionarlos aquí 😎.

Tenemos algunas propiedades estáticas, como la instancia (debido a la naturaleza del singleton), API_ENDPOINT y atributos. API_ENDPOINT es el punto final de eventos de Metricalp. https://event.metricalp.com es siempre el valor predeterminado. Sin embargo, permitiremos al usuario sobrescribirlo en nuestros métodos si es necesario (uso de proxy de Metricalp para pasar bloqueadores de anuncios, etc.).

attributes es un objeto (mapa) para mantener las propiedades predeterminadas. Por ejemplo, ID del rastreador (tid), información del sistema operativo actual, versión y nombre de la aplicación, etc. Enviaremos estos datos con cada evento. Así que, los definiremos una vez, los mantendremos en los atributos y los usaremos en cada evento para proteger el principio DRY. Pero algunos atributos necesitan ser definidos en cada solicitud (como la ruta/pantalla actual). Los proporcionaremos en cada solicitud. Veamos todos los atributos posibles y sus propósitos para una solicitud:

type (required)

Debes proporcionar el tipo de evento para cada evento. Dado que Metricalp es una herramienta de análisis basada en eventos, es necesario y debes proporcionar el tipo para cada solicitud. Por ejemplo, puedes proporcionarlo como screen_view o any_custom_event_name, etc.

path

Puedes proporcionar la pantalla o ruta actual al activar un evento. Es opcional, pero se sugiere para obtener mejores datos en el panel de control. Por ejemplo HomePage o SettingsPage, etc.

metr_collected_via (required)

Necesitas proporcionar la plataforma actual. Los valores posibles son ios, android, web o api. Todos deben estar en minúsculas. En el futuro se admitirán más plataformas. Esto puede definirse una vez en la inicialización y mantenerse en los atributos. Web significa recopilación a través del navegador (requiere la cadena del agente de usuario en los encabezados para la extracción de información) y api significa eventos producidos por el servidor/backend.

metr_os_detail

Puedes proporcionar el sistema operativo y la versión actual del usuario. Puedes proporcionarlo como OSName OSVersion, por ejemplo, iOS 14.5 o Android 11. Es opcional, pero ciertamente recomendable. Esto puede definirse una vez en la inicialización y mantenerse en los atributos.

metr_app_detail

Debes proporcionar el nombre y la versión de tu aplicación. Es importante proporcionar la versión para rastrearla en el panel de control y obtener información detallada. Puedes proporcionarlo como AppName@Version, por ejemplo, MyExampleApp@1.0.0. Es opcional, pero ciertamente recomendable. Esto puede definirse una vez en la inicialización y mantenerse en los atributos.

metr_user_language

Debes proporcionar el idioma actual de tu aplicación. Puedes proporcionarlo como Language (long name)-Country(ISO Code), por ejemplo, English-US o Spanish-ES o Turkish-TR, etc. Si no estás seguro del país, puedes proporcionar desconocido. Por ejemplo, English-unknown. Este prop puede definirse una vez en la inicialización y mantenerse en los atributos.

metr_unique_identifier

Necesitamos explicar este prop metr_unique_identifier. Normalmente, en el seguimiento web, Metricalp no usa cookies como hemos mencionado en muchos lugares. Identificamos a los usuarios con sus direcciones IP en hashes unidireccionales. La fórmula es algo así: hash(user_ip + user_agent + salt). Aquí, ip + user_agent es casi único para cada usuario. Pero en las aplicaciones móviles, las cadenas del agente de usuario son inconsistentes y poco fiables. Por lo tanto, necesitamos un identificador único para cada usuario. Esto lo dejamos a ti. Puedes usar cualquier identificador único para tu aplicación. Por ejemplo, si es una aplicación de autorización y solo estás rastreando después de que los usuarios hayan iniciado sesión, puedes proporcionar identificadores de usuario. O puedes usar identificadores únicos reales relacionados con el dispositivo (Android e iOS tienen algunos métodos nativos para obtenerlos). O puedes generar un UUID aleatorio cuando el usuario abre la aplicación por primera vez, almacenarlo en el almacenamiento y luego usarlo como metr_unique_identifier. Ahora, el algoritmo de hashing será como hash(user_ip + metr_unique_identifier + salt). En este enfoque, el metr_unique_identifier no cambiará a menos que el usuario elimine y vuelva a instalar la aplicación. Pero eso es bastante justo. Si eso no es suficiente para ti, puedes proporcionar tu propio identificador único, como mencionamos anteriormente. ID de usuario o identificador del dispositivo o cualquier otra combinación.

metr_bypass_ip

Este es un prop opcional. Si ves el ejemplo de hash final anterior con metr_unique_identifier: hash(user_ip + metr_unique_identifier + salt), aún tenemos la IP en la función de hash. Por lo tanto, cuando el usuario, por ejemplo, cambia de Wi-Fi a una red móvil, la IP cambiará. Mientras que metr_unique_identifier sigue siendo el mismo, debido al cambio de IP, se contará como otro recuento único para ese día. Pero puedes omitir esta unicidad de IP con este prop. Si lo configuras en true, no usaremos la IP en la función de hash: hash(metr_unique_identifier + salt). Lo configuramos en true por defecto a menos que el desarrollador lo configure en falsy.

tid (required)

Debes proporcionar tu TID (también conocida como ID de seguimiento). Puedes obtenerla en el panel de control de Metricalp. Es obligatorio. Si no la proporcionas, recibirás un error. Puedes encontrar tu TID en la página Embed & Share Tracker.

[any custom props]

Puedes proporcionar cualquier prop personalizada (custom_prop1, custom_prop2...) con cada evento. Si has definido alias, puedes usarlos como clave, por ejemplo, user_id, theme, etc. Puedes consultar Custom Event & Props para obtener información detallada sobre eventos y props personalizados.

Métodos de la Clase

getOrBuildInstance()

Este es un método estático para obtener la instancia actual de Metricalp. Si no hay ninguna instancia, creará una nueva y la devolverá. Esto es parte de la naturaleza del singleton.

init(attributes, initialScreen)

Metricalp.init es un método estático que debes llamar una vez en tu aplicación. Debe estar en el nivel superior de tu aplicación. Aquí es donde establecerás los atributos iniciales. Toma el camino (pantalla) como segundo argumento para establecer en el primer evento scren_view automáticamente desencadenado justo después de la inicialización. Si omites este argumento de camino, no ocurrirá este desencadenamiento automático. Por lo tanto, le damos al usuario la oportunidad de omitir este primer evento automático de screen_view.

getInstance()

Metricalp.getInstance es un método estático que puedes llamar para obtener la instancia actual de Metricalp. Es útil para obtener nuestro objeto singleton. Si no se ha creado una instancia, este método lanzará un error.

setAttributes(attributes)

setAttributes es un método para establecer atributos. Utilizamos este método de instancia dentro de otros métodos estáticos después de obtener nuestra instancia.

getAttributes()

getAttributes es un método para obtener atributos. Utilizamos este método de instancia dentro de otros métodos estáticos después de obtener nuestra instancia.

resetAttributes(attributes)

resetAttributes es un método estático para restablecer atributos. Es útil para restablecer los atributos a un estado inicial proporcionado. Toma nuevos atributos como argumento.

updateAttributes(attributes)

updateAttributes es un método estático para actualizar atributos. Es útil para actualizar parcialmente los atributos con nuevos. Toma nuevos atributos parciales como argumento.

getAllAttributes()

getAllAttributes es un método estático para obtener todos los atributos. Es útil para obtener todos los atributos de una vez.

sendEvent(type, eventAttributes, overrideAttributes)

sendEvent es un método estático para enviar un evento. Toma el tipo de evento, atributos del evento y atributos de anulación (para anular los atributos predeterminados iniciales) como argumentos. Combinará los atributos y enviará el evento con ellos. Devolverá una promesa que se resolverá con true si el evento se envía correctamente, de lo contrario, se resolverá con false. No utilizaremos directamente este método en nuestra aplicación, utilizaremos los métodos screenViewEvent y customEvent, que son envoltorios de este método.

screenViewEvent(path, eventAttributes, overrideAttributes)

screenViewEvent es un método estático para enviar un evento screen_view. Toma el camino de la pantalla, atributos del evento y atributos de anulación (para anular los atributos predeterminados iniciales) como argumentos. Combinará los atributos y enviará el evento con ellos. Devolverá una promesa que se resolverá con true si el evento se envía correctamente, de lo contrario, se resolverá con false.

appLeaveEvent(eventAttributes, overrideAttributes)

appLeaveEvent es un método estático para enviar eventos screen_leave. Normalmente, cuando el usuario navega de una pantalla a otra, la biblioteca crea automáticamente eventos screen_leave entre dos eventos screen_view. Pero en el caso de que la aplicación se cierre (el usuario cierra la aplicación o la aplicación se va al segundo plano), debes activarlo. Por lo tanto, hemos proporcionado un método para activar el cierre de la aplicación, que se llama appLeaveEvent. Toma atributos del evento y atributos de anulación (para anular los atributos predeterminados iniciales) como argumentos. Combinará los atributos y enviará el evento con ellos. Devolverá una promesa que se resolverá con true si el evento se envía correctamente, de lo contrario, se resolverá con false.

customEvent(type, eventAttributes, overrideAttributes)

customEvent es un método estático para enviar un evento personalizado. Toma el tipo de evento, atributos del evento y atributos de anulación (para anular los atributos predeterminados iniciales) como argumentos. Combinará los atributos y enviará el evento con ellos. Devolverá una promesa que se resolverá con true si el evento se envía correctamente, de lo contrario, se resolverá con false.

Eso es todo. Puedes seguir este enfoque y usar Metricalp en cualquier plataforma. Permítenos explicar los detalles y trucos independientemente de la plataforma. Si eres un desarrollador de React Native, puedes usar la biblioteca oficial sin ningún esfuerzo. Para otras plataformas, debes seguir este enfoque hasta que publiquemos SDKs oficiales. Además, estamos abiertos a contribuciones para SDKs con el enfoque mencionado anteriormente. Nos enorgullece ser centrados en la API y no ser solo una herramienta web. Nos preocupamos por todos los clientes y seguimos haciéndolo de la manera más asequible.