Skip to content
This repository
Newer
Older
100644 501 lines (376 sloc) 15.288 kb
b399e2e9 » Chris Le
2011-05-29 Completely rewrote README documentation.
1 Gattica
2 =======
3 Gattica is an easy to use Gem for getting data from the Google Analytics API.
4
5 Features
6 --------
7 * Supports: metrics, dimensions, sorting, filters, goals, and segments.
8 * Handles accounts with over 1000 profiles
9 * Returns data as: hash, json, CSV
10
11 [How to export Google Analytics data using Ruby](
12 http://www.seerinteractive.com/blog/google-analytics-data-export-api-with-rubygattica/2011/02/22/) (Links to my blog post on [Seer Interactive](http://www.seerinteractive.com))
13
14 <hr />
15
16 Quick Start
17 ===========
18 Here are bare basics to get you up and running.
19
20 Installation
21 ------------
22 Add Gattica to your Gemfile
23
24 gem 'gattica', :git => 'git://github.com/chrisle/gattica.git'
25
26 Don't forget to bundle install:
27
28 $ bundle install
29
30 Login, get a list of accounts, pick an account, and get data:
31
32 # Include the gem
33 require 'gattica'
34
35 # Login
36 ga = Gattica.new({
37 :email => 'email@gmail.com',
38 :password => 'password'
39 })
40
41 # Get a list of accounts
42 accounts = ga.accounts
43
44 # Choose the first account
45 ga.profile_id = accounts.first.profile_id
46
47 # Get the data
48 data = ga.get({
49 :start_date => '2011-01-01',
50 :end_date => '2011-04-01',
51 :dimensions => ['month', 'year'],
52 :metrics => ['visits', 'bounces'],
53 })
54
55 # Show the data
56 puts data.inspect
57
58 <hr />
59
60 General Usage
61 =============
62
63 ### Create your Gattica object
64
65 ga = Gattica.new({ :email => 'email@gmail.com', :password => 'password' })
66 puts ga.token # => returns a big alpha-numeric string
67
68 ### Query for accounts you have access to
69
70 # Retrieve a list of accounts
71 accounts = ga.accounts
72
73 # Show information about accounts
74 puts "---------------------------------"
75 puts "Available profiles: " + accounts.count.to_s
76 accounts.each do |account|
77 puts " --> " + account.title
78 puts " last updated: " + account.updated.inspect
79 puts " web property: " + account.web_property_id
80 puts " profile id: " + account.profile_id.inspect
81 puts " goals: " + account.goals.count.inspect
82 end
83
84 ### Set which profile Gattica needs to use
85
86 # Tell Gattica to query profile ID 5555555
87 ga.profile_id = 5555555
88
89 ### Get data from Google Analytics
90
91 The Get method will get data from Google Analytics and return Gattica::DataSet type.
92
93 * Dates must be in 'YYYY-MM-DD' format.
94 * Dimensions and metrics can be gotten from [Google Analytics Dimensions & Metrics Reference](http://code.google.com/apis/analytics/docs/gdata/gdataReferenceDimensionsMetrics.html)
95 * You do not need to use "ga:" at the beginning of the strings.
96
97 Here's an example:
98
99 # Get the number of visitors by month from Jan 1st to April 1st.
100 data = ga.get({
101 :start_date => '2011-01-01',
102 :end_date => '2011-04-01',
103 :dimensions => ['month', 'year'],
104 :metrics => ['visitors']
105 })
106
107 <hr />
108
109 Using Dimension & Metrics
110 =========================
111
112 Here are some additional examples that illustrate different things you can do with dimensions and metrics.
113
114
115 ### Sorting
116
117 # Sorting by number of visits in descending order (most visits at the top)
118 data = ga.get({
119 :start_date => '2011-01-01',
120 :end_date => '2011-04-01',
121 :dimensions => ['month', 'year'],
122 :metrics => ['visits']
123 :sort => ['-visits'],
124 })
125
126 ### Limiting results
127
128 # Limit the number of results to 25.
129 data = ga.get({
130 :start_date => '2011-01-01',
131 :end_date => '2011-04-01',
132 :dimensions => ['month', 'year'],
133 :metrics => ['visits']
134 :max_results => 25
135 })
136
137 ### Results as a Hash
138
139 my_hash = data.to_h['points']
140
141 # =>
142 # [{
143 # "xml" => "<entry gd:etag=\"W/&quot;.... </entry>",
144 # "id" => "http://www.google.com/analytics/feeds/data?...",
145 # "updated" => Thu, 31 Mar 2011 17:00:00 -0700,
146 # "title" => "ga:month=01 | ga:year=2011",
147 # "dimensions" => [{:month=>"01"}, {:year=>"2011"}],
148 # "metrics" => [{:visitors=>6}]
149 # },
150 # {
151 # "xml" => ...
152 # "id" => ...
153 # "updated" => ...
154 # ...
155 # }]
156
157
158 ### JSON formatted string
159
160 # Return data as a json string. (Useful for NoSQL databases)
161 my_json = data.to_h['points'].to_json
162
163 # =>
164 # "[{
165 # \"xml\":\"<entry> .... </entry>\",
166 # \"id\":\"http://www.google.com/analytics/feeds/data? ...",
167 # \"updated\":\"2011-03-31T17:00:00-07:00\",
168 # \"title\":\"ga:month=01 | ga:year=2011\",
169 # \"dimensions\":[{\"month\":\"01\"},{\"year\":\"2011\"}],
170 # \"metrics\":[{\"visitors\":6}]
171 # },
172 # {
173 # \"xml\":\"<entry> .... </entry>\",
174 # \"id\":\"http://www.google.com/analytics/feeds/data? ...",
175 # ...
176 # }]"
177
178 ### CSV formatted string
179
180 # Return the data in CSV format. (Useful for using in Excel.)
181
182 # Short CSV will only return your dimensions and metrics:
183 short_csv = data.to_csv(:short)
184
185 # => "month,year,visitors\n\n01,2011, ...."
186
187 # Long CSV will get you a few additional columns:
188 long_csv = data.to_csv
189
190 # => "id,updated,title,month,year,visitors\n\nhttp:// ..."
191
192
193 ### DIY formatting
194
195 # You can work directly with the 'point' method to return data.
196 data.points.each do |data_point|
197 month = data_point.dimensions.detect { |dim| dim.key == :month }.value
198 year = data_point.dimensions.detect { |dim| dim.key == :year }.value
199 visitors = data_point.metrics.detect { |metric| metric.key == :visitors }.value
200 puts "#{month}/#{year} got #{visitors} visitors"
201 end
202
203 # =>
204 # 01/2011 got 34552 visitors
205 # 02/2011 got 36732 visitors
206 # 03/2011 got 45642 visitors
207 # 04/2011 got 44456 visitors
208
209 <hr />
210
211 Using Filter, Goals, and Segments
212 =========================
213
214 Learn more about filters: [Google Data feed filtering reference](http://code.google.com/apis/analytics/docs/gdata/gdataReference.html#filtering)
215
216
217 ### Get profiles with goals
218
219 # Get all the profiles that have goals
220 profiles_with_goals = accounts.select { |account| account.goals.count > 0 }
221
222 # =>
223 # [{
224 # "id" => "http://www.google.com/analytics/feeds/accounts/ga:...",
225 # "updated" => Mon, 16 May 2011 16:40:30 -0700,
226 # "title" => "Profile Title",
227 # "table_id" => "ga:123456",
228 # "account_id" => 123456,
229 # "account_name" => "Account name",
230 # "profile_id" => 123456,
231 # "web_property_id" => "UA-123456-3",
232 # "goals"=>[{
233 # :active => "true",
234 # :name => "Goal name",
235 # :number => 1,
236 # :value => 0.0
237 # }]
238 # },
239 # {
240 # "id" => "http://www.google.com/analytics/feeds/accounts/ga:...",
241 # "updated" => Mon, 16 May 2011 16:40:30 -0700,
242 # "title" => "Profile Title",
243 # ...
244 # }]
245
246 ### List available segments
247
248 # Get all the segments that are available to you
249 segments = ga.segments
250
251 # Segments with negative gaid are default segments from Google. Segments
252 # with positive gaid numbers are custom segments that you created.
253 # =>
254 # [{
255 # "id" => "gaid::-1",
256 # "name" => "All Visits",
257 # "definition" => " "
258 # },
259 # {
260 # "id" => "gaid::-2",
261 # "name" => "New Visitors",
262 # "definition" => "ga:visitorType==New Visitor"
263 # },
264 # {
265 # "id" => ... # more default segments
266 # "name" => ...
267 # "definition" => ...
268 # },
269 # {
270 # "id" => "gaid::12345678",
271 # "name" => "Name of segment",
272 # "definition" => "ga:keyword=...."
273 # },
274 # {
275 # "id" => ... # more custom segments
276 # "name" => ...
277 # "definition" => ...
278 # }]
279
280 ### Query by segment
281
282 # Return visits and bounces for mobile traffic
283 # (Google's default user segment gaid::-11)
284
285 mobile_traffic = ga.get({
286 :start_date => '2011-01-01',
287 :end_date => '2011-02-01',
288 :dimensions => ['month', 'year'],
289 :metrics => ['visits', 'bounces'],
290 :segment => ['gaid::-11']
291 })
292
293 ### Filtering
294
295 Filters are boolean expressions in strings. Here's an example of an equality:
296
297 # Filter by Firefox users
298 firefox_users = ga.get({
299 :start_date => '2010-01-01',
300 :end_date => '2011-01-01',
301 :dimensions => ['month', 'year'],
302 :metrics => ['visits', 'bounces'],
303 :filters => ['browser == Firefox']
304 })
305
306 Here's an example of greater-than:
307
308 # Filter where visits is >= 10000
309 lots_of_visits = ga.get({
310 :start_date => '2010-01-01',
311 :end_date => '2011-02-01',
312 :dimensions => ['month', 'year'],
313 :metrics => ['visits', 'bounces'],
314 :filters => ['visits >= 10000']
315 })
316
317 Multiple filters is an array. Currently, they are only joined by 'AND'.
318
319 # Firefox users and visits >= 10000
320 firefox_users_with_many_pageviews = ga.get({
321 :start_date => '2010-01-01',
322 :end_date => '2011-02-01',
323 :dimensions => ['month', 'year'],
324 :metrics => ['visits', 'bounces'],
325 :filters => ['browser == Firefox', 'visits >= 10000']
326 })
327
328
329 <hr />
330
331 Even More Examples!
332 ===============
333
334 ### Top 25 keywords that drove traffic
335
336 Output the top 25 keywords that drove traffic to your website in the first quarter of 2011.
337
338 # Get the top 25 keywords that drove traffic
339 data = ga.get({
340 :start_date => '2011-01-01',
341 :end_date => '2011-04-01',
342 :dimensions => ['keyword'],
343 :metrics => ['visits'],
344 :sort => ['-visits'],
345 :max_results => 25
346 })
347
348 # Output our results
349 data.points.each do |data_point|
350 kw = data_point.dimensions.detect { |dim| dim.key == :keyword }.value
351 visits = data_point.metrics.detect { |metric| metric.key == :visits }.value
352 puts "#{visits} visits => '#{kw}'"
353 end
354
355 # =>
356 # 19667 visits => '(not set)'
357 # 1677 visits => 'keyword 1'
358 # 178 visits => 'keyword 2'
359 # 165 visits => 'keyword 3'
360 # 161 visits => 'keyword 4'
361 # 112 visits => 'keyword 5'
362 # 105 visits => 'seo company reviews'
363 # ...
364
365 <hr />
366
367 Additional Options & Settings
368 =============================
369
370 Setting HTTP timeout
371 --------------------
372
373 If you have a lot of profiles in your account (like 1000+ profiles) querying for accounts may take over a minute. Net::HTTP will timeout and an exception will be raised.
374
375 To avoid this, specify a timeout when you instantiate the Gattica object:
376
377 ga = Gattica.new({
378 :email => 'email@gmail.com',
379 :password => 'password',
380 :timeout => 600 # Set timeout for 10 minutes!
381 })
382
383 The default timeout is 300 seconds (5 minutes). Change the default in: lib/gattica/settings.rb
384
385 For reference 1000 profiles with 2-5 goals each takes around 90-120 seconds.
386
387 Reusing a session token
388 -----------------------
389
390 You can reuse an older session if you still have the token string. Google recommends doing this to avoid authenticating over and over.
391
392
393 my_token = ga.token # => 'DSasdf94...'
394
395 # Sometime later, you can initialize Gattica with the same token
396 ga = Gattica.new({ :token => my_token })
397
398 If your token times out, you will need to re-authenticate.
399
400 Specifying your own headers
401 ---------------------------
402
403 Google expects a special header in all HTTP requests called 'Authorization'. Gattica handles this header automatically. If you want to specify your own you can do that when you instantiate Gattica:
404
405 ga = Gattica.new({
406 :token => 'DSasdf94...',
407 :headers => {'My-Special-Header':'my_custom_value'}
408 })
409
410 <hr />
411
412 History
413 =======
414
415 Version history
416 ---------------
e6821a6f » Chris Le
2012-01-31 Update to v2.4 api
417 ### 0.6.0
418 * Update to use Google Analytics v2.4 management API
093380bf » Chris Le
2012-01-31 Update readme
419
420 TL;DR: Uses the v2.4 API now because Google deprecated <2.3.
421
422 * :) - Drop-in replacement for you.
423 * :) - Won't timeout anymore.
424 * :) - Accounts method might be faster if you have a few profiles
425 * :( - Accounts method is notably slower if you have >1000 profiles.
e6821a6f » Chris Le
2012-01-31 Update to v2.4 api
426
427 Google has changed the output of the API < 2.3. Most notable changes
428 were the output of what was the /management/accounts/default call. Some
429 of the XML changed, but most notably it didn't return everything all at
430 once. It used to look like this: http://bit.ly/w6Ummj
093380bf » Chris Le
2012-01-31 Update readme
431
e6821a6f » Chris Le
2012-01-31 Update to v2.4 api
432 * Fixed token [deviantech]
433
434 ### 0.5.1
435 * Added some tests - needs more work :(
436
437 ### 0.4.7
438 * Removed version numbers [john mcgrath]
439
440 ### 0.4.6
441 * Removed monkey patch [mathieuravaux]
442
b399e2e9 » Chris Le
2011-05-29 Completely rewrote README documentation.
443 ### 0.4.4
444 * Added a configuration file to unit tests
445 * Removed version.rb. Not needed. (thanks John McGrath see: github.com/john)
446 * Migrated examples and rewrote README file
447
448 ### 0.4.3
449 * FIXED: Typo in start-index parameter
450 * Refactored Engine class into it's own file.
451 * Began to re-style code to wrap at 80 characters
452 * Added some unit tests
453
454 ### 0.4.2
455 * Added Ruby 1.9 support (Thanks @mathieuravaux https://github.com/mathieuravaux)
456 * Uses hpricot 0.8.4 now. 0.8.3 segfaults.
457 * Added ability to change the timeout when requesting analytics from Google
458 * Added the ability to use max_results
459
460 ### 0.3.2.scottp
461 * scottp Added Analytics API v2 header, and basic support for "segment" argument.
462
463 ### 0.3.2
464 * er1c updated to use standard Ruby CSV library
465
466 ### 0.3.0
467 * Support for filters (filters are all AND'ed together, no OR yet)
468
469 ### 0.2.1
470 * More robust error checking on HTTP calls
471 * Added to_xml to get raw XML output from Google
472
473 ### 0.2.0 / 2009-04-27
474 * Changed initialization format: pass a hash of options rather than individual email, password and profile_id
475 * Can initialize with a valid token and use that instead of requiring email/password each time
476 * Can initialize with your own logger object instead of having to use the default (useful if you're using with Rails, initialize with RAILS_DEFAULT_LOGGER)
477 * Show error if token is invalid or expired (Google returns a 401 on any HTTP call)
478 * Started tests
479
480 ### 0.1.4 / 2009-04-22
481 * Another attempt at getting the gem to build on github
482
483 ### 0.1.3 / 2009-04-22
484 * Getting gem to build on github
485
486 ### 0.1.2 / 2009-04-22
487 * Updated readme and examples, better documentation throughout
488
489 ### 0.1.1 / 2009-04-22
490 * When outputting as CSV, surround each piece of data with double quotes (appears pretty common for various properties (like Browser name) to contain commas
491
492 ### 0.1.0 / 2009-03-26
493 * Basic functionality working good. Can't use filters yet.
494
495
496 Maintainer history
497 ------------------
498 * [Rob Cameron](https://github.com/activenetwork/gattica) (2010)
499 * [Mike Rumble](https://github.com/rumble/gattica) (2010)
500 * [Chris Le](https://github.com/chrisle/gattica) (Current)
19293241 » Chris Le
2012-01-24 updated readme to notify upcoming 3.0 api change
501
Something went wrong with that request. Please try again.