{"id":13463494,"url":"https://github.com/tpitale/legato","last_synced_at":"2025-10-24T20:39:20.318Z","repository":{"id":2020671,"uuid":"2956613","full_name":"tpitale/legato","owner":"tpitale","description":"Google Analytics Reporting API Client for Ruby","archived":false,"fork":false,"pushed_at":"2023-05-10T02:42:16.000Z","size":288,"stargazers_count":400,"open_issues_count":11,"forks_count":47,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-03-31T21:46:00.378Z","etag":null,"topics":["analytics","google-analytics","ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tpitale.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2011-12-11T03:37:26.000Z","updated_at":"2025-03-31T17:38:29.000Z","dependencies_parsed_at":"2023-02-13T17:35:46.870Z","dependency_job_id":"f08e2845-37e5-4115-a8dd-42d0401c1e73","html_url":"https://github.com/tpitale/legato","commit_stats":{"total_commits":170,"total_committers":24,"mean_commits":7.083333333333333,"dds":"0.44705882352941173","last_synced_commit":"7576de49b1f2c69544cb9d6743cc9e9abce90daf"},"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tpitale%2Flegato","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tpitale%2Flegato/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tpitale%2Flegato/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tpitale%2Flegato/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tpitale","download_url":"https://codeload.github.com/tpitale/legato/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247737788,"owners_count":20987721,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["analytics","google-analytics","ruby"],"created_at":"2024-07-31T13:00:54.390Z","updated_at":"2025-10-24T20:39:15.272Z","avatar_url":"https://github.com/tpitale.png","language":"Ruby","readme":"# Legato: Ruby Client for the Google Analytics Core Reporting and Management API #\n\n[![Gem Version](https://badge.fury.io/rb/legato.png)](http://badge.fury.io/rb/legato)\n[![Build Status](https://travis-ci.org/tpitale/legato.png)](https://travis-ci.org/tpitale/legato)\n[![Code Climate](https://codeclimate.com/github/tpitale/legato.png)](https://codeclimate.com/github/tpitale/legato)\n\n## [Check out the Wiki!](https://github.com/tpitale/legato/wiki) ##\n\n**Feel free to open an issue if you have a question that is not answered in the [Wiki](https://github.com/tpitale/legato/wiki)**\n\nIf you've come here from Garb, welcome! There are a few changes from Garb, so you'll want to check out:\n\n* [Model Data](https://github.com/tpitale/legato/wiki/Model-Data)\n* [Query Parameters](https://github.com/tpitale/legato/wiki/Query-Parameters)\n* And the biggest difference: [Filtering](https://github.com/tpitale/legato/wiki/Filtering)\n\nIf you're not able to upgrade quite yet, Garb has been maintained https://github.com/Sija/garb\n\n## Google Analytics Management ##\n\n1. Get an OAuth2 Access Token from Google, Read about [OAuth2](https://github.com/tpitale/legato/wiki/OAuth2-and-Google)\n\n    ```ruby\n    access_token = OAuth2 Access Token # from Google\n    ```\n\n2. Create a New User with the Access Token\n\n    ```ruby\n    user = Legato::User.new(access_token)\n    ```\n\n3. List the Accounts and Profiles of the first Account\n\n    ```ruby\n    user.accounts\n    user.accounts.first.profiles\n    ```\n\n4. List all the Profiles the User has Access to\n\n    ```ruby\n    user.profiles\n    ```\n\n5. Get a Profile\n\n    ```ruby\n    profile = user.profiles.first\n    ```\n\n6. The Profile Carries the User\n\n    ```ruby\n    profile.user == user #=\u003e true\n    ```\n\n7. The profile can also lookup its \"parent\" Web Property\n\n    ```ruby\n    profile.web_property\n    ```\n\n## Google Analytics Model ##\n\n```ruby\nclass Exit\n  extend Legato::Model\n\n  metrics :exits, :pageviews\n  dimensions :page_path, :operating_system, :browser\nend\n\nprofile.exit #=\u003e returns a Legato::Query\nprofile.exit.each {} #=\u003e any enumerable kicks off the request to GA\n```\n\n## Metrics \u0026 Dimensions ##\n\nhttp://code.google.com/apis/analytics/docs/gdata/dimsmets/dimsmets.html\n\n```ruby\nmetrics :exits, :pageviews\ndimensions :page_path, :operating_system, :browser\n```\n\n## Filtering ##\n\nCreate named filters to wrap query filters.\n\nHere's what google has to say: http://code.google.com/apis/analytics/docs/gdata/v3/reference.html#filters\n\n### Examples ###\n\nInside of any `Legato::Model` class, the method `filter` is available (like `metrics` and `dimensions`).\n\nReturn entries with exits counts greater than or equal to 2000\n\n```ruby\nfilter(:high_exits) {gte(:exits, 2000)}\n\n# or ...\n\nfilter :high_exits, \u0026lambda {gte(:exits, 2000)}\n```\n\nReturn entries with pageview metric less than or equal to 200\n\n```ruby\nfilter(:low_pageviews) {lte(:pageviews, 200)}\n```\n\nFilters with dimensions\n\n```ruby\nfilter(:for_browser) {|browser| matches(:browser, browser)}\n```\n\nFilters with OR\n\n```ruby\nfilter(:browsers) {|*browsers| browsers.map {|browser| matches(:browser, browser)}}\n```\n\n\n## Using and Chaining Filters ##\n\nPass the profile as the first or last parameter into any filter.\n\n```ruby\nExit.for_browser(\"Safari\", profile)\n```\n\nChain two filters.\n\n```ruby\nExit.high_exits.low_pageviews(profile)\n```\n\nProfile gets a method for each class extended by Legato::Model\n\n```ruby\nExit.results(profile) == profile.exit\n```\n\nWe can chain off of that method, too.\n\n```ruby\nprofile.exit.high_exits.low_pageviews.by_pageviews\n```\n\nChaining order doesn't matter. Profile can be given to any filter.\n\n```ruby\nExit.high_exits(profile).low_pageviews == Exit.low_pageviews(profile).high_exits\n```\n\nBe sure to pass the appropriate number of arguments matching the lambda for your filter.\n\nFor a filter defined like this:\n\n```ruby\nfilter(:browsers) {|*browsers| browsers.map {|browser| matches(:browser, browser)}}\n```\n\nWe can use it like this, passing any number of arguments:\n\n```ruby\nExit.browsers(\"Firefox\", \"Safari\", profile)\n```\n\n## Google Analytics Supported Filtering Methods ##\n\nGoogle Analytics supports a significant number of filtering options.\n\nHere is what we can do currently:\n(the operator is a method available in filters for the appropriate metric or dimension)\n\nOperators on metrics (method =\u003e GA equivalent):\n\n    eql     =\u003e '==',\n    not_eql =\u003e '!=',\n    gt      =\u003e '\u003e',\n    gte     =\u003e '\u003e=',\n    lt      =\u003e '\u003c',\n    lte     =\u003e '\u003c='\n\nOperators on dimensions:\n\n    matches          =\u003e '==',\n    does_not_match   =\u003e '!=',\n    contains         =\u003e '=~',\n    does_not_contain =\u003e '!~',\n    substring        =\u003e '=@',\n    not_substring    =\u003e '!@'\n\n## Session-level Segments\n\nYour query can have a session-level segment, which works with filter expressions. It\nworks like an [advanced\nsegment](https://support.google.com/analytics/answer/1033017?hl=en), except you\ndon't have to create it beforehand, you can just specify it at query time.\n\nSome of the numbers you'll get will be different from using a filter, since\n[the subset of visits matched happens before dimensions and metrics are\ncalculated](http://ga-dev-tools.appspot.com/explorer/) (hover on the `segment`\nparameter to see).\n\nSome metrics and dimensions are not allowed for segments, see the [API\ndocumentation](https://developers.google.com/analytics/devguides/reporting/core/v3/reference#segment)\nfor more details.\n\n**Note**: Legato does _not_ support [Users vs Sessions](https://developers.google.com/analytics/devguides/reporting/core/v3/segments#users-vs-sessions), yet. The default will be sessions (the equivalent of the earlier, now removed, dynamic segments).\n\n### Defining, using and chaining segments\n\nReturn entries with exits counts greater than or equal to 2000\n\n```ruby\nsegment :high_exits do\n  gte(:exits, 2000)\nend\n```\n\nReturn entries with pageview metric less than or equal to 200\n\n```ruby\nsegment :low_pageviews do\n  lte(:pageviews, 200)\nend\n```\n\nYou can chain them\n\n```ruby\nExit.high_exits.low_pageviews(profile)\n```\n\nand call them directly on the profile\n\n```ruby\nprofile.exit.high_exits.low_pageviews\n```\n## Accounts, WebProperties, Profiles, and Goals ##\n\n```ruby\nLegato::Management::Account.all(user)\nLegato::Management::WebProperty.all(user)\nLegato::Management::Profile.all(user)\nLegato::Management::Goal.all(user)\n```\n## Other Parameters Can be Passed to a call to #results ##\n\n  * :start_date - The date of the period you would like this report to start\n  * :end_date - The date to end, inclusive\n  * :limit - The maximum number of results to be returned\n  * :offset - The starting index\n  * :sort - metric/dimension to sort by\n  * :quota_user - any arbitrary string that uniquely identifies a user (40 characters max)\n  * :sampling_level - 'FASTER' or 'HIGHER_PRECISION' https://developers.google.com/analytics/devguides/reporting/core/v3/reference#samplingLevel\n  * :segment_id - this will supersede any segments chained to the query\n\n## Real Time Reporting ##\n\nhttps://developers.google.com/analytics/devguides/reporting/realtime/v3/\nhttps://developers.google.com/analytics/devguides/reporting/realtime/dimsmets/\n\nGA provides an endpoint to do **basic** reporting in near-realtime. Please read the above documentation to know which features (and dimentsion/metrics) are or are _not_ available. It is also only available in **beta** so you must already have access.\n\nInside of Legato, you can simply add `realtime` to your query (`#results` returns a `Query` instance), like this:\n\n```ruby\nExit.results(profile).realtime\n```\nThe results you iterate over (with `.each`, etc) will be from the realtime reporting API.\n\nYou can also call `realtime` on your model to get a new `Query` instance with realtime API set.\n\n```ruby\nquery = Exit.realtime\nquery.realtime? #=\u003e true\nquery.tracking_scope #=\u003e 'rt'\n```\n\n## Managing Quotas ##\n\nAssigning a `quota_user` or `user_ip` on a user instance will be used by management and query requests.\n\n```ruby\nuser = Legato::User.new(access_token)\nuser.quota_user = 'some_unique_user_identifier'\n# OR\nuser.user_ip = ip_address_from_a_web_user_or_something\n```\n","funding_links":[],"categories":["Web Apps, Services \u0026 Interaction","Analytics"],"sub_categories":["Web Analytics"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftpitale%2Flegato","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftpitale%2Flegato","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftpitale%2Flegato/lists"}