diff --git a/assets/src/js/components/SiteSettings.js b/assets/src/js/components/SiteSettings.js index 715f343..5a2960c 100644 --- a/assets/src/js/components/SiteSettings.js +++ b/assets/src/js/components/SiteSettings.js @@ -101,6 +101,7 @@ class SiteSettings extends Component { o.async=1; o.src=t; o.id='fathom-script'; m.parentNode.insertBefore(o,m) })(document, window, '//stats.usefathom.com/tracker.js', 'fathom'); +fathom('set', 'siteId', '${props.site.trackingId}'); fathom('trackPageview'); `} diff --git a/assets/src/js/tracker.js b/assets/src/js/tracker.js index 3bb5cd4..674d13d 100644 --- a/assets/src/js/tracker.js +++ b/assets/src/js/tracker.js @@ -1,12 +1,18 @@ 'use strict'; let queue = window.fathom.q || []; -let trackerUrl = ''; - -const commands = { - "trackPageview": trackPageview, - "setTrackerUrl": setTrackerUrl, +let config = { + 'siteId': '', + 'trackerUrl': '', }; +const commands = { + "set": set, + "trackPageview": trackPageview, +}; + +function set(key, value) { + config[key] = value; +} // convert object to query string function stringifyObject(obj) { @@ -93,15 +99,7 @@ function findTrackerUrl() { return el ? el.src.replace('tracker.js', 'collect') : ''; } -function setTrackerUrl(v) { - trackerUrl = v; -} - -function trackPageview() { - if(trackerUrl === '') { - trackerUrl = findTrackerUrl(); - } - +function trackPageview() { // Respect "Do Not Track" requests if('doNotTrack' in navigator && navigator.doNotTrack === "1") { return; @@ -149,10 +147,12 @@ function trackPageview() { u: data.pagesViewed.indexOf(path) == -1 ? 1 : 0, nv: data.isNewVisitor ? 1 : 0, ns: data.isNewSession ? 1 : 0, + sid: config.siteId, }; + let url = config.trackerUrl || findTrackerUrl() let i = document.createElement('img'); - i.src = trackerUrl + stringifyObject(d); + i.src = url + stringifyObject(d); i.addEventListener('load', function() { let now = new Date(); let midnight = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 24, 0, 0); diff --git a/pkg/api/collect.go b/pkg/api/collect.go index cc0c2e2..b26885e 100644 --- a/pkg/api/collect.go +++ b/pkg/api/collect.go @@ -53,16 +53,17 @@ func (c *Collector) ServeHTTP(w http.ResponseWriter, r *http.Request) { // get pageview details pageview := &models.Pageview{ - ID: q.Get("id"), - Hostname: parseHostname(q.Get("h")), - Pathname: parsePathname(q.Get("p")), - IsNewVisitor: q.Get("nv") == "1", - IsNewSession: q.Get("ns") == "1", - IsUnique: q.Get("u") == "1", - IsBounce: q.Get("b") != "0", - Referrer: parseReferrer(q.Get("r")), - Duration: 0, - Timestamp: now, + ID: q.Get("id"), + SiteTrackingID: q.Get("sid"), + Hostname: parseHostname(q.Get("h")), + Pathname: parsePathname(q.Get("p")), + IsNewVisitor: q.Get("nv") == "1", + IsNewSession: q.Get("ns") == "1", + IsUnique: q.Get("u") == "1", + IsBounce: q.Get("b") != "0", + Referrer: parseReferrer(q.Get("r")), + Duration: 0, + Timestamp: now, } // push pageview onto channel to be inserted (in batch) later diff --git a/pkg/api/sites.go b/pkg/api/sites.go index 9daa13c..55898f1 100644 --- a/pkg/api/sites.go +++ b/pkg/api/sites.go @@ -30,7 +30,7 @@ func (api *API) SaveSiteHandler(w http.ResponseWriter, r *http.Request) error { // generate tracking ID if this is a new site if s.ID == 0 && s.TrackingID == "" { - s.TrackingID = randomString(8) + s.TrackingID = generateTrackingID() } if err := api.database.SaveSite(s); err != nil { @@ -55,10 +55,14 @@ func (api *API) DeleteSiteHandler(w http.ResponseWriter, r *http.Request) error return respond(w, http.StatusOK, envelope{Data: true}) } +func generateTrackingID() string { + return randomString(2) + "-" + randomString(2) +} + func randomString(len int) string { bytes := make([]byte, len) for i := 0; i < len; i++ { - bytes[i] = byte(65 + rand.Intn(25)) //A=65 and Z = 65+25 + bytes[i] = byte(97 + rand.Intn(25)) //a=97 and z = 97+25 } return string(bytes) diff --git a/pkg/datastore/sqlstore/pageviews.go b/pkg/datastore/sqlstore/pageviews.go index b380e39..71cc855 100644 --- a/pkg/datastore/sqlstore/pageviews.go +++ b/pkg/datastore/sqlstore/pageviews.go @@ -33,7 +33,7 @@ func (db *sqlstore) InsertPageviews(pageviews []*models.Pageview) error { } // generate placeholders string - placeholderTemplate := "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)," + placeholderTemplate := "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)," placeholders := strings.Repeat(placeholderTemplate, n) placeholders = placeholders[:len(placeholders)-1] nPlaceholders := strings.Count(placeholderTemplate, "?") @@ -47,19 +47,20 @@ func (db *sqlstore) InsertPageviews(pageviews []*models.Pageview) error { for i := range pageviews { j = i * nPlaceholders values[j] = pageviews[i].ID - values[j+1] = pageviews[i].Hostname - values[j+2] = pageviews[i].Pathname - values[j+3] = pageviews[i].IsNewVisitor - values[j+4] = pageviews[i].IsNewSession - values[j+5] = pageviews[i].IsUnique - values[j+6] = pageviews[i].IsBounce - values[j+7] = pageviews[i].Referrer - values[j+8] = pageviews[i].Duration - values[j+9] = pageviews[i].Timestamp + values[j+1] = pageviews[i].SiteTrackingID + values[j+2] = pageviews[i].Hostname + values[j+3] = pageviews[i].Pathname + values[j+4] = pageviews[i].IsNewVisitor + values[j+5] = pageviews[i].IsNewSession + values[j+6] = pageviews[i].IsUnique + values[j+7] = pageviews[i].IsBounce + values[j+8] = pageviews[i].Referrer + values[j+9] = pageviews[i].Duration + values[j+10] = pageviews[i].Timestamp } // string together query & execute with values - query := `INSERT INTO pageviews(id, hostname, pathname, is_new_visitor, is_new_session, is_unique, is_bounce, referrer, duration, timestamp) VALUES ` + placeholders + query := `INSERT INTO pageviews(id, site_tracking_id, hostname, pathname, is_new_visitor, is_new_session, is_unique, is_bounce, referrer, duration, timestamp) VALUES ` + placeholders query = db.Rebind(query) _, err := db.Exec(query, values...) if err != nil { diff --git a/pkg/models/site.go b/pkg/models/site.go index 95b53e1..65cac69 100644 --- a/pkg/models/site.go +++ b/pkg/models/site.go @@ -3,6 +3,6 @@ package models // Site represents a group for tracking data type Site struct { ID int64 `db:"id" json:"id"` - TrackingID string `db:"tracking_id" json:"tracking_id"` + TrackingID string `db:"tracking_id" json:"trackingId"` Name string `db:"name" json:"name"` }