require 'rack'
class MixpanelMiddleware
def initialize(app, mixpanel_token, options={})
@app = app
@token = mixpanel_token
@options = {
:async => false
}.merge(options)
end
def call(env)
@env = env
@status, @headers, @response = @app.call(env)
update_response!
update_content_length!
delete_event_queue!
[@status, @headers, @response]
end
private
def update_response!
@response.each do |part|
if is_regular_request? && is_html_response?
insert_at = part.index(' new_size.to_s)
end
def is_regular_request?
!is_ajax_request?
end
def is_ajax_request?
@env.has_key?("HTTP_X_REQUESTED_WITH") && @env["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest"
end
def is_html_response?
@headers["Content-Type"].include?("text/html") if @headers.has_key?("Content-Type")
end
def is_javascript_response?
@headers["Content-Type"].include?("text/javascript") if @headers.has_key?("Content-Type")
end
def render_mixpanel_scripts
if @options[:async]
<<-EOT
EOT
else
<<-EOT
EOT
end
end
def delete_event_queue!
@env.delete('mixpanel_events')
end
def queue
return [] if !@env.has_key?('mixpanel_events') || @env['mixpanel_events'].empty?
@env['mixpanel_events']
end
def render_event_tracking_scripts(include_script_tag=true)
return "" if queue.empty?
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")
end
output = "try {#{output}} catch(err) {}"
include_script_tag ? "" : output
end
end