Improved JS tracking code and fixed bug that would not allow multiple mt() calls #3196

Open
wants to merge 18 commits into
from

Projects

None yet

3 participants

@alanhartless
Contributor
alanhartless commented Jan 6, 2017 edited
Q A
Bug fix? y
New feature?
Related user documentation PR URL
Related developer documentation PR URL
Issues addressed (#s or URLs)
BC breaks?
Deprecations?

Description:

Support for calling mt() multiple times only worked if the second mt() was wrapped in a setTimeout(). And then only for the first and second calls. Subsequent calls to mt() or back to back calls to mt() would fail. This PR fixes that.

It also now uses CORS by default to deliver the event. If the event fails, it falls back to creating a tracking pixel. This eliminates the need to make subsequent CORS requests to get the contact ID.

It also fixes a bug where the tracking pixel and/or CORS urls were forced to http if embedded into a http page but Mautic is under https.

It stores the contact ID and tracking pixel and appends it to the subsequent requests to prevent multiple visitor contacts from being created due to browsers not accepting cookies by default.

It adds an option in Configuration -> Landing Page Settings to opt into prior behavior of tracking contacts by IP.

Finally it prevents page hits and contacts from being created for requests from "do not track IPs."

Steps to test this PR:

  1. Embed the tracking code into a web page and add the call to mt() several times. Look at the contact's page hits. Each call to mt() should be registered.
  2. Configure CORS and do the same. A call to /mtc/event should be made instead of mtracking.gif. Again, each hit should be registered.
  3. Access Mautic on https and embed the tracking code on http. Tracking should still work.
  4. Configure the browser to only accepts cookies from sites previously visited. Clear the browser's cache (cookies, etc) if used to access Mautic before. Embed the tracking code on a domain other than that of Mautic (be sure to use dev if on local so that localhost IPs are acknowledged). Visit the page and then look at anonymous contacts in Mautic. Only one anonymous should be created.
  5. Enable the new track by IP option. Visit a tracked page. Clear all the cookies and local session and hit it again. The same contact should be used for subsequent requests. Disable the option and repeat (be sure to clear browser cache to avoid the new localStorage fix). This time a new contact should have been created.
  6. Add your IP to Configuration -> System Settings -> Do Not Track IPs (if on localhost, use 127.0.0.1). Clear browser cache and visit a tracked page. The hit nor contact should be created (good to avoid spam IP or known bot IPs).

Steps to reproduce the bug:

  1. Repeat #1 above but only the first mt() will be recorded.
  2. Repeat #3 above and will get a Response for preflight is invalid error in the browsers dev console
@alanhartless alanhartless added this to the 2.6.0 milestone Jan 6, 2017
@escopecz

Works nicely for me. Thanks Alan!

alanhartless added some commits Jan 6, 2017
@alanhartless alanhartless Fixed page URL when using tracking pixel da991b0
@alanhartless alanhartless Added option to track visitors by IP and prevented recording page hit…
…s from contacts with IPs on the do not track list (help prevent spam hits)
78a64d3
@alanhartless alanhartless Fixed bad loop that caused duplicate hits for the tracking pixel in s…
…ome cases.
6f4997d
@alanhartless alanhartless Store tracking information in localStorage to return with subsequent …
…CORS requests and pixel to prevent multiple anonymous hits for browsers that won't accept the cookie by default (i.e. if Mautic is on a different domain than the website being tracked)
4cf36d3
@escopecz
Contributor
escopecz commented Jan 9, 2017
  1. Page hits sent from local to a Mautic on a live domain, HTTP, Restrict domains: off:
  • Requests via CORS. OPTIONS requests were successful as well as POST requests.
  • The contact was created as anonymous even though there was an email address in the request query.
  1. Page hits sent from local to a Mautic on a live domain, HTTP, Restrict domains: on, valid domains: none:
  • Requests via mtracking.gif
  • Again, the page hits were assigned to the same anonymous contact as above, no email address saved.
  1. Page hits sent from local to a Mautic on a live domain, HTTP, Restrict domains: on, valid domains: http://localhost:
  • Requests via CORS
  • Again, the page hits were assigned to the same anonymous contact as above, no email address saved.
  1. Page hits sent from local to a Mautic on a live domain, HTTPS, Restrict domains: on, valid domains: http://localhost:
  • Requests via CORS
  • Again, the page hits were assigned to the same anonymous contact as above, no email address saved.
  1. Page hits sent from local to a local Mautic, HTTP, Restrict domains: off:
  • Requests via CORS. OPTIONS requests were successful as well as POST requests.
  • The contact was created as identified contact with the email address from the request query.

Any idea why the URL query params are saved on my local and not on my semi-production Mautic on a live domain?

@escopecz
Contributor
escopecz commented Jan 9, 2017

So all my problems with my remote Mautic was that I did not set the email field to be publicly updatable. Everything works as described 👍

@escopecz
Contributor

The fingerprint values are back for me 👍 Thanks!

$pageTrackingCORSUrl = str_replace(
- ['http://', 'https://'],
@dongilbert
dongilbert Jan 10, 2017 Member

Doesn't this result in having a $pageTrackingCORSUrl that starts with // if their mautic is behind an SSL? Same for $pageTrackingUrl and $contactIdUrl. As an example: https://repl.it/FF78/0

- m.pageTrackingUrl = (l.protocol == 'https:' ? 'https:' : 'http:') + '//{$pageTrackingUrl}';
- m.pageTrackingCORSUrl = (l.protocol == 'https:' ? 'https:' : 'http:') + '//{$pageTrackingCORSUrl}';
+ m.pageTrackingUrl = (l.protocol == 'https:' ? 'https:' : '{$scheme}:') + '//{$pageTrackingUrl}';
+ console.log(m.pageTrackingUrl);
@dongilbert
dongilbert Jan 10, 2017 Member

Latent console.log

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