Google Analytics Data Export API with Ruby + Gattica
Download Gattica (with goals and segment support) on GitHub
Getting Google Analytics data export API is amazingly fun! I originally contributed to the open source Google Analytics library for PHP. Recently, I’ve been coding in Ruby for it’s speed and agility.
Ruby is amazing! In 15 lines of code I could get all visits, bounces, for every client, by month.
To date, Ruby only has two Ruby Gems to interface with the Google Analytics API: Garb and Gattica. Unfortunately, they both seem to be missing some of the deeper areas of the API:
Why Garb’s and Gattica’s code didn’t work for me
- Garb’s filtering is not flexible. Using Garb’s report classes becomes very limiting, very quickly when you’re attempting to do some deep work in the API. Stevenwilkin added a hack to support dynamic segments.
- Gattica 0.3.3 doesn’t fully support goals or segments. Too bad! Gattica is very easy to use but didn’t support what I needed to do.
Solved: Wrote code. Made available to everyone
So, my solution was to add my proverbial brick to Gattica so that it supported goals and segments. You can download my fork of Gattica on GitHub.
Quick start for developers:
Include it your Rails app by adding one line to your gemfile
gem 'gattica', '>=0.3.3.4',
:git => 'git://github.com/chrisle/gattica.git'
(Make sure to run ‘bundle install’ afterwards.)
Or… download and build it yourself
wget https://github.com/chrisle/gattica/tarball/master
tar -zxvf chrisle-gattica-*
cd chrisle-gattica-*
git build gattica.gemspec
git install gattica
Conntect to Google Analytics
ga = Gattica.new({ :email => 'johndoe@google.com',
:password => 'password',
:timeout => 500 })
Collect the accounts that the authenticated user has access to and show them on the screen
accounts = ga.accounts
accounts.each do |a|
puts a.title # => "www.mywebsite.com"
puts a.web_property_id # => "UA-1234567-12"
puts a.profile_id # => 55555
end
Specify an account and get visitor and bounce data for this month
ga.profile_id = 55555
results = ga.get({ :start_date => '2011-01-01',
:end_date => '2011-02-01',
:dimensions => ['month', 'year'],
:metrics => ['visits', 'bounces'],
:sort => ['year', 'month']})
Find the first profile that has goals
first_profile_with_goals = accounts.detect {
|a| a.ga_goals.count > 0
}
Collect a list of segments available to the authenticated user and display them
all_segments = ga.segments
all_segments.each {|s| puts "name: " + s.name + ", id: " + s.id}
Segment by a mobile traffic (Google’s default user segment gaid::-11)
ga.profile_id = 55555
mobile_traffic_segment = "gaid::-11"
results = ga.get({ :start_date => '2011-01-01',
:end_date => '2011-02-01',
:dimensions => ['month', 'year'],
:metrics => ['visits', 'bounces'],
:sort => ['year', 'month'],
:segment => [mobile_traffic_segment]})
Thanks to code ninja Bob Brodie of Sumo Heavy fame for introducing me to Ruby On Rails.
Posted: 02.22.11


Adrian Drysdale:
Great research as usual. I always come on here to get some great tips, seems like Seer are the only ones actually coming up with their own ideas instead of rewriting old ones.
Dev Basu:
It’s amazing that all of that could be accomplished in only 15 lines of code. I’m going to have my developer look over this and see if we can dig into deeper reports like extracting event actions and categories.
Chris Le:
Thanks! Check out the repository on GitHub. I recently found that “hpricot” (a separate required Gem) crashes. The latest version of Gattica compensates for that so it doesn’t crash! Hazzah!
Rocky:
Hi Chris,
I was trying to follow your instructions, but when I run:
ga = Gattica.new({ :email => ‘MY EMAIL’,
:password => ‘MY PASSWORD’,
:timeout => 500 })
I keep getting:
You have a nil object when you didn’t expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.split
Any idea what could be wrong?
Thanks!
Chris Le:
I’m not sure off the top of my head. Let’s move this discussion to the official trouble tickets on GitHub: (https://github.com/chrisle/gattica/issues)
roger:
I hope the little boy from that picture didn’t code it…or did he?