Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 507 lines (380 sloc) 15.445 kb
b399e2e Completely rewrote README documentation.
Chris Le authored
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 ---------------
16ccd26 Update readme
Chris Le authored
417 ### 0.6.1
418 * Incorporated fixes by vgololobov
419 * Removed circular dependency
420 * Fixed 1.9.3 init exception https://github.com/chrisle/gattica/pull/6
421
e6821a6 Update to v2.4 api
Chris Le authored
422 ### 0.6.0
423 * Update to use Google Analytics v2.4 management API
093380b Update readme
Chris Le authored
424
425 TL;DR: Uses the v2.4 API now because Google deprecated <2.3.
426
427 * :) - Drop-in replacement for you.
428 * :) - Won't timeout anymore.
429 * :) - Accounts method might be faster if you have a few profiles
430 * :( - Accounts method is notably slower if you have >1000 profiles.
e6821a6 Update to v2.4 api
Chris Le authored
431
432 Google has changed the output of the API < 2.3. Most notable changes
433 were the output of what was the /management/accounts/default call. Some
434 of the XML changed, but most notably it didn't return everything all at
435 once. It used to look like this: http://bit.ly/w6Ummj
093380b Update readme
Chris Le authored
436
e6821a6 Update to v2.4 api
Chris Le authored
437 * Fixed token [deviantech]
438
439 ### 0.5.1
440 * Added some tests - needs more work :(
441
442 ### 0.4.7
443 * Removed version numbers [john mcgrath]
444
445 ### 0.4.6
446 * Removed monkey patch [mathieuravaux]
447
b399e2e Completely rewrote README documentation.
Chris Le authored
448 ### 0.4.4
449 * Added a configuration file to unit tests
450 * Removed version.rb. Not needed. (thanks John McGrath see: github.com/john)
451 * Migrated examples and rewrote README file
452
453 ### 0.4.3
454 * FIXED: Typo in start-index parameter
455 * Refactored Engine class into it's own file.
456 * Began to re-style code to wrap at 80 characters
457 * Added some unit tests
458
459 ### 0.4.2
460 * Added Ruby 1.9 support (Thanks @mathieuravaux https://github.com/mathieuravaux)
461 * Uses hpricot 0.8.4 now. 0.8.3 segfaults.
462 * Added ability to change the timeout when requesting analytics from Google
463 * Added the ability to use max_results
464
465 ### 0.3.2.scottp
466 * scottp Added Analytics API v2 header, and basic support for "segment" argument.
467
468 ### 0.3.2
469 * er1c updated to use standard Ruby CSV library
470
471 ### 0.3.0
472 * Support for filters (filters are all AND'ed together, no OR yet)
473
474 ### 0.2.1
475 * More robust error checking on HTTP calls
476 * Added to_xml to get raw XML output from Google
477
478 ### 0.2.0 / 2009-04-27
479 * Changed initialization format: pass a hash of options rather than individual email, password and profile_id
480 * Can initialize with a valid token and use that instead of requiring email/password each time
481 * 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)
482 * Show error if token is invalid or expired (Google returns a 401 on any HTTP call)
483 * Started tests
484
485 ### 0.1.4 / 2009-04-22
486 * Another attempt at getting the gem to build on github
487
488 ### 0.1.3 / 2009-04-22
489 * Getting gem to build on github
490
491 ### 0.1.2 / 2009-04-22
492 * Updated readme and examples, better documentation throughout
493
494 ### 0.1.1 / 2009-04-22
495 * When outputting as CSV, surround each piece of data with double quotes (appears pretty common for various properties (like Browser name) to contain commas
496
497 ### 0.1.0 / 2009-03-26
498 * Basic functionality working good. Can't use filters yet.
499
500
501 Maintainer history
502 ------------------
503 * [Rob Cameron](https://github.com/activenetwork/gattica) (2010)
504 * [Mike Rumble](https://github.com/rumble/gattica) (2010)
505 * [Chris Le](https://github.com/chrisle/gattica) (Current)
1929324 updated readme to notify upcoming 3.0 api change
Chris Le authored
506
Something went wrong with that request. Please try again.