Come integrare Metricalp con applicazioni mobili

Da quando abbiamo rilasciato Metricalp, tutti hanno sempre chiesto il supporto per le piattaforme mobili. Avevano ragione, i browser mobile e le app mobili stanno superando le piattaforme web. Quindi, siamo felici di annunciare che siamo sulla strada per il supporto delle piattaforme mobili. Al momento, abbiamo SDK ufficiali per React Native, Android e iOS .

Potresti chiedere, come è possibile usare Metricalp con un'app mobile senza una libreria ufficiale? La risposta è semplice, perché Metricalp è stato progettato in modo completamente API-centrico. Quindi, creare un evento Metricalp è solo una richiesta HTTP POST. Questo è il modo di farlo su web, mobile o qualsiasi altra piattaforma. Dietro le quinte, tutte le librerie di integrazione utilizzano questo metodo, semplicemente inviando una richiesta HTTP POST. Quindi, puoi usare Metricalp anche con la tua lavatrice intelligente se vuoi, sin dal primo giorno. Ecco la richiesta HTTP POST dell'evento utilizzata nella libreria React Native come esempio, e poi descriveremo ogni dettaglio di essa qui sotto:

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

Questo è tutto. Puoi usare completamente Metricalp attivando la richiesta HTTP POST sopra descritta. Spieghiamo i dettagli e i trucchi indipendentemente dalla piattaforma. Prepariamo anche esempi specifici per piattaforma e infine rilasceremo SDK specifici per tutte le piattaforme. Ma fino ad allora, stiamo scrivendo questa documentazione per permetterti di usare Metricalp nella tua app mobile sin da ora. Inoltre, puoi essere più flessibile con questo approccio puro di richiesta HTTP POST senza un SDK. Bene, iniziamo con i dettagli.

Pensa di dover attivare una richiesta HTTP POST più e più volte nella tua applicazione. Questa richiesta avrà alcune proprietà predefinite come il tuo ID tracker (tid). Definirai anche alcune proprietà in ogni chiamata. Cosa faresti? Nella programmazione, per proteggere il principio DRY (Non Ripeterti), creerai una funzione, una classe o un modulo per gestire questa richiesta HTTP POST. Qui faremo proprio questo. Creeremo una classe singleton. Terrà le proprietà predefinite e avrà un metodo per attivare la richiesta HTTP POST. Metterò la classe singleton della libreria React Native qui e la spiegherò attraverso essa. Puoi seguire lo stesso approccio in Java, Kotlin (Android), Objective-C, Swift (iOS) o con qualsiasi piattaforma.

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
    );
  }
}
 

Questo è tutto. La libreria React Native di Metricalp è un file singolo con poche righe. Intendevo dire che puoi crearne una tua sulla piattaforma, non è una cosa enorme. Non dimenticare che alla fine è solo una richiesta HTTP POST.

Prima di tutto, abbiamo definito la nostra classe come singleton. Perché definiremo le proprietà predefinite all'inizio e non vogliamo che vengano sovrascritte. Questi concetti riguardano più la programmazione, non direttamente Metricalp, ma è utile menzionarli qui 😎

Abbiamo alcune proprietà statiche, istanza (a causa della natura del singleton), API_ENDPOINT e attributi. API_ENDPOINT è l'endpoint degli eventi Metricalp. https://event.metricalp.com è sempre il valore predefinito. Tuttavia, permetteremo all'utente di sovrascriverlo nei nostri metodi se necessario (uso proxy di Metricalp per aggirare i blocchi pubblicitari ecc.).

attributi è un oggetto (mappa) per mantenere le proprietà predefinite. Ad esempio, ID tracker (tid), informazioni sul sistema operativo corrente, versione e nome dell'app, ecc. Invieremo questi dati con ogni evento. Quindi, li definiremo una volta, li manterremo negli attributi e li utilizzeremo in ogni evento per proteggere il principio DRY. Ma alcuni attributi devono essere definiti per ogni richiesta (come il percorso corrente/schermata). Li forniremo in ogni richiesta. Diamo un'occhiata a tutti gli attributi possibili e ai loro scopi per una richiesta:

type (required)

Dovresti fornire il tipo di evento per ogni evento. Poiché Metricalp è uno strumento di analisi basato su eventi, è necessario e dovresti fornire il tipo per ogni richiesta. Ad esempio, puoi fornirlo come screen_view o any_custom_event_name, ecc.

path

Puoi fornire la schermata corrente o il percorso mentre attivi un evento. È opzionale ma consigliato per ottenere dati migliori nella dashboard. Ad esempio HomePage o SettingsPage, ecc.

metr_collected_via (required)

Devi fornire la piattaforma corrente. I valori possibili sono ios, android, web o api. Tutti devono essere in minuscolo. In futuro saranno supportate più piattaforme. Questo può essere definito una volta all'inizio e mantenuto negli attributi. Web significa raccolta tramite browser (richiede la stringa user agent negli header per l'estrazione delle informazioni) e api significa eventi prodotti dal server/backend.

metr_os_detail

Puoi fornire il sistema operativo e la versione dell'utente. Puoi fornirlo come sintassi OSName OSVersion, ad esempio iOS 14.5 o Android 11. È opzionale ma sicuramente consigliato. Questo può essere definito una volta all'inizio e mantenuto negli attributi.

metr_app_detail

Dovresti fornire il nome e la versione della tua app. È importante fornire la versione per tracciarla nella dashboard e ottenere approfondimenti dettagliati. Puoi fornirlo come sintassi AppName@Version, ad esempio MyExampleApp@1.0.0. È opzionale ma sicuramente consigliato. Questo può essere definito una volta all'inizio e mantenuto negli attributi.

metr_user_language

Dovresti fornire la lingua corrente della tua app. Puoi fornirlo come sintassi Language (long name)-Country(ISO Code), ad esempio English-US o Spanish-ES o Turkish-TR, ecc. Se non sei sicuro del paese, puoi fornire unknown. Ad esempio English-unknown. Questa prop può essere definita una volta all'inizio e mantenuta negli attributi.

metr_unique_identifier

Dobbiamo spiegare questa prop metr_unique_identifier. Normalmente nel tracciamento Web, Metricalp non utilizza i cookie come abbiamo menzionato in molti luoghi. Identifichiamo gli utenti con i loro indirizzi IP in hash unidirezionali. La formula è qualcosa del tipo: hash(user_ip + user_agent + salt). Qui ip + user_agent è quasi unico per ogni utente. Ma nelle app mobili, le stringhe user agent sono incoerenti e non affidabili. Quindi, abbiamo bisogno di un identificatore unico per ogni utente. Abbiamo lasciato a te questo identificatore unico. Puoi utilizzare qualsiasi identificatore unico per la tua app. Ad esempio, se è un'app di autorizzazione e tracci solo dopo che gli utenti hanno effettuato l'accesso, allora puoi fornire gli ID utente. Oppure puoi usare identificatori unici reali relativi ai dispositivi (Android e iOS hanno alcuni metodi nativi per ottenerli). Oppure, puoi generare un UUID casuale quando l'utente apre l'app per la prima volta e conservarlo nello storage e poi usarlo come metr_unique_identifier. Ora, l'algoritmo di hashing sarà qualcosa del tipo hash(user_ip + metr_unique_identifier + salt). In questo approccio, il metr_unique_identifier rimarrà invariato a meno che l'utente non rimuova e reinstalli l'app. Ma è abbastanza equo. Se non è sufficiente per te, puoi fornire il tuo identificatore unico come abbiamo menzionato sopra. ID utente o identificatore del dispositivo o qualsiasi altra combinazione.

metr_bypass_ip

Questa è una prop opzionale. Se vedi sopra l'esempio finale di hash con metr_unique_identifier: hash(user_ip + metr_unique_identifier + salt), abbiamo comunque l'IP nella funzione di hash. Quindi, quando l'utente, ad esempio, è su Wi-Fi e poi passa a una rete mobile, l'IP cambierà. Anche se metr_unique_identifier è lo stesso, a causa del cambiamento dell'IP, verrà conteggiato come un altro conteggio unico per quel giorno. Ma, puoi aggirare questa unicità dell'IP con questa prop. Se la imposti su true, non utilizzeremo l'IP nella funzione di hash: hash(metr_unique_identifier + salt). La impostiamo su true come predefinito a meno che lo sviluppatore non la imposti su falsy.

tid (required)

Dovresti fornire il tuo TID (anche conosciuto come Tracking ID). Puoi ottenerlo dalla dashboard di Metricalp. È obbligatorio. Se non lo fornisci, riceverai un errore. Puoi trovare il tuo tid nella pagina Embed & Share Tracker.

[any custom props]

Puoi fornire qualsiasi prop personalizzata (custom_prop1, custom_prop2...) con ogni evento. Se hai definito alias, puoi usarli come chiave, ad esempio user_id, theme, ecc. Puoi controllare Custom Event & Props per informazioni dettagliate su eventi e prop personalizzati.

Metodi della Classe

getOrBuildInstance()

Questo è un metodo statico per ottenere l'istanza corrente di Metricalp. Se non c'è alcuna istanza, ne creerà una nuova e la restituirà. Questo è dovuto alla natura del singleton.

init(attributes, initialScreen)

Metricalp.init è un metodo statico che dovresti chiamare una volta nella tua app. Dovrebbe essere al livello superiore della tua app. Qui imposterai gli attributi iniziali. Prende il percorso (schermo) come secondo argomento per impostare il primo evento scren_view automaticamente attivato subito dopo l'inizializzazione. Se ometti questo argomento percorso, questo trigger automatico non avverrà. Pertanto, diamo all'utente la possibilità di saltare questo primo evento automatico di screen_view.

getInstance()

Metricalp.getInstance è un metodo statico che puoi chiamare per ottenere l'istanza corrente di Metricalp. È utile per ottenere il nostro oggetto singleton. Se non è stata creata alcuna istanza, questo metodo genererà un errore.

setAttributes(attributes)

setAttributes è un metodo per impostare gli attributi. Utilizziamo questo metodo di istanza all'interno di altri metodi statici dopo aver ottenuto la nostra istanza.

getAttributes()

getAttributes è un metodo per ottenere gli attributi. Utilizziamo questo metodo di istanza all'interno di altri metodi statici dopo aver ottenuto la nostra istanza.

resetAttributes(attributes)

resetAttributes è un metodo statico per reimpostare gli attributi. È utile per reimpostare gli attributi a uno stato iniziale fornito. Prende nuovi attributi come argomento.

updateAttributes(attributes)

updateAttributes è un metodo statico per aggiornare gli attributi. È utile per aggiornare parzialmente gli attributi con nuovi. Prende nuovi attributi parziali come argomento.

getAllAttributes()

getAllAttributes è un metodo statico per ottenere tutti gli attributi. È utile per ottenere tutti gli attributi in una sola volta.

sendEvent(type, eventAttributes, overrideAttributes)

sendEvent è un metodo statico per inviare un evento. Prende il tipo di evento, attributi dell'evento e attributi di override (per sovrascrivere gli attributi predefiniti iniziali) come argomenti. Combinerà gli attributi e invierà l' evento con essi. Restituirà una promessa che si risolverà con true se l'evento è inviato correttamente, altrimenti si risolverà con false. Non utilizzeremo direttamente questo metodo nella nostra app, utilizzeremo i metodi screenViewEvent e customEvent, che sono wrapper di questo metodo.

screenViewEvent(path, eventAttributes, overrideAttributes)

screenViewEvent è un metodo statico per inviare un evento screen_view. Prende il percorso dello schermo, attributi dell'evento e attributi di override (per sovrascrivere gli attributi predefiniti iniziali) come argomenti. Combinerà gli attributi e invierà l'evento con essi. Restituirà una promessa che si risolverà con true se l'evento è inviato correttamente, altrimenti si risolverà con false.

appLeaveEvent(eventAttributes, overrideAttributes)

appLeaveEvent è un metodo statico per inviare eventi screen_leave. Normalmente, quando l'utente naviga da uno schermo all'altro, la libreria crea automaticamente eventi screen_leave tra due eventi screen_view. Ma quando l'app viene chiusa (l'utente chiude l'app o l'app va in background), dovresti attivarla. Pertanto, abbiamo fornito un metodo per attivare la chiusura dell'app, chiamato appLeaveEvent. Prende attributi dell'evento e attributi di override (per sovrascrivere gli attributi predefiniti iniziali) come argomenti. Combinerà gli attributi e invierà l'evento con essi. Restituirà una promessa che si risolverà con true se l'evento è inviato correttamente, altrimenti si risolverà con false.

customEvent(type, eventAttributes, overrideAttributes)

customEvent è un metodo statico per inviare un evento personalizzato. Prende il tipo di evento, attributi dell'evento e attributi di override (per sovrascrivere gli attributi predefiniti iniziali) come argomenti. Combinerà gli attributi e invierà l'evento con essi. Restituirà una promessa che si risolverà con true se l'evento è inviato correttamente, altrimenti si risolverà con false.

Questo è tutto. Puoi seguire questo approccio e utilizzare Metricalp su qualsiasi piattaforma. Lasciaci spiegare i dettagli e i trucchi indipendentemente dalla piattaforma. Se sei uno sviluppatore di React Native, puoi utilizzare la libreria ufficiale senza alcuno sforzo. Per altre piattaforme, devi seguire questo approccio fino a quando non rilasceremo SDK ufficiali. Inoltre, siamo aperti a contributi per SDK con l'approccio sopra descritto. Siamo orgogliosi di essere centrati sull'API e non solo uno strumento web. Ci preoccupiamo di tutti i clienti e lo facciamo ancora nel modo più conveniente.