Skip to content

Instantly share code, notes, and snippets.

@pke
Created May 23, 2013 11:59
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pke/5635575 to your computer and use it in GitHub Desktop.
Save pke/5635575 to your computer and use it in GitHub Desktop.
Windows Modern UI Google Analytics helpers
ApplicationView = Windows.UI.ViewManagement.ApplicationView
ApplicationViewState = Windows.UI.ViewManagement.ApplicationViewState
ApplicationLanguages = Windows.Globalization.ApplicationLanguages
CURRENT_RATE_LIMIT = MAX_RATE_LIMIT = 60
RATE_LIMIT_TICK = 2000
RATE_LIMITED_MESSAGE_QUEUE = new Queue()
logger = window.console
window.assert ||= (x, message) ->
throw new Error("Assert failed: #{message}") unless x
GA_CONFIG =
url: "https://www.google-analytics.com/collect"
method: "POST"
defaultParams:
v: 1
aip: 1
sr: "#{window.screen.width}x#{window.screen.height}"
sd: window.screen.colorDepth
ul: ApplicationLanguages.primaryLanguageOverride || ApplicationLanguages.languages[0]
configured = false
configureAnalytics = (trackingId, clientId, appName, appVersion) ->
assert(trackingId and clientId and appName and appVersion)
configured = true
GA_CONFIG.defaultParams.tid = trackingId
GA_CONFIG.defaultParams.cid = clientId
GA_CONFIG.defaultParams.an = appName
GA_CONFIG.defaultParams.av = appVersion
replenishRateLimit = () ->
if CURRENT_RATE_LIMIT < MAX_RATE_LIMIT
CURRENT_RATE_LIMIT += 1
queuedItem = RATE_LIMITED_MESSAGE_QUEUE.dequeue()
doSendRequestAsync(requestData) if queuedItem
setInterval(replenishRateLimit, RATE_LIMIT_TICK)
doSendRequestAsync = (requestData) ->
assert(configured, "Analytics needs to be configured. Call analytics.configure.")
CURRENT_RATE_LIMIT -= 1
WinJS.xhr
type: GA_CONFIG.method
url: GA_CONFIG.url
data: requestData
.then (result) ->
return
, (error) ->
logger.error(error)
return
sendRequestAsync = (request) ->
_.extend(request, GA_CONFIG.defaultParams)
request.z = Date.now() # cache buster
encodedRequest = String.uriEncodedFromObject(request)
if CURRENT_RATE_LIMIT is 0
RATE_LIMITED_MESSAGE_QUEUE.enqueue(encodedRequest)
WinJS.Promise.as()
else
doSendRequestAsync(encodedRequest)
trackEvent = (category, action, label) ->
sendRequestAsync
t: "event"
ec: category
ea: action
el: label
# also possible ev: "event value"
# combining it with "label" doesn't seem to work, though
return
endSessionAsync = sendRequestAsync.bind(@, sc: "end")
startSession = () ->
sendRequestAsync(sc: "start")
return
trackAppView = (pageName) ->
sendRequestAsync
t: "appview"
cd: pageName
return
# NAMESPACE EXPORTS
WinJS.Namespace.define "google.analytics",
configure: configureAnalytics
trackEvent: trackEvent
trackAppView: trackAppView
startSession: startSession
# end session is the only "proper" async function because it requires a deferral
# apart from that, waiting for GA calls is quite silly
endSessionAsync: endSessionAsync
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment