Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/hub/analytics-script.ts
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45/*6* CoCalc native analytics7*8* This script saves some information about how, from where and why someone came on a cocalc page.9* It checks for UTM parameters and the referral and landing page.10* On kucalc, static pages are served without going through the hub.11* Therefore we have to do the extraction on static pages,12* which will also work on adjacent pages like the documentation.13* The cookies are only set if they're new.14* e.g. this filters the SSO auth pages, which are uninteresting referrals15*/1617// variable PREFIX, NAME, DOMAIN and ID are injected in the hub's http server18declare var NAME, ID, DOMAIN, PREFIX, window, document;1920// write cookie. it would be cool to set this via the http request itself,21// but for reasons I don't know it doesn't work across subdomains.22const maxage = 7 * 24 * 60 * 60; // 7 days23document.cookie = `${NAME}=${ID}; path=/; domain=${DOMAIN}; max-age=${maxage}`;2425const { href, protocol, host, pathname } = window.location;2627// TODO: use the array defined in packages/util/misc.js28const UTM_KEYS: ReadonlyArray<string> = Object.freeze([29"source",30"medium",31"campaign",32"term",33"content",34]);3536type Response = Partial<{37utm: { [key: string]: string };38referrer: string;39landing: string;40}>;4142const response: Response = {};4344const UTM = {};45const params = href.slice(href.indexOf("?") + 1).split("&");46let have_utm = false;47for (let i = 0; i < params.length; i++) {48const part = params[i];49const k_v = part.split("=");50let k = k_v[0];51const v = k_v[1];52if (k == null || v == null) continue;53if (k.slice(0, 4) !== "utm_") continue;54k = k.slice(4);55if (!UTM_KEYS.includes(k)) continue;56UTM[k] = window.decodeURIComponent(v.slice(0, 100));57have_utm = true;58}5960if (have_utm) {61response["utm"] = UTM;62}6364// do we have a referrer? (not just "")65if (document.referrer.length > 0) {66response["referrer"] = document.referrer;67}6869// also keep a note about the very first landing page70response["landing"] = `${protocol}//${host}${pathname}`;7172// PREFIX could be "/", "//{domain}/", "/some/path", or even "//{domain}/some/path"73// @see backend/base-path.ts + hub/analytics.ts74// Note: don't use double // in the URL, because that will redirect and CORS doesn't work with redirects -- #550675const delim = PREFIX[PREFIX.length - 1] === "/" ? "" : "/";76const fetch_url = `${PREFIX}${delim}analytics.js`;7778// send back a beacon (token is in an http-only cookie)79window80.fetch(fetch_url, {81method: "POST",82mode: "cors",83cache: "no-cache",84credentials: "include",85headers: {86"Content-Type": "application/json",87},88redirect: "follow",89body: JSON.stringify(response),90})91//.then(response => console.log("Success:", response))92.catch((error) => console.error("Error:", error));9394// so it is a module.95export {};969798