{"id":21558114,"url":"https://github.com/koopjs/koop-provider-google-analytics","last_synced_at":"2025-06-11T09:32:48.628Z","repository":{"id":56387654,"uuid":"147728376","full_name":"koopjs/koop-provider-google-analytics","owner":"koopjs","description":"Provider to connect to Google Analytics V4 API","archived":false,"fork":false,"pushed_at":"2022-12-09T21:55:47.000Z","size":357,"stargazers_count":2,"open_issues_count":2,"forks_count":0,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-05-26T11:06:37.715Z","etag":null,"topics":["koop-provider"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/koopjs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-09-06T20:16:27.000Z","updated_at":"2020-11-10T21:33:37.000Z","dependencies_parsed_at":"2023-01-25T23:45:58.374Z","dependency_job_id":null,"html_url":"https://github.com/koopjs/koop-provider-google-analytics","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koopjs%2Fkoop-provider-google-analytics","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koopjs%2Fkoop-provider-google-analytics/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koopjs%2Fkoop-provider-google-analytics/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koopjs%2Fkoop-provider-google-analytics/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/koopjs","download_url":"https://codeload.github.com/koopjs/koop-provider-google-analytics/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koopjs%2Fkoop-provider-google-analytics/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259239054,"owners_count":22826850,"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":["koop-provider"],"created_at":"2024-11-24T08:14:01.706Z","updated_at":"2025-06-11T09:32:48.604Z","avatar_url":"https://github.com/koopjs.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# koop-provider-google-analytics\n\n[Getting Started](#Getting-Started)  \n[Service endpoint pattern](#Service-endpoint-pattern)  \n[Sample requests](#Sample-requests)\n\n## Getting Started\n\n### Setup\n\nThis provider ships with a sample instance `server.js` which registers koop-provider-google-analytics. For the provider to work properly a few variables must be set for the environment or in a configuration file.\n\n#### Environment Variables \n|Variable|Description|Required|\n|---|---|---|\n| GOOGLE_VIEW_ID | The unique ID used to retrieve the Google Analytics data. Available through your Google Analytics dashboard. | Yes |\n| GOOGLE_ANALYTICS_TIMEZONE | String representing the timezone used to define the [Google Analytics view/report data](https://support.google.com/analytics/answer/1010249?hl=en). See [moment/timezone](https://momentjs.com/timezone/) for valid timezones. | Yes |\n| GOOGLE_CLIENT_EMAIL | The Google Analytics client email generated by Google for connecting to the API. | Yes |\n| GOOGLE_PRIVATE_KEY | The Google Analytics private key generated by Google for connecting their API. Must be base64 encoded (due to multiline key)| Yes |\n| GOOGLE_START_DATE |  Beginning of the time range used for analytics reports in `YYYY-MM-DD` format.  Defaults to 2005-01-01. | No |\n| ANALYTICS_CACHE_TTL | Number of seconds to cache analytics data until re-retrieved from Google Analytics.  If not set, there will be no caching. | No |\n\n#### Config file\nIf you prefer, you can set the required variables in the Koop configuration file rather than as environment variables.  See [config/default.js.example](config/default.js.example) for specifics.  The configuration file can also be use to customize the provider's support for additional Google Analytics dimensions and metrics. The [config/default.js.example](config/default.js.example) includes examples of adding dimensions and metrics not already defined in [src/constants-and-lookups.js](src/constants-and-lookups.js).  You will need to remove `.example` from the filename in order for the `config` npm to read and register this file.\n\n#### Backfill multi-dimesional time-series data\nThe Google Analytics API won't include empty rows when requesting multiple dimensions; if you want empty rows for a request with a time dimension plus at least one other dimension, set the `backfillTimeseries` configuration setting to `true`.\n\nWith the above environment variables and or config set, the Koop server can be started with:\n```\n  node server.js\n```\n\nThe Koop API will be listening on port 8080.\n\n## Service endpoint pattern\n\nThe service endpoint conforms to the following pattern:\n\n`http://\u003cdomain\u003e/google-analytics/:id/FeatureServer/0/query?\u003cquery-parameters\u003e`\n\n### `:id` parameter\nThe `:id` parameter is composite of three other parameters.  The requested `metric`, `dimensions`, and transformation `options` are delimited like: `\u003cmetric\u003e:\u003cdimensions\u003e~\u003coptions\u003e`. A single metric is required. Multiple dimensions or options can be delimited with `,`. You can skip using dimensions or options by leaving out the delimiters and values.  For example, to request a `metric` without `dimensions` but still add `options`, the `:id` parameter would look like `\u003cmetric\u003e~\u003coptions\u003e`. See each parameter below for details.\n\n#### `metric`\nThe `metric` parameter indicates the requested metric.  Only a single metric can be requested.  By default, the provider is configured to allow metrics in the following table.  Additional metrics can be added with the configuration file.\n\n|value|description|\n|---|---|\n|`views`|Number of page views|\n|`uniqueViews`|Number of unique page views|\n|`sessions`|Number of page views|\n|`totalEvents`|Number of total events|\n\n#### `dimensions`\nThe `dimensions` parameter indicates the requested dimension(s) for slicing the data.  Multiple dimensions can be requested by concatenating values with `,`, e.g `month,country`. Default dimension types are listed below. Additional dimensions can be added with the configuration file.\n\n|value|description|\n|---|---|\n|`hour`| Slice data by timestamp in hourly intervals |\n|`day`| Slice data by timestamp in daily intervals |\n|`week`| Slice data by timestamp in weekly intervals |\n|`month`| Slice data by timestamp in monthly intervals |\n|`country`| Slice data by country |\n|`eventCategory`| Slice data by eventCategory |\n|`eventAction`| Slice data by eventAction |\n|`eventLabel`| Slice data by eventAction |\n|`hostname`| Slice data by hostname |\n\n### Query parameters\nQuery parameters further refine the metrics request and are optional. Below are a list of the currently supported query parameters and their default values:\n\n|name|type|description|default|\n|---|---|---|---|\n|`time`|`string`|Comma separated date/date-time range for the requested metrics. Can be unix timestamp or `YYYY-MM-DD` strings, e.g. `2017-01-01,2018-01-01` or `1483257600,1514793600`. Use \"null\" to omit part of the range.| 2000-01-01  to current date |\n|`where`|`string`|A SQL style `WHERE` clause. [See notes below](#where-parameter-rules).||\n\n#### `where` parameter rules\nThis provider converts the SQL found in the `where` parameter to arrays of Google Analytics metric and dimension filter clauses. Unfortuntately, some `where`s will not be translatable to filter clauses due to Google Analytics business rules. The provider will give informative errors when a `where` cannot be translated, but general guidelines are provided below:  \n1) Predicates of a given type (metrics or dimensions) cannot be combined with more than one type of logical operator. For example, `view \u003e 100 OR uniqueViews \u003e 10 AND sessions \u003e 5` will not work.\n2) Logical combination of metric and dimension predicates must be with `AND`, e.g. `(sessions \u003e 100) AND (country = 'Canada')`.\n3) Currently supported operators for metric predicates include `=`, `\u003c`, `\u003e`. Combine predicates with `OR` to achieve `\u003c=` or `\u003e=`, e.g. `(sessions \u003e 100 OR sessions \u003e= 100)`.\n4) The only supported operator for dimension predicates is `=`.\n5) Complex `where`s that include multiple metric and dimension predicates should be partitioned by type (metric/dimension) with parenthesis, e.g `(sessions \u003e 100 OR sessions \u003e= 100) AND (country = 'Canada' OR country = 'Mexico')`.\n\n\n### Feature Service query parameters\nSince Koop employs the FeatureServer output service, you can use its subset of the ArcGIS REST API [parameters for feature service layers](https://developers.arcgis.com/rest/services-reference/query-feature-service-layer-.htm).\n\n## Sample requests\n1. [Monthly timeseries of page views for date range](#Monthly-timeseries-of-page-views-for-date-range)  \n1. [Sum of all page views for date range](#Sum-of-all-page-views-for-date-range)  \n1. [Average monthly page views for date range](#Average-monthly-page-views-for-date-range)  \n1. [Sum of total events dimensioned by event category for a date range](#Sum-of-total-events-dimensioned-by-event-category-for-a-date-range)  \n1. [Top ten session counts by country for a date range](#Top-ten-session-counts-by-country-for-a-date-range)\n1. [Multiple metrics, multiple dimensions](#Multiple-metrics,-multiple-dimensions)\n1. [Dimension by eventCategory and filter with where](#Dimension-by-eventCategory-and-filter-with-where)\n\n**NOTE:* All request require a `token` parameter or `authorization` header with a valid user token.\n\n### Monthly timeseries of page views for date range\n`http://localhost:8080/google-analytics/views:month/FeatureServer/0/query?time=2017-01-01,2018-07-01`\n\nResponse:\n\n```\n{\n    \"objectIdFieldName\": \"OBJECTID\",\n    \"globalIdFieldName\": \"\",\n    \"hasZ\": false,\n    \"hasM\": false,\n    \"spatialReference\": {\n        \"wkid\": 4326\n    },\n    \"fields\": [\n        {\n            \"name\": \"OBJECTID\",\n            \"type\": \"esriFieldTypeOID\",\n            \"alias\": \"OBJECTID\",\n            \"sqlType\": \"sqlTypeOther\",\n            \"domain\": null,\n            \"defaultValue\": null\n        },\n        {\n            \"name\": \"timestamp\",\n            \"type\": \"esriFieldTypeDate\",\n            \"alias\": \"timestamp\",\n            \"sqlType\": \"sqlTypeOther\",\n            \"domain\": null,\n            \"defaultValue\": null,\n            \"length\": 36\n        },\n        {\n            \"name\": \"views\",\n            \"type\": \"esriFieldTypeInteger\",\n            \"alias\": \"views\",\n            \"sqlType\": \"sqlTypeOther\",\n            \"domain\": null,\n            \"defaultValue\": null\n        }\n    ],\n    \"features\": [\n        {\n            \"attributes\": {\n                \"timestamp\": 1485907199999,\n                \"views\": 898118,\n                \"OBJECTID\": 1003353633\n            }\n        },\n        ...\n        ...\n        ...\n        {\n            \"attributes\": {\n                \"timestamp\": 1533081599999,\n                \"views\": 26983,\n                \"OBJECTID\": 1924415847\n            }\n        }\n    ],\n    \"exceededTransferLimit\": false\n}\n```\n\n### Sum of all page views for date range\n`http://localhost:8080/google-analytics/views/FeatureServer/0/query?time=2017-01-01,2018-07-01`\n\nResponse:\n```\n{\n    \"objectIdFieldName\": \"OBJECTID\",\n    \"globalIdFieldName\": \"\",\n    \"hasZ\": false,\n    \"hasM\": false,\n    \"spatialReference\": {\n        \"wkid\": 4326\n    },\n    \"fields\": [\n        {\n            \"name\": \"OBJECTID\",\n            \"type\": \"esriFieldTypeOID\",\n            \"alias\": \"OBJECTID\",\n            \"sqlType\": \"sqlTypeOther\",\n            \"domain\": null,\n            \"defaultValue\": null\n        },\n        {\n            \"name\": \"views\",\n            \"type\": \"esriFieldTypeInteger\",\n            \"alias\": \"views\",\n            \"sqlType\": \"sqlTypeOther\",\n            \"domain\": null,\n            \"defaultValue\": null\n        }\n    ],\n    \"features\": [\n        {\n            \"attributes\": {\n                \"views\": 28411690,\n                \"OBJECTID\": 952929127\n            }\n        }\n    ],\n    \"exceededTransferLimit\": false\n}\n```\n\n### Average monthly page views for date range\n`http://localhost:8080/google-analytics/views:month/FeatureServer/0/query?time=2017-01-01,2018-07-01\u0026outStatistics=[{\"statisticType\": \"avg\",\"onStatisticField\": \"views\",\"outStatisticFieldName\": \"average_monthly_views\"}]`\n\nResponse:\n\n```\n{\n    \"displayFieldName\": \"OBJECTID\",\n    \"fields\": [\n        {\n            \"name\": \"average_monthly_views\",\n            \"type\": \"esriFieldTypeDouble\",\n            \"alias\": \"average_monthly_views\",\n            \"sqlType\": \"sqlTypeOther\",\n            \"domain\": null,\n            \"defaultValue\": null\n        }\n    ],\n    \"features\": [\n        {\n            \"attributes\": {\n                \"average_monthly_views\": 1687865.6923076923\n            }\n        }\n    ]\n}\n```\n\n### Sum of total events dimensioned by event category for a date range\n`http://localhost:8080/google-analytics/totalEvents/eventCategory/FeatureServer/0/query?time=2017-01-01,2018-07-01`\n\n\nResponse:\n```json\n{\n    \"objectIdFieldName\": \"OBJECTID\",\n    \"globalIdFieldName\": \"\",\n    \"hasZ\": false,\n    \"hasM\": false,\n    \"spatialReference\": {\n        \"wkid\": 4326\n    },\n    \"fields\": [\n        {\n            \"name\": \"OBJECTID\",\n            \"type\": \"esriFieldTypeOID\",\n            \"alias\": \"OBJECTID\",\n            \"sqlType\": \"sqlTypeOther\",\n            \"domain\": null,\n            \"defaultValue\": null\n        },\n        {\n            \"name\": \"eventCategory\",\n            \"type\": \"esriFieldTypeString\",\n            \"alias\": \"eventCategory\",\n            \"sqlType\": \"sqlTypeOther\",\n            \"domain\": null,\n            \"defaultValue\": null,\n            \"length\": 128\n        },\n        {\n            \"name\": \"totalEvents\",\n            \"type\": \"esriFieldTypeInteger\",\n            \"alias\": \"totalEvents\",\n            \"sqlType\": \"sqlTypeOther\",\n            \"domain\": null,\n            \"defaultValue\": null\n        }\n    ],\n    \"features\": [\n        {\n            \"attributes\": {\n                \"eventCategory\": \"API\",\n                \"totalEvents\": 9503,\n                \"OBJECTID\": 2141521907\n            }\n        },\n        {\n            \"attributes\": {\n                \"eventCategory\": \"API Explorer\",\n                \"totalEvents\": 35130,\n                \"OBJECTID\": 339333549\n            }\n        },\n...\n...\n...\n        {\n            \"attributes\": {\n                \"eventCategory\": \"widgets\",\n                \"totalEvents\": 160570,\n                \"OBJECTID\": 1460530564\n            }\n        }\n    ],\n    \"exceededTransferLimit\": false\n}\n```\n\n### Top ten session counts by country for a date range\n`http://localhost:8080/google-analytics/sessions/country/FeatureServer/0/query?time=2017-01-01,2018-07-01\u0026orderByFields=sessions%20DESC\u0026limit=10`\n\nResponse:\n```json\n{\n    \"objectIdFieldName\": \"OBJECTID\",\n    \"globalIdFieldName\": \"\",\n    \"hasZ\": false,\n    \"hasM\": false,\n    \"spatialReference\": {\n        \"wkid\": 4326\n    },\n    \"fields\": [\n        {\n            \"name\": \"OBJECTID\",\n            \"type\": \"esriFieldTypeOID\",\n            \"alias\": \"OBJECTID\",\n            \"sqlType\": \"sqlTypeOther\",\n            \"domain\": null,\n            \"defaultValue\": null\n        },\n        {\n            \"name\": \"country\",\n            \"type\": \"esriFieldTypeString\",\n            \"alias\": \"country\",\n            \"sqlType\": \"sqlTypeOther\",\n            \"domain\": null,\n            \"defaultValue\": null,\n            \"length\": 128\n        },\n        {\n            \"name\": \"sessions\",\n            \"type\": \"esriFieldTypeInteger\",\n            \"alias\": \"sessions\",\n            \"sqlType\": \"sqlTypeOther\",\n            \"domain\": null,\n            \"defaultValue\": null\n        }\n    ],\n    \"features\": [\n        {\n            \"attributes\": {\n                \"country\": \"United States\",\n                \"sessions\": 3465985,\n                \"OBJECTID\": 2115310799\n            }\n        },\n        {\n            \"attributes\": {\n                \"country\": \"Canada\",\n                \"sessions\": 344534,\n                \"OBJECTID\": 1164473059\n            }\n        },\n        {\n            \"attributes\": {\n                \"country\": \"United Kingdom\",\n                \"sessions\": 259762,\n                \"OBJECTID\": 1199712002\n            }\n        },\n        {\n            \"attributes\": {\n                \"country\": \"Colombia\",\n                \"sessions\": 164969,\n                \"OBJECTID\": 463997413\n            }\n        },\n        {\n            \"attributes\": {\n                \"country\": \"Japan\",\n                \"sessions\": 111078,\n                \"OBJECTID\": 660706644\n            }\n        },\n        {\n            \"attributes\": {\n                \"country\": \"Brazil\",\n                \"sessions\": 104631,\n                \"OBJECTID\": 1916301181\n            }\n        },\n        {\n            \"attributes\": {\n                \"country\": \"Australia\",\n                \"sessions\": 100033,\n                \"OBJECTID\": 200827751\n            }\n        },\n        {\n            \"attributes\": {\n                \"country\": \"New Zealand\",\n                \"sessions\": 70347,\n                \"OBJECTID\": 266670080\n            }\n        },\n        {\n            \"attributes\": {\n                \"country\": \"Spain\",\n                \"sessions\": 52992,\n                \"OBJECTID\": 1375456220\n            }\n        },\n        {\n            \"attributes\": {\n                \"country\": \"France\",\n                \"sessions\": 50162,\n                \"OBJECTID\": 1909896837\n            }\n        }\n    ],\n    \"exceededTransferLimit\": false\n}\n```\n\n### Multiple metrics, multiple dimensions\n`http://localhost:8080/google-analytics/sessions::views/country::eventCategory/FeatureServer/0/query?time=2017-01-01,2018-07-01`\n\n```json\n{\n    \"objectIdFieldName\": \"OBJECTID\",\n    \"globalIdFieldName\": \"\",\n    \"hasZ\": false,\n    \"hasM\": false,\n    \"spatialReference\": {\n        \"wkid\": 4326\n    },\n    \"fields\": [\n        {\n            \"name\": \"OBJECTID\",\n            \"type\": \"esriFieldTypeOID\",\n            \"alias\": \"OBJECTID\",\n            \"sqlType\": \"sqlTypeOther\",\n            \"domain\": null,\n            \"defaultValue\": null\n        },\n        {\n            \"name\": \"country\",\n            \"type\": \"esriFieldTypeString\",\n            \"alias\": \"country\",\n            \"sqlType\": \"sqlTypeOther\",\n            \"domain\": null,\n            \"defaultValue\": null,\n            \"length\": 128\n        },\n        {\n            \"name\": \"eventCategory\",\n            \"type\": \"esriFieldTypeString\",\n            \"alias\": \"eventCategory\",\n            \"sqlType\": \"sqlTypeOther\",\n            \"domain\": null,\n            \"defaultValue\": null,\n            \"length\": 128\n        },\n        {\n            \"name\": \"sessions\",\n            \"type\": \"esriFieldTypeInteger\",\n            \"alias\": \"sessions\",\n            \"sqlType\": \"sqlTypeOther\",\n            \"domain\": null,\n            \"defaultValue\": null\n        },\n        {\n            \"name\": \"views\",\n            \"type\": \"esriFieldTypeInteger\",\n            \"alias\": \"views\",\n            \"sqlType\": \"sqlTypeOther\",\n            \"domain\": null,\n            \"defaultValue\": null\n        }\n    ],\n    \"features\": [\n        {\n            \"attributes\": {\n                \"country\": \"Australia\",\n                \"eventCategory\": \"dataset\",\n                \"sessions\": 3,\n                \"views\": 7,\n                \"OBJECTID\": 1105561907\n            }\n        },\n        ...\n        ...\n        ...\n        {\n            \"attributes\": {\n                \"country\": \"United States\",\n                \"eventCategory\": \"Search\",\n                \"sessions\": 716,\n                \"views\": 10475,\n                \"OBJECTID\": 2012216286\n            }\n        }\n    ],\n    \"exceededTransferLimit\": false\n}\n```\n\n### Dimension by eventCategory and filter with where\n`http://localhost:8080/google-analytics/sessions::views/eventCategory/FeatureServer/0/query?where=(country='United States') AND views \u003e 999`\n\n```json\n{\n    \"objectIdFieldName\": \"OBJECTID\",\n    \"globalIdFieldName\": \"\",\n    \"hasZ\": false,\n    \"hasM\": false,\n    \"spatialReference\": {\n        \"wkid\": 4326\n    },\n    \"fields\": [\n        {\n            \"name\": \"views\",\n            \"type\": \"esriFieldTypeInteger\",\n            \"alias\": \"views\",\n            \"sqlType\": \"sqlTypeOther\",\n            \"domain\": null,\n            \"defaultValue\": null\n        },\n        {\n            \"name\": \"eventCategory\",\n            \"type\": \"esriFieldTypeString\",\n            \"alias\": \"eventCategory\",\n            \"sqlType\": \"sqlTypeOther\",\n            \"domain\": null,\n            \"defaultValue\": null,\n            \"length\": 128\n        },\n        {\n            \"name\": \"sessions\",\n            \"type\": \"esriFieldTypeInteger\",\n            \"alias\": \"sessions\",\n            \"sqlType\": \"sqlTypeOther\",\n            \"domain\": null,\n            \"defaultValue\": null\n        }\n    ],\n    \"features\": [\n        {\n            \"attributes\": {\n                \"sessions\": 80831,\n                \"views\": 157629,\n                \"eventCategory\": \"ArcGIS\"\n            }\n        },\n        ...\n        ...\n        {\n            \"attributes\": {\n                \"sessions\": 813,\n                \"views\": 18397,\n                \"eventCategory\": \"Search\"\n            }\n        }\n    ],\n    \"exceededTransferLimit\": false\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkoopjs%2Fkoop-provider-google-analytics","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkoopjs%2Fkoop-provider-google-analytics","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkoopjs%2Fkoop-provider-google-analytics/lists"}