Touchstone is a Rails Engine that adds the ability to track advanced metrics for your web app. It is inspired by this post on the Think Vitamin blog. I would recommend reading that article to understand what Touchstone does.
Please consider this an alpha release. Versions will be released fairly quickly. Hopefully nothing will break but I'm trying to get this running in production on one of my apps so correcting errors as I go.
Touchstone consists of 3 classes:
A campaign records the details of a source from which visitors will sign up to your website. It can be a Google Adwords campaign or a link on your homepage.
By adding the parameter ?cid= to each link, the visit will be recorded.
When a visitor visits your website via a link containing ?cid= and then signs up, the sign up is tied back to that visit and that campaign. You can then track the revenue obtained from each visitor against the cost of a particular campaign.
Touchstone requires your application to have something like a User model. The model doesn't need to be called User (you can configure this) but the purpose of Touchstone is to track users who signup to your application in response to a campaign.
The views are built using Bootstrap so installing Touchstone will introduce dependencies on the sass and sass-bootstrap gems.
Add the following line to your Gemfile:
gem 'touchstone'
Then run bundle install
Once the gem has been installed run rails g touchstone
This will:
- Copy an initializer file to
config/initializers/touchstone.rb
. You should read this file and set your configuration options before proceeding Add a before filter to your application controller. NB: This defaults to setting a private method for the filter. If you already haveNot currently working. You will need to update application_controller.rb manually. See below.private
defined in your application controller, you will need to remove the duplicate declaration.- Mounts the engine in your routes.rb file
By default, Touchstone will require http_basic authentication to access. The credentials for access will be read from a YAML file called touchstone.yml in your config folder. You will need to create this file unless you choose not to restrict access to Touchstone (not recommended).
Copy the migrations across to your application by running rake touchstone:install:migrations
. This will add migrations to create the tables for the 3 classes set out above.
If, for any reason the command rails g touchstone
has not made the correct changes to your files, these are the changes that need to be made and can be made manually. If you do not have a User
model, the configuration option association_name
in the Touchstone initializer must be set before running the Touchstone migrations.
You will need to mount Touchstone in your application by adding the following line to your routes.rb
file:
mount Touchstone::Engine, :at => "/touchstone/"
Add the following to your application_controller.rb
file:
before_filter :set_cookie_and_record_visit
private
def set_cookie_and_record_visit
if params[:cid] && Campaign.find_by_id(params[:cid]) && !CampaignVisit.find_by_request_ip(request.remote_ip)
if !cookies['touchstone_campaign_id']
cookies['touchstone_campaign_id'] = "#{params[:cid]}"
CampaignVisit.create(:campaign_id => params[:cid], :request_ip => request.remote_ip)
end
end
end
Restart your server, and if you now visit http://yourdomain.com/touchstone
, you will see the default page.
Usage is very simple. Assume you are running a Google Adwords campaign for 1 week at a cost of $100. Create this campaign in Touchstone and it will return a campaign ID. Make sure all your links on Adwords contain the parameter at the end ?cid={campaign_id}
where campaign_id
is the id generated by Touchstone. Please note:
- Campaigns don't need to be paid campaigns, it can be as simple as a link on your homepage
- You can update the campaign cost at any time. All calculations are "on the fly" so you're metrics will update automatically
The installation steps described above will get you going with tracking visits from particular campaigns but you still have some work to do in linking this to your users. Touchstone only really provides a benefit when you track how much revenue your users bring in and then it will compare that to the cost of your campaigns. By way of examples only, you could adopt the following pattern to record a campaign signup:
class UsersController < ApplicationController
...
def create
@user = User.new(params[:user])
if @user.save
unless cookies['touchstone_campaign_id'].nil?
campaign_id = cookies['touchstone_campaign_id']
CampaignSignup.create(:user_id => @user.id, :campaign_id => campaign_id)
end
flash["notice"] = "Successfully signed up"
...
end
end
end
Touchstone requires your user model to have a method called lifetime_value in order to calculate the revenue that a user has generated. Tracking a user's lifetime value will depend on your transactional logic but assuming a common pattern of a user having a subscription and that subscription containing many transactions, the following could be used:
class User < ActiveRecord::Base
...
def lifetime_value
total = Array.new
self.subscription.transactions.each do |t|
total << t.amount
end
total.inject{|sum,x| sum + x}
end
...
end
- Add some tests
- Copy css and js to application