Skip to content

Add a filter function to plugins to filter out events so that they are not tracked - #1326

Merged
Matus Tomlein (matus-tomlein) merged 4 commits into
release/4.0.0from
issue/plugin_filter
Jul 11, 2024
Merged

Add a filter function to plugins to filter out events so that they are not tracked#1326
Matus Tomlein (matus-tomlein) merged 4 commits into
release/4.0.0from
issue/plugin_filter

Conversation

@matus-tomlein

Copy link
Copy Markdown
Contributor

Adds a new filter(payload) function to plugins which accepts the payload and returns a boolean deciding whether the event should be tracked or skipped. This has various use cases such as:

  • sampling events
  • being able to forward events to another tracker (WebView tracker in particular) without tracking them from the JS tracker
  • usage in unit tests to avoid making actual requests
  • ...

In addition to the new function, I had to change the return type of the track() function in the tracker core. Previously it always returned Payload. Now in case an event is filtered out, the function returns undefined. This should not affect the usage of the browser or node trackers, but still is a breaking change so adding this to v4.

@bundlemon

bundlemon Bot commented Jul 9, 2024

Copy link
Copy Markdown

BundleMon

Files added (6)
Status Path Size Limits
libraries/browser-tracker-core/dist/index.mod
ule.js
+27.33KB 28KB / +10%
trackers/javascript-tracker/dist/sp.js
+26.13KB 25.5KB / +10%
trackers/javascript-tracker/dist/sp.lite.js
+15.45KB 16KB / +10%
trackers/browser-tracker/dist/index.umd.min.j
s
+15.31KB 16KB / +10%
libraries/tracker-core/dist/index.module.js
+13.46KB 15KB / +10%
trackers/browser-tracker/dist/index.module.js
+3.49KB 5KB / +10%

Total files change +101.16KB 0%

Final result: ❌

View report in BundleMon website ➡️


Current branch size history

Comment thread libraries/tracker-core/src/core.ts Outdated
// Call the filter on plugins to determine if the event should be tracked
const skip = corePlugins.find((plugin) => {
try {
return plugin.filter && !plugin.filter(pb.build());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also pass the SDJs explicitly? I always find working with Payload directly kind of awkward since you have to check for ue_px/cx and possibly decode them (and since URL safe base64 isn't usually covered by btoa you may require a dependency for that)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to explicitly check for === false here to avoid accidents? Or is skipping on falsey values like undefined/null a useful convenience?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also pass the SDJs explicitly? I always find working with Payload directly kind of awkward since you have to check for ue_px/cx and possibly decode them (and since URL safe base64 isn't usually covered by btoa you may require a dependency for that)

This is a very good point, I agree that it's super annoying to work with the Payload and the PayloadBuilder. I think this is something we can improve with some breaking changes in the v4 tracker. I want to add a getContextEntities and getSelfDescribing event function to the PayloadBuilder and pass that information along with the payload to afterTrack and filter here but in order to do that we need to make changes to the PayloadBuilder (so that we don't have to parse the cx and ue_px values). I will raise a separate PR to do this.

Would it be better to explicitly check for === false here to avoid accidents? Or is skipping on falsey values like undefined/null a useful convenience?

I kind of think that skipping falsey values is useful as we have been getting these tickets where people use JS or ignore the types and just return null where we don't expect it...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kind of think that skipping falsey values is useful as we have been getting these tickets where people use JS or ignore the types and just return null where we don't expect it...

Haha, that's exactly why I think we should be more pedantic about it. 😂

"Oh we goofed our filter function and accidentally tracked some events we didn't mean to" vs "FFFFFUUUUU we goofed our filter function and have irrevocably lost a bunch of events that were important!".

Though I guess once someone inevitably uses this for PII removal the situation will be reversed so we can't really win.

I was thinking that rather than split filter out we just make it so beforeTrack can throw Error("SKIP_EVENT") or something very specific and if we get that exact exception we do the skip. More explicit, harder to do anything accidentally.

PayloadBuilder changes sound great!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, I didn't think this through, checking for === false is safer in this case 😅 Will change that.

About the idea to throw an error from the beforeTrack function instead of having a dedicated filter one – that could work too, but I prefer filter for two reasons:

  1. We can ensure that the filter is called after all plugin beforeTrack functions are applied and thus the payload is kind of complete. So one can check for more things, like context entities added by other plugins in the filter function.
  2. We have the same filter API in the plugins on mobile trackers so it's nice to be consistent on the API. It also makes it a bit more obvious that it is possible to filter events.

Comment thread api-docs/docs/node-tracker/markdown/node-tracker.coreplugin.md

@jethron Jethro Nederhof (jethron) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants