-
-
Save ezioruan/4337b7f0b10aef31060a987cbb4cbfaf to your computer and use it in GitHub Desktop.
example Go code showing how to download reporting data from Google Analytics using the Core Reporting API, a Google service account + oauth2 (UPDATE: go here http://code.rickt.org/post/142445693275/updated-golang-code-to-query-ga-data-via-the instead)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// NOTE: go here for an update http://code.rickt.org/post/142445693275/updated-golang-code-to-query-ga-data-via-the | |
// this gist still works but has a lot of extra fluff you don't need | |
// http://code.rickt.org/post/142445693275/updated-golang-code-to-query-ga-data-via-the is what you really want | |
// | |
package main | |
import ( | |
"flag" | |
"fmt" | |
"golang.org/x/oauth2" | |
"golang.org/x/oauth2/jwt" | |
"google.golang.org/api/analytics/v3" | |
"io/ioutil" | |
"log" | |
"os" | |
"time" | |
) | |
// constants | |
const ( | |
dateLayout string = "2006-01-02" // date format that Core Reporting API requires | |
) | |
// example secretsfile (obtained from the Google Cloud Console specific to your app) | |
// { | |
// "web": { | |
// "auth_uri": "https://accounts.google.com/o/oauth2/auth", | |
// "token_uri": "https://accounts.google.com/o/oauth2/token", | |
// "client_email": "blahblahblahblah@developer.gserviceaccount.com", | |
// "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/blahblahblahblah@developer.gserviceaccount.com", | |
// "client_id": "blahblahblahblah.apps.googleusercontent.com", | |
// "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs" | |
// } | |
// } | |
// your globals (change these using values from the JSON secretsfile obtained from the Google Cloud Console specific to your app) | |
var ( | |
gaServiceAcctEmail string = "blahblahblahblah@developer.gserviceaccount.com" // email address of registered app in Google Cloud Console | |
gaServiceAcctPEMKey string = "/path/to/your/analyticsdumper.pem" // private key (PEM format) of registered application | |
gaScope string = "https://www.googleapis.com/auth/analytics.readonly" // scope information for Core Reporting API | |
gaTableID string = "ga:XXXXXXXX" // namespaced profile (table) ID of your analytics account/property/profile | |
gaTokenURL string = "https://accounts.google.com/o/oauth2/token" // token auth URL | |
) | |
// analytics-dumper globals | |
var ( | |
// vars used for the runtime flags | |
gaDimensions string // which dimensions? | |
gaEndDate string // what's the end date of our query? | |
gaFilter string // what's our filter (if any)? | |
gaMetrics string // which metrics? | |
gaMaxResults int64 // how many max results do we want returned? | |
gaSortOrder string // what's the sort order? | |
help bool // do we want help? | |
gaStartDate string // what's the start date of our query? | |
) | |
// func: init() | |
// initialisation function for the command line flags/options. | |
func init() { | |
flag.BoolVar(&help, "h", false, "show all command line arguments.") | |
flag.StringVar(&gaDimensions, "d", "", "GA query dimensions") | |
flag.StringVar(&gaEndDate, "ed", "", "GA query end date") | |
flag.StringVar(&gaFilter, "f", "", "GA query filter") | |
flag.Int64Var(&gaMaxResults, "x", 10000, "GA maximum # of results to return (default: 10000)") | |
flag.StringVar(&gaMetrics, "m", "ga:pageviews", "GA metrics you want to query (default: ga:pageviews)") | |
flag.StringVar(&gaSortOrder, "s", "", "GA query reply sort order") | |
flag.StringVar(&gaStartDate, "sd", "2013-10-01", "GA query start date (default: 2013-10-01)") | |
} | |
// func: main() | |
// the main function. | |
func main() { | |
// grok the command line args | |
flag.Usage = usage | |
flag.Parse() | |
if help { | |
flag.Usage() | |
} | |
// load up the registered applications private PEM key. | |
pk, err := ioutil.ReadFile(gaServiceAcctPEMKey) | |
if err != nil { | |
log.Fatal("error reading GA Service Account PEM key -", err) | |
} | |
// create a jwt.Config that we will subsequently use for our authenticated client/transport | |
jwtc := jwt.Config{ | |
Email: gaServiceAcctEmail, | |
PrivateKey: pk, | |
Scopes: []string{gaScope}, | |
TokenURL: gaTokenURL, | |
} | |
// create our authenticated client/transport using the jwt.Config we just created | |
client := jwtc.Client(oauth2.NoContext) | |
// create a new analytics service by passing in the authenticated http client | |
analyticsService, err := analytics.New(client) | |
if err != nil { | |
log.Fatal("error creating Analytics Service -", err) | |
} | |
// create a new analytics data service by passing in the analytics service we just created | |
dataGaService := analytics.NewDataGaService(analyticsService) | |
// w00t! now we're talking to the core reporting API. the hard stuff is over, lets setup a simple query. | |
var dimensions, filter, sortorder string | |
// if no gaEndDate specified via command line args, set it to today's date. | |
if gaEndDate == "" { | |
t := time.Now() | |
gaEndDate = t.Format(dateLayout) | |
} | |
// setup the query, call the Analytics API via our analytics data service's Get func with the table ID, dates & metric variables | |
dataGaGetCall := dataGaService.Get(gaTableID, gaStartDate, gaEndDate, gaMetrics) | |
// now we can build the analytics query! | |
// setup the dimensions (if none specified at runtime) | |
if gaDimensions != "" { | |
dimensions = fmt.Sprintf("ga:dimensions=%s", gaDimensions) | |
dataGaGetCall.Dimensions(dimensions) | |
} | |
// setup the sort order (if none specified at runtime) | |
if gaSortOrder != "" { | |
sortorder = fmt.Sprintf("ga:sort=%s", gaSortOrder) | |
dataGaGetCall.Sort(sortorder) | |
} | |
// setup the filter (if none specified at runtime) | |
if gaFilter != "" { | |
filter = fmt.Sprintf("%s", gaFilter) | |
dataGaGetCall.Filters(filter) | |
} | |
// setup the max results we want returned. | |
dataGaGetCall.MaxResults(gaMaxResults) | |
// send the query to the API, get a big fat gaData back. | |
gaData, err := dataGaGetCall.Do() | |
if err != nil { | |
log.Fatal("API error -", err) | |
} | |
// we've made it this far, so lets print info about the query | |
fmt.Printf("gaStartDate=%s, gaEndDate=%s\n", gaStartDate, gaEndDate) | |
fmt.Printf("gaDimensions=%s\n", dimensions) | |
fmt.Printf("gaFilter=%s\n", filter) | |
fmt.Printf("gaMetrics=%s\n", gaMetrics) | |
fmt.Printf("gaSortOrder=%s\n", sortorder) | |
// how much data did we get back? | |
fmt.Printf("len(gaData.Rows)=%d, TotalResults=%d\n", len(gaData.Rows), gaData.TotalResults) | |
// lets print out the returned data via a lazy loop through the returned rows | |
for row := 0; row <= len(gaData.Rows)-1; row++ { | |
fmt.Printf("row=%d %v\n", row, gaData.Rows[row]) | |
} | |
} | |
// func: usage() | |
// prints out all possible flags/options when "-h" or an unknown option is used at runtime. | |
// exits back to shell when complete. | |
func usage() { | |
fmt.Printf("usage: %s [OPTION] \n", os.Args[0]) | |
flag.PrintDefaults() | |
os.Exit(2) | |
} | |
// example run of analyticsdumper below | |
// note: shows all pageviews for this particular property from 2013-10-01 until date of run | |
// $ ./analyticsdumper | |
// gaStartDate=2013-10-01, gaEndDate=2016-04-07 | |
// gaDimensions= | |
// gaFilter= | |
// gaMetrics=ga:pageviews | |
// gaSortOrder= | |
// len(gaData.Rows)=1, TotalResults=1 | |
// row=0 [646765827] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment