lib/mixpanel/tracker/middleware.rb in mixpanel-1.1.3 vs lib/mixpanel/tracker/middleware.rb in mixpanel-2.0.0
- old
+ new
@@ -1,25 +1,28 @@
require 'rack'
+require 'json'
module Mixpanel
class Tracker
class Middleware
def initialize(app, mixpanel_token, options={})
@app = app
@token = mixpanel_token
@options = {
- :async => false,
- :insert_js_last => false
+ :insert_js_last => false,
+ :persist => false,
+ :config => {}
}.merge(options)
end
def call(env)
@env = env
@status, @headers, @response = @app.call(env)
if is_trackable_response?
+ merge_queue! if @options[:persist]
update_response!
update_content_length!
delete_event_queue!
end
@@ -65,59 +68,72 @@
def is_javascript_response?
@headers["Content-Type"].include?("text/javascript") if @headers.has_key?("Content-Type")
end
def is_trackable_response?
+ return false if @status == 302
is_html_response? || is_javascript_response?
end
def render_mixpanel_scripts
- if @options[:async]
- <<-EOT
- <script type='text/javascript'>
- var mpq = [];
- mpq.push(["init", "#{@token}"]);
- (function(){var b,a,e,d,c;b=document.createElement("script");b.type="text/javascript";b.async=true;b.src=(document.location.protocol==="https:"?"https:":"http:")+"//api.mixpanel.com/site_media/js/api/mixpanel.js";a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(b,a);e=function(f){return function(){mpq.push([f].concat(Array.prototype.slice.call(arguments,0)))}};d=["track","track_links","track_forms","register","register_once","identify","name_tag","set_config"];for(c=0;c<d.length;c++){mpq[d[c]]=e(d[c])}})();
+ <<-EOT
+ <!-- start Mixpanel -->
+ <script type="text/javascript">
+ (function(c,a){var b,d,h,e;b=c.createElement("script");b.type="text/javascript";
+ b.async=!0;b.src=("https:"===c.location.protocol?"https:":"http:")+
+ '//api.mixpanel.com/site_media/js/api/mixpanel.2.js';d=c.getElementsByTagName("script")[0];
+ d.parentNode.insertBefore(b,d);a._i=[];a.init=function(b,c,f){function d(a,b){
+ var c=b.split(".");2==c.length&&(a=a[c[0]],b=c[1]);a[b]=function(){a.push([b].concat(
+ Array.prototype.slice.call(arguments,0)))}}var g=a;"undefined"!==typeof f?g=a[f]=[]:
+ f="mixpanel";g.people=g.people||[];h=['disable','track','track_pageview','track_links',
+ 'track_forms','register','register_once','unregister','identify','name_tag',
+ 'set_config','people.set','people.increment'];for(e=0;e<h.length;e++)d(g,h[e]);
+ a._i.push([b,c,f])};a.__SV=1.1;window.mixpanel=a})(document,window.mixpanel||[]);
+
+ mixpanel.init("#{@token}");
+ mixpanel.set_config(#{@options[:config].to_json});
</script>
- EOT
- else
- <<-EOT
- <script type='text/javascript'>
- var mp_protocol = (('https:' == document.location.protocol) ? 'https://' : 'http://');
- document.write(unescape('%3Cscript src="' + mp_protocol + 'api.mixpanel.com/site_media/js/api/mixpanel.js" type="text/javascript"%3E%3C/script%3E'));
- </script>
- <script type='text/javascript'>
- try {
- var mpmetrics = new MixpanelLib('#{@token}');
- } catch(err) {
- null_fn = function () {};
- var mpmetrics = {
- track: null_fn, track_funnel: null_fn, register: null_fn, register_once: null_fn, register_funnel: null_fn
- };
- }
- </script>
- EOT
- end
+ <!-- end Mixpanel -->
+ EOT
end
def delete_event_queue!
- @env.delete('mixpanel_events')
+ if @options[:persist]
+ (@env['rack.session']).delete('mixpanel_events')
+ else
+ @env.delete('mixpanel_events')
+ end
end
def queue
- return [] if !@env.has_key?('mixpanel_events') || @env['mixpanel_events'].empty?
- @env['mixpanel_events']
+ if @options[:persist]
+ return [] if !(@env['rack.session']).has_key?('mixpanel_events') || @env['rack.session']['mixpanel_events'].empty?
+ @env['rack.session']['mixpanel_events']
+ else
+ return [] if !@env.has_key?('mixpanel_events') || @env['mixpanel_events'].empty?
+ @env['mixpanel_events']
+ end
end
- def render_event_tracking_scripts(include_script_tag=true)
- return "" if queue.empty?
+ def merge_queue!
+ present_hash = {}
+ special_events = ['identify', 'name_tag', 'people.set', 'register']
+ queue.uniq!
- if @options[:async]
- output = queue.map {|type, arguments| %(mpq.push(["#{type}", #{arguments.join(', ')}]);) }.join("\n")
- else
- output = queue.map {|type, arguments| %(mpmetrics.#{type}(#{arguments.join(', ')});) }.join("\n")
+ queue.reverse_each do |item|
+ is_special = special_events.include?(item[0])
+ if present_hash[item[0]] and is_special
+ queue.delete(item)
+ else
+ present_hash[item[0]] = true if is_special
+ end
end
+ end
+ def render_event_tracking_scripts(include_script_tag=true)
+ return "" if queue.empty?
+
+ output = queue.map {|type, arguments| %(mixpanel.#{type}(#{arguments.join(', ')});) }.join("\n")
output = "try {#{output}} catch(err) {}"
include_script_tag ? "<script type='text/javascript'>#{output}</script>" : output
end
end