Browse Extension Tracking via Snowplow

Hi,

Apologies if categorised incorrectly.

We have deployed Snowplow Analytics tracking to our Browser Extension. Our Browser Extension will be for end users to use while browser different websites (other than our own).

I have noticed that each time a new website is visited, the domain session id changes despite the user being active in the browser extension within 30 minutes.

Is there a way to isolate the session to the browser extension activity as opposed to the activity of the user change websites?

Thanks,

It sounds like you’re using the content scripts to do the tracking so the tracker gets loaded in the page’s context and so drops cookies for each site?

It will depend on what events you’re tracking and the information that’s most important to you, you will probably lose some of the native tracker functionality by “fixing” this.

The two easiest approaches are probably:

  • Centralize your tracker in the background service worker, and instead of calling the tracker from your content scripts, send messages to the background worker (e.g. via chrome.runtime.sendMessage); this should make all your Domain User/Session IDs consistent, but you will lose so information that is only accessible from the document that the content scripts have. Some of this (URL, referrer, page title) you could pass through in your messages and manually set when you call the tracker; other things will probably not get (document size etc). The service worker may only be able to send requests using fetch() though, so I’m not 100% sure this will work with the official SDKs.
  • Manually synchronise some of the tracker state between each batch of events you try to send. Assuming you already have permission to the storage API you would just wrap any code that sends events in some boilerplate to synchronise the IDs with some in shared storage. This is clunky but should work for most events that aren’t automatic (like page pings, link clicks, etc – Anything fired by the SDK that you can’t wrap in your synchronisation boilerplate.)

Something like this is probably a good starting point:

/* Content script */
import { newTracker } from "@snowplow/browser-tracker";

const tracker = newTracker("myextension", "mycollector.example.com", {stateStorageStrategy: "localStorage"});

const syncSnowplow = (cb) => {
	chrome.storage.local.get({
		sp_tracker_state_id: localStorage.getItem(tracker.getCookieName("id")),
		sp_tracker_state_expiry: localStorage.getItem(tracker.getCookieName("ses") + ".expires")
	}, ({sp_tracker_state_id, sp_tracker_state_expiry}) => {
		localStorage.setItem(tracker.getCookieName("id"), sp_tracker_state_id);
		localStorage.setItem(tracker.getCookieName("ses"), "*");
		localStorage.setItem(tracker.getCookieName("ses") + ".expires", sp_tracker_state_expiry);

		cb(tracker);

		chrome.storage.local.set({
			sp_tracker_state_id: localStorage.getItem(tracker.getCookieName("id")),
			sp_tracker_state_expiry: localStorage.getItem(tracker.getCookieName("ses") + ".expires")
		});
	})
};

syncSnowplow((tracker) => tracker.trackPageView());
syncSnowplow((tracker) => tracker.trackStructEvent({category: 'cat', action: 'act', label: 'lab'}));
syncSnowplow((tracker) => /* etc... */ void 0);

I’m assuming here you’re using the Browser Tracker because loading third-party scripts for the Javascript tracker from content scripts can be difficult in it’s own way.

1 Like

This is helpful! Thanks a lot. It seems more difficult than first thought so I think we will elect to build a pesudo session based on network user id and time diff between sessions.