2023-05-18 16:32:50 +03:00
|
|
|
// Wrapper function for Plausible event
|
|
|
|
|
2024-02-21 01:08:35 +03:00
|
|
|
function isPosthogLoaded() {
|
|
|
|
return window.posthog?.__loaded;
|
|
|
|
}
|
|
|
|
|
2024-02-14 00:23:03 +03:00
|
|
|
/**
|
|
|
|
* Hashes a user's email address so we can use it as a distinct_id in PostHog without storing the email address itself
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param {string} email an email address
|
|
|
|
* @returns {(string|null)} a sha256 hash of the email address to use as distinct_id in PostHog — null if hashing fails
|
|
|
|
*/
|
|
|
|
async function hashEmail(email) {
|
|
|
|
try {
|
|
|
|
const digest = await window.crypto.subtle.digest('SHA-256', new TextEncoder().encode(email.trim().toLowerCase()));
|
|
|
|
const hashArray = Array.from(new Uint8Array(digest));
|
|
|
|
const hash = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
|
|
|
|
// Double-check that the hash is a valid sha256 hex string before returning it, else return null
|
|
|
|
return hash.length === 64 ? hash : null;
|
|
|
|
} catch (e) {
|
|
|
|
// Modern browsers all support window.crypto, but we need to check for it to avoid errors on really old browsers
|
|
|
|
// If any errors occur when hashing email, return null
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2024-02-21 01:32:56 +03:00
|
|
|
* Sends a tracking event to Plausible and Posthog, if installed.
|
2024-02-14 00:23:03 +03:00
|
|
|
*
|
2024-02-21 01:32:56 +03:00
|
|
|
* By default, Plausible and Posthog are not installed, in which case this function no-ops.
|
2024-02-14 00:23:03 +03:00
|
|
|
*
|
|
|
|
* @param {string} eventName A string name for the event being tracked
|
|
|
|
* @param {Object} [props={}] An optional object of properties to include with the event
|
|
|
|
*/
|
|
|
|
export function trackEvent(eventName, props = {}) {
|
2023-05-18 16:32:50 +03:00
|
|
|
window.plausible = window.plausible || function () {
|
|
|
|
(window.plausible.q = window.plausible.q || []).push(arguments);
|
|
|
|
};
|
|
|
|
window.plausible(eventName, {props: props});
|
2024-02-21 01:32:56 +03:00
|
|
|
|
|
|
|
if (isPosthogLoaded()) {
|
|
|
|
window.posthog.capture(eventName, props);
|
|
|
|
}
|
2023-05-18 16:32:50 +03:00
|
|
|
}
|
2024-02-14 00:23:03 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Calls posthog.identify() with a hashed email address as the distinct_id
|
|
|
|
*
|
|
|
|
* @param {Object} user A user to identify in PostHog
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
export async function identifyUser(user) {
|
|
|
|
// Return early if window.posthog doesn't exist
|
2024-02-21 01:08:35 +03:00
|
|
|
if (!isPosthogLoaded()) {
|
2024-02-14 00:23:03 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
// User the user exists and has an email address, identify them in PostHog
|
|
|
|
if (user && user.get('email')) {
|
|
|
|
const email = user.get('email');
|
|
|
|
const hashedEmail = await hashEmail(email);
|
|
|
|
const distinctId = window.posthog.get_distinct_id();
|
|
|
|
// Only continue if hashing was successful, and the user hasn't already been identified
|
|
|
|
if (hashedEmail && hashedEmail !== distinctId) {
|
|
|
|
const props = {};
|
|
|
|
// Add the user's id
|
|
|
|
if (user.get('id')) {
|
|
|
|
props.id = user.get('id');
|
|
|
|
}
|
|
|
|
// Add the user's role
|
|
|
|
if (user.get('role').name) {
|
|
|
|
props.role = user.get('role').name.toLowerCase();
|
|
|
|
}
|
|
|
|
// Add the user's created_at date
|
|
|
|
if (user.get('createdAtUTC')) {
|
|
|
|
props.created_at = user.get('createdAtUTC').toISOString();
|
|
|
|
}
|
|
|
|
window.posthog.identify(hashedEmail, props);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calls posthog.reset() to clear the current user's distinct_id and all associated properties
|
|
|
|
* To be called when a user logs out
|
|
|
|
*
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
export function resetUser() {
|
2024-02-21 01:08:35 +03:00
|
|
|
if (isPosthogLoaded()) {
|
2024-02-14 00:23:03 +03:00
|
|
|
window.posthog.reset();
|
|
|
|
}
|
|
|
|
}
|