# Authentication of googleAnalyticsR with gcloud user on Jupyter¶

Thanks to a tweet from Lak, he highlighted another way to authenticate purely online when using notebooks e.g. not uploading a token from an offline R session.

Lak documents this in this helpful blogpost

It involves using the Terminal to get user access from the authentication within GCP.

1. Create an `OAuth2 client ID (Other)` for the project running the notebook at this link https://console.cloud.google.com/apis/credentials
2. Save the clientId JSON and upload to the Jupyter base directory (here assumed you name it `jupyter_client_id.json`)
3. Make sure the APIs you want to authentication with are activated for that project e.g. Google Analytics Reporting API
4. Make a Terminal in Jupyter via `File > New > Terminal` and issue the below commands to login via the browser, and print the access token (hint: you can press SHIFT and right click in terminal to copy/paste if CTRL+C and CTRL+V

    # https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login
    gcloud auth application-default login \
        --client-id-file jupyter_client_id.json \
        --scopes=https://www.googleapis.com/auth/analytics.readonly,https://www.googleapis.com/auth/analytics

    ## access the URL, login and create a verification code, paste in console.

    ## view then copy-paste the access token, to be passed into the R function
    gcloud auth application-default print-access-token

1. Use the following function to take the access token. This will be in `googleAuthR` version > 0.7.9000

In [1]:

    gar_gce_auth_default <- function(access_token,
                                     scopes,
                                     cache_file = "gcloud.auth"){

      json_creds <- jsonlite::fromJSON('~/.config/gcloud/application_default_credentials.json')

      token_formatted <-
        httr::Token2.0$new(app = httr::oauth_app("google",
                                     key = json_creds$client_id,
                                     secret = json_creds$client_secret),
                           endpoint = httr::oauth_endpoints("google"),
                           credentials = list(access_token = access_token,
                                              token_type = json_creds$type,
                                              expires_in = NULL,
                                              refresh_token = NULL),
                           params = list(scope = scopes, type = NULL,
                                         use_oob = FALSE, as_header = TRUE),
                           cache_path = FALSE)

      options("googleAuthR.client_id" = json_creds$client_id,
              "googleAuthR.client_secret" = json_creds$client_secret,
              "googleAuthR.scopes.selected" = scopes)
      saveRDS(token_formatted, cache_file)

      message("Authenticated. Token saved to ", cache_file)

      token_formatted

    }

An example token copy-pasted from the terminal is below. Pass that and the scopes for the API into the function above to create the token

In [2]:

    at='ya29.XXXXXOgi2Zyl0PYU-mwZseSWXXXXXiQqxwCCalVMgRMcoXRn5fF2PH_Rz4fltI16O10zgh-RVN'
    scopes = c('https://www.googleapis.com/auth/analytics.edit,https://www.googleapis.com/auth/analytics')
    token <- gar_gce_auth_default(at, scopes = scopes)

    Authenticated. Token saved to gcloud.auth

Once the token is available, you can use pass it in directly in the `ga_auth()` function, or via the filename it has been saved under (by default `gcloud.auth`)

In [6]:

    library(googleAnalyticsR)
    ga_auth(token)

    # can now list accounts, get data etc.
    accs <- ga_account_list()
    head(accs)

    Token cache file:

accountId | accountName | internalWebPropertyId | level | websiteUrl | webPropertyId | webPropertyName | type | starred | viewId | viewName
--- | --- | --- | --- | --- | --- | --- | --- | --- | --- | ---
79301104 | cloudyr | 118427305 | STANDARD | http://cloudyr.github.io | UA-79301104-1 | the cloudyr project | WEB | NA | 123875646 | All Web Site Data
54516992 | Demo Account | 87479473 | STANDARD | https://shop.googlemerchandisestore.com | UA-54516992-1 | Google Merchandise Store | WEB | NA | 92320289 | 1 Master View
54516992 | Demo Account | 87479473 | STANDARD | https://shop.googlemerchandisestore.com | UA-54516992-1 | Google Merchandise Store | WEB | NA | 92324711 | 2 Test View
54516992 | Demo Account | 87479473 | STANDARD | https://shop.googlemerchandisestore.com | UA-54516992-1 | Google Merchandise Store | WEB | NA | 90822334 | 3 Raw Data View
73050356 | GDE Tracking | 110873793 | STANDARD | http://gde-websites.com | UA-73050356-1 | GDE Tracking | WEB | NA | 115760903 | Bot excluded
73050356 | GDE Tracking | 110873793 | STANDARD | http://gde-websites.com | UA-73050356-1 | GDE Tracking | WEB | NA | 115751114 | RAW DATA

In [4]:

    viewId <- 81416156
    gadata <- google_analytics(viewId,
                               date_range = c("30daysAgo", "yesterday"),
                               metrics = "sessions", dimensions = "source",
                               order = order_type("sessions", "DESCENDING", "VALUE"))
    head(gadata)

    2019-06-10 13:31:26> Downloaded [81] rows from a total of [81].

source | sessions
--- | ---
google | 5182
(direct) | 1625
t.co | 179
github.com | 111
cran.r-project.org | 47
shinyapps | 40

## Authentication via JSON service account¶

One other alternative which is better for long-term production use it to generate a service account key.

1. In the same place you generated the OAuth2 credentials create a `service account key` here
2. Download and upload to the Jupyter instance. Protect this key as it gives access.
3. The key will have an email associated with it. Add this as a user to your Google Analytics account you want to interact with.
4. Use `googleAuthR::gar_service_auth()` to authenticate.

This has more details on the googleAnalyticsR website here

In [5]:

    sessionInfo()

    R version 3.5.1 (2018-07-02)
    Platform: x86_64-pc-linux-gnu (64-bit)
    Running under: Debian GNU/Linux 9 (stretch)

    Matrix products: default
    BLAS: /opt/anaconda3/lib/R/lib/libRblas.so
    LAPACK: /opt/anaconda3/lib/R/lib/libRlapack.so

    locale:
     [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
     [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8
     [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8
     [7] LC_PAPER=en_US.UTF-8       LC_NAME=C
     [9] LC_ADDRESS=C               LC_TELEPHONE=C
    [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C

    attached base packages:
    [1] stats     graphics  grDevices utils     datasets  methods   base

    other attached packages:
    [1] bindrcpp_0.2.2         googleAnalyticsR_0.5.0 RevoUtils_11.0.1
    [4] RevoUtilsMath_11.0.0

    loaded via a namespace (and not attached):
     [1] Rcpp_0.12.18      bindr_0.1.1       magrittr_1.5      tidyselect_0.2.4
     [5] uuid_0.1-2        R6_2.2.2          rlang_0.3.4.9003  stringr_1.3.1
     [9] httr_1.3.1        dplyr_0.7.6       tools_3.5.1       googleAuthR_0.6.3
    [13] htmltools_0.3.6   digest_0.6.15     assertthat_0.2.0  tibble_1.4.2
    [17] crayon_1.3.4      IRdisplay_0.5.0   tidyr_0.8.1       purrr_0.2.5
    [21] repr_0.15.0       base64enc_0.1-3   curl_3.2          IRkernel_0.8.11
    [25] glue_1.3.0        memoise_1.1.0     evaluate_0.11     pbdZMQ_0.3-3
    [29] stringi_1.2.4     pillar_1.4.1.9000 compiler_3.5.1    jsonlite_1.5
    [33] pkgconfig_2.0.1