I’ve been investigating methods for performing affiliate based click tracking, for both work and my own personal needs. I’ve tried using Rails directly, Sinatra and Rack.
- Rails – Slow, hell no.
- Sinatra – Fast, but now another app to maintain (as small as it is), but still an option.
- Rack – Faster than Rails, slower than Sinatra. Less to manage.
I built some Rack middleware today, and thought I’d show you guys what I came up with. Here is how it works:
- Surfer hits http://click.ourdomain.com/track/7868635/campaign/some/path/here.
- Rack takes the request, shoves into Redis using lists.
- Rack sets a cookie.
- Rack redirects to http://ourdomain.com/some/path/here.
- A daemon polls Redis to post process the data. This is out of the scope of this post though, maybe later.
You might be wondering what’s with the url. Simple, the digit is the affiliateID, the ‘campaign’ is whatever dynamic text-tag they want for organizing the traffic, and /some/path/here is where on ourdomain.com to redirect the user. This allows affiliates to send surfers anywhere on the site and still get credit, no need for generating custom links.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | require 'rubygems' require 'redis' class Click def initialize(app) @app = app end def call(env) if env["PATH_INFO"] =~ /^\/track\/([0-9]+)\/[a-zA-Z0-9-]+\/(.*)/ host = parse_host(env["HTTP_HOST"]) add_click_to_queue(env) response = Rack::Response.new("Redirecting ...") response.set_cookie("click#{host[:domain]}", { :domain => host[:domain], :path => '/', :expires => 30.days.from_now, :value => $1 }) response.redirect("#{host[:host]}/#{$2}") response.finish else @app.call(env) end end def parse_host(host) base = host.split('.', 2)[1] { :host => "http://#{base}", :domain => ".#{base.split(':').first}" } end def add_click_to_queue(env) redis ||= Redis.new redis.push_tail 'clicks', Marshal.dump({ :path => env["PATH_INFO"], :ip => env["REMOTE_ADDR"] }) end end |
This is just a mockup. Like I said, I’m not covering the post-processing of the data by polling Redis, that might come soon. I encourage you to leave comments on better methods for doing tracking clicks, integrating with Redis, etc. Thanks to @seanstickle for helping me on the cookie details.
Werd.
Related posts: