Comment intégrer Metricalp avec des applications mobiles
Depuis le lancement de Metricalp, tout le monde a toujours demandé un support pour les plateformes mobiles. Ils avaient raison, les navigateurs mobiles et les applications mobiles surpassent la plateforme web. Nous sommes donc heureux d'annoncer que nous sommes sur la feuille de route pour le support des plateformes mobiles. Actuellement, nous avons des SDK officiels pour React Native, Android et iOS .
Vous vous demandez peut-être comment il est possible d'utiliser Metricalp avec une application mobile sans bibliothèque officielle. La réponse est simple, car Metricalp a été conçu de manière entièrement centrée sur l'API. Ainsi, en réalité, créer un événement Metricalp n'est qu'une requête HTTP POST. C'est le cas sur le web, mobile ou toute autre plateforme. En arrière-plan, toutes les bibliothèques d'intégration utilisent cette méthode, en envoyant simplement une requête HTTP POST. Vous pouvez donc utiliser Metricalp même avec votre machine à laver intelligente si vous le souhaitez dès le premier jour. Voici la requête HTTP POST de l'événement qui est utilisée dans la bibliothèque React Native comme exemple, puis nous décrirons chaque détail ci-dessous :
fetch(attributes.endpoint || Metricalp.API_ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
type,
path: attributes.path || '(non défini)',
metr_collected_via: attributes.platform,
metr_os_detail: attributes.os || '(non défini)',
metr_app_detail: attributes.app || '(non défini)',
metr_user_language: attributes.language || '(non défini)',
metr_unique_identifier: attributes.uuid || '',
metr_bypass_ip: attributes.bypassIpUniqueness || false,
tid: attributes.tid,
})
C'est tout. Vous pouvez utiliser pleinement Metricalp en déclenchant la requête HTTP POST ci-dessus. Expliquons les détails et les astuces indépendamment de la plateforme. Nous préparerons également des exemples spécifiques à la plateforme et finalement, nous publierons des SDK spécifiques à la plateforme pour toutes les plateformes. Mais d'ici là, nous rédigeons cette documentation pour vous permettre d'utiliser Metricalp dans votre application mobile dès maintenant. De plus, vous pouvez être plus flexible avec cette approche purement HTTP POST sans SDK. D'accord, commençons par les détails.
Imaginez que vous devez déclencher une requête HTTP POST encore et encore dans votre application. Cette requête aura certaines propriétés par défaut comme votre identifiant de suivi (tid). Vous définirez également certaines propriétés à chaque appel. Que feriez-vous ? En programmation, pour protéger le principe DRY (Don't Repeat Yourself), vous créerez une fonction, une classe ou un module pour gérer cette requête HTTP POST. Ici, nous ferons cela. Nous créerons une classe singleton. Elle conservera les propriétés par défaut et aura une méthode pour déclencher la requête HTTP POST. Je placerai ici la classe singleton de la bibliothèque React Native et je l'expliquerai à travers elle. Vous pouvez suivre la même approche en Java, Kotlin (Android), Objective-C, Swift (iOS) ou avec n'importe quelle autre plateforme.
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
);
}
}
C'est tout. La bibliothèque React Native de Metricalp est un fichier unique avec quelques lignes. Je voulais dire que tu peux créer la tienne sur la plateforme, ce n'est pas grand-chose. N'oublie pas qu'en fin de compte, c'est juste une requête HTTP POST.
Tout d'abord, nous avons défini notre classe comme un singleton. Parce que nous définirons les propriétés par défaut lors de l'initialisation et nous ne voulons pas qu'elles soient écrasées. Ce sont plus des concepts de programmation, pas directement liés à Metricalp, mais c'est bien de les mentionner ici 😎.
Nous avons certaines propriétés statiques, comme l'instance (à cause de la nature du singleton), API_ENDPOINT et attributs. API_ENDPOINT est le point de terminaison des événements Metricalp. https://event.metricalp.com est toujours la valeur par défaut. Cependant, nous permettrons à l'utilisateur de le remplacer dans nos méthodes si nécessaire (utilisation de proxy de Metricalp pour contourner les bloqueurs de publicité, etc.).
attributes est un objet (map) pour conserver les propriétés par défaut. Par exemple, l'ID du traceur (tid), les informations sur le système d'exploitation actuel, la version et le nom de l'application, etc. Nous enverrons ces données avec chaque événement. Donc, nous les définirons une fois, les garderons dans les attributs et les utiliserons pour chaque événement afin de protéger le principe DRY. Mais certains attributs doivent être définis pour chaque demande (comme le chemin/écran actuel). Nous les fournirons pour chaque demande. Voyons tous les attributs possibles et leurs objectifs pour une demande :
type (required)
Tu dois fournir le type d'événement pour chaque événement. Étant donné que Metricalp est un outil d'analyse basé sur les événements, il est nécessaire de fournir le type pour chaque demande. Par exemple, tu peux le fournir comme screen_view ou any_custom_event_name, etc.
path
Tu peux fournir l'écran ou le chemin actuel lors du déclenchement d'un événement. C'est optionnel, mais recommandé pour obtenir de meilleures données sur le tableau de bord. Par exemple HomePage ou SettingsPage, etc.
metr_collected_via (required)
Tu dois fournir la plateforme actuelle. Les valeurs possibles sont ios, android, web ou api. Tous doivent être en minuscules. À l'avenir, d'autres plateformes seront prises en charge. Cela peut être défini une fois lors de l'initialisation et conservé dans les attributs. Web signifie collecte via le navigateur (nécessite la chaîne de l'agent utilisateur dans les en-têtes pour l'extraction d'informations) et API signifie événements générés par le serveur/backend.
metr_os_detail
Tu peux fournir le système d'exploitation actuel et la version de l'utilisateur. Tu peux le fournir sous le format OSName OSVersion, par exemple, iOS 14.5 ou Android 11. C'est optionnel, mais certainement recommandé. Cela peut être défini une fois lors de l'initialisation et conservé dans les attributs.
metr_app_detail
Tu dois fournir le nom et la version de ton application. Il est important de fournir la version pour suivre cela sur le tableau de bord et obtenir des informations détaillées. Tu peux le fournir sous le format AppName@Version, par exemple, [email protected]. C'est optionnel, mais certainement recommandé. Cela peut être défini une fois lors de l'initialisation et conservé dans les attributs.
metr_user_language
Tu dois fournir la langue actuelle de ton application. Tu peux le fournir sous le format Language (long name)-Country(ISO Code), par exemple, English-US ou Spanish-ES ou Turkish-TR, etc. Si tu n'es pas sûr du pays, tu peux fournir inconnu. Par exemple, English-unknown. Ce prop peut être défini une fois lors de l'initialisation et conservé dans les attributs.
metr_unique_identifier
Nous devons expliquer ce prop metr_unique_identifier. Normalement, dans le suivi web, Metricalp n'utilise pas de cookies comme nous l'avons mentionné à de nombreux endroits. Nous identifions les utilisateurs avec leurs adresses IP dans des hachages unidirectionnels. La formule est quelque chose comme hash(user_ip + user_agent + salt). Ici, ip + user_agent est presque unique pour chaque utilisateur. Mais dans les applications mobiles, les chaînes d'agents utilisateur sont incohérentes et peu fiables. Donc, nous avons besoin d'un identifiant unique pour chaque utilisateur. Nous te laissons cette responsabilité. Tu peux utiliser n'importe quel identifiant unique pour ton application. Par exemple, si c'est une application d'autorisation et que tu suis seulement après que les utilisateurs se sont connectés, tu peux fournir des identifiants utilisateur. Ou tu peux utiliser des identifiants uniques réels liés au dispositif (Android et iOS ont des méthodes natives pour les obtenir). Ou tu peux générer un UUID aléatoire lorsque l'utilisateur ouvre l'application pour la première fois, le stocker dans le stockage et l'utiliser ensuite comme metr_unique_identifier. Maintenant, l'algorithme de hachage sera comme hash(user_ip + metr_unique_identifier + salt). Dans cette approche, le metr_unique_identifier ne changera pas à moins que l'utilisateur supprime et réinstalle l'application. Mais c'est assez équitable. Si cela ne te suffit pas, tu peux fournir ton propre identifiant unique, comme mentionné ci-dessus. ID utilisateur ou identifiant de dispositif ou toute autre combinaison.
metr_bypass_ip
C'est un prop optionnel. Si tu vois l'exemple de hachage final avec metr_unique_identifier : hash(user_ip + metr_unique_identifier + salt), nous avons toujours l'IP dans la fonction de hachage. Donc, si un utilisateur, par exemple, passe de Wi-Fi à un réseau mobile, l'IP changera. Alors que metr_unique_identifier reste le même, en raison du changement d'IP, cela sera compté comme un autre compte unique pour ce jour-là. Mais tu peux contourner cette unicité IP avec ce prop. Si tu le définis sur true, nous n'utiliserons pas l'IP dans la fonction de hachage : hash(metr_unique_identifier + salt). Nous le définissons sur true par défaut, à moins que le développeur le définisse sur falsy.
tid (required)
Tu dois fournir ton TID (également appelé ID de suivi). Tu peux l'obtenir sur le tableau de bord Metricalp. C'est obligatoire. Si tu ne le fournis pas, tu recevras une erreur. Tu peux trouver ton TID sur la page Embed & Share Tracker.
[any custom props]
Tu peux fournir n'importe quel prop personnalisé (custom_prop1, custom_prop2...) avec chaque événement. Si tu as défini des alias, tu peux les utiliser comme clés, par exemple, user_id, theme, etc. Tu peux consulter Custom Event & Props pour plus d'informations sur les événements et props personnalisés.
Méthodes de la classe
getOrBuildInstance()
C'est une méthode statique pour obtenir l'instance actuelle de Metricalp. Si aucune instance n'existe, une nouvelle instance est créée et renvoyée. Cela découle de la nature du singleton.
init(attributes, initialScreen)
Metricalp.init est une méthode statique que vous devez appeler une fois dans votre application. Elle doit être au niveau supérieur de votre application. Vous définirez les attributs initiaux ici. Elle prend le chemin (écran) comme deuxième argument pour le définir dans l'événement screen_view automatiquement déclenché juste après l'initialisation. Si vous omettez cet argument de chemin, ce déclenchement automatique ne se produira pas. Nous donnons donc à l'utilisateur la possibilité de passer cet événement screen_view automatique initial.
getInstance()
Metricalp.getInstance est une méthode statique que vous pouvez appeler pour obtenir l'instance actuelle de Metricalp. Elle est utile pour obtenir notre objet singleton. S'il n'y a pas d'instance construite, cette méthode générera une erreur.
setAttributes(attributes)
setAttributes est une méthode pour définir les attributs. Nous utilisons cette méthode d'instance à l'intérieur d'autres méthodes statiques après avoir obtenu notre instance.
getAttributes()
getAttributes est une méthode pour obtenir les attributs. Nous utilisons cette méthode d'instance à l'intérieur d'autres méthodes statiques après avoir obtenu notre instance.
resetAttributes(attributes)
resetAttributes est une méthode statique pour réinitialiser les attributs. Elle est utile pour réinitialiser les attributs à un état initial fourni. Elle prend de nouveaux attributs comme argument.
updateAttributes(attributes)
updateAttributes est une méthode statique pour mettre à jour les attributs. Elle est utile pour mettre à jour partiellement les attributs avec de nouveaux. Elle prend de nouveaux attributs partiels comme argument.
getAllAttributes()
getAllAttributes est une méthode statique pour obtenir tous les attributs. Elle est utile pour obtenir tous les attributs en une seule fois.
sendEvent(type, eventAttributes, overrideAttributes)
sendEvent est une méthode statique pour envoyer un événement. Elle prend le type d'événement, les attributs de l'événement et les attributs de remplacement (pour remplacer les attributs par défaut initiaux) comme arguments. Elle combinera les attributs et enverra l'événement avec eux. Elle retournera une promesse qui se résoudra avec true si l'événement est envoyé avec succès, sinon elle se résoudra avec false. Nous n'utiliserons pas directement cette méthode dans notre application, nous utiliserons les méthodes screenViewEvent et customEvent, qui sont des wrappers de cette méthode.
screenViewEvent(path, eventAttributes, overrideAttributes)
screenViewEvent est une méthode statique pour envoyer un événement screen_view. Elle prend le chemin de l'écran, les attributs de l'événement et les attributs de remplacement (pour remplacer les attributs par défaut initiaux) comme arguments. Elle combinera les attributs et enverra l'événement avec eux. Elle retournera une promesse qui se résoudra avec true si l'événement est envoyé avec succès, sinon elle se résoudra avec false.
appLeaveEvent(eventAttributes, overrideAttributes)
appLeaveEvent est une méthode statique pour envoyer des événements screen_leave. Normalement, lorsque l'utilisateur passe d'un écran à un autre, la bibliothèque crée automatiquement des événements screen_leave entre deux événements screen_view. Mais lors de la fermeture de l'application (l'utilisateur ferme l'application ou l'application passe en arrière-plan), vous devez déclencher cet événement. Nous avons donc fourni une méthode pour déclencher lors de la fermeture de l'application, appelée appLeaveEvent. Elle prend les attributs de l'événement et les attributs de remplacement (pour remplacer les attributs par défaut initiaux) comme arguments. Elle combinera les attributs et enverra l'événement avec eux. Elle retournera une promesse qui se résoudra avec true si l'événement est envoyé avec succès, sinon elle se résoudra avec false.
customEvent(type, eventAttributes, overrideAttributes)
customEvent est une méthode statique pour envoyer un événement personnalisé. Elle prend le type d'événement, les attributs de l'événement et les attributs de remplacement (pour remplacer les attributs par défaut initiaux) comme arguments. Elle combinera les attributs et enverra l'événement avec eux. Elle retournera une promesse qui se résoudra avec true si l'événement est envoyé avec succès, sinon elle se résoudra avec false.
C'est tout. Vous pouvez suivre cette approche et utiliser Metricalp sur n'importe quelle plateforme. Laissez-nous vous expliquer les détails et les astuces indépendamment de la plateforme. Si vous êtes un développeur React Native, vous pouvez utiliser la bibliothèque officielle sans effort. Pour d'autres plateformes, vous devez suivre cette approche jusqu'à ce que nous publions des SDKs officiels. De plus, nous sommes ouverts aux contributions pour les SDKs avec l'approche ci-dessus. Nous sommes fiers d'être centrés sur l'API et non seulement un outil web. Nous nous soucions de tous les clients et nous le faisons encore de la manière la plus abordable.