jburkhardt / RAdwords

Loading Google Adwords Data into R
https://github.com/banboo-data/r4googleads
Other
99 stars 36 forks source link

refreshToken() on unix server #90

Closed jburkhardt closed 6 years ago

jburkhardt commented 6 years ago
Error in rjson::fromJSON(RCurl::postForm("https://accounts.google.com/o/oauth2/token",  :   STRING_ELT() can only be applied to a 'character vector', not a 'raw'

https://stackoverflow.com/questions/50701975/using-the-package-radwords-in-an-r-script-on-a-unix-server-error-in-rjson#comment88438114_50701975

jburkhardt commented 6 years ago

Debugging

library(RAdwords)
google_auth <- doAuth()
statement <- statement(select=c('Date','Ctr'),
                  report="ACCOUNT_PERFORMANCE_REPORT",
                  start="2018-01-01",
                  end="2018-01-09")
apiVersion = "201802"
clientCustomerId = "***-***-****"
includeZeroImpressions = F
verbose = T

# for a better overview split google auth
access <- google_auth$access
credlist <- google_auth$credentials
google.auth <- paste(access$token_type, access$access_token)

# because access token can expire 
# we need to check whether this is the case
if(as.numeric(Sys.time())-3600 >= access$timeStamp){
  access <- refreshToken(google_auth) 
} 

url <- paste("https://adwords.google.com/api/adwords/reportdownload/v",apiVersion,sep="")

header <- c("Authorization" = google.auth,
            "developerToken" = credlist$auth.developerToken,
            "clientCustomerId" = clientCustomerId,
            "includeZeroImpressions" = includeZeroImpressions)

data <- RCurl::getURL(url, 
                      httpheader = header,
                      postfields=statement,
                      verbose = verbose,
                      #                     cainfo = cert, #add SSL certificate
                      ssl.verifypeer = TRUE)
devktpx commented 6 years ago

The code in (1) leads to the error statement in (2). Please note that I entered the code line by line so the error occoured in the last line.

(1) Code

    library(RAdwords)
    google_auth <- doAuth()
    statement <- statement(select=c('Date','Ctr'),
                  report="ACCOUNT_PERFORMANCE_REPORT",
                  start="2018-01-01",
                  end="2018-01-09")

         apiVersion = "201802"
         clientCustomerId = "xxx-xxx-xxxx" # I did insert the actual number for x.
         includeZeroImpressions = F
         verbose = T

    access <- google_auth$access
    credlist <- google_auth$credentials
    google.auth <- paste(access$token_type, access$access_token)

    access <- refreshToken(google_auth)

(2) Error-Statement

       Error in rjson::fromJSON(RCurl::postForm("https://accounts.google.com/o/oauth2/token",  :
         STRING_ELT() can only be applied to a 'character vector', not a 'raw'
       Calls: refreshToken -> <Anonymous> -> .Call
       Execution halted
jburkhardt commented 6 years ago

@devktpx Thank you for the update. What happens if you run the code below?

library(RAdwords)
google_auth <- doAuth()
statement <- statement(select=c('Date','Ctr'),
                  report="ACCOUNT_PERFORMANCE_REPORT",
                  start="2018-01-01",
                  end="2018-01-09")
apiVersion = "201802"
clientCustomerId = "***-***-****"
includeZeroImpressions = F
verbose = T

# for a better overview split google auth
access <- google_auth$access
credlist <- google_auth$credentials
google.auth <- paste(access$token_type, access$access_token)

# because access token can expire 
# we need to check whether this is the case
if(as.numeric(Sys.time())-3600 >= access$timeStamp){
  raw_data <- RCurl::postForm('https://accounts.google.com/o/oauth2/token', 
                refresh_token=google_auth$access$refresh_token, 
                client_id=google_auth$credentials$c.id,
                client_secret=google_auth$credentials$c.secret, 
                grant_type="refresh_token", 
                style="POST",
                .opts = list(ssl.verifypeer = FALSE))

if(is.raw(raw_data)) {
  rt = rjson::fromJSON(rawToChar(raw_data))
} else {
  rt = rjson::fromJSON(raw_data)
}

access <- rt
} 

url <- paste("https://adwords.google.com/api/adwords/reportdownload/v",apiVersion,sep="")

header <- c("Authorization" = google.auth,
            "developerToken" = credlist$auth.developerToken,
            "clientCustomerId" = clientCustomerId,
            "includeZeroImpressions" = includeZeroImpressions)

data <- RCurl::getURL(url, 
                      httpheader = header,
                      postfields=statement,
                      verbose = verbose,
                      #                     cainfo = cert, #add SSL certificate
                      ssl.verifypeer = TRUE)
devktpx commented 6 years ago

Thank you for the valueable input @jburkhardt

My Version of RAdwords is:

0.1.16

Here is the code that I posted this time. Please note that I inserted the error occured in the last line of the code, that is to say: in the curl-request.

library(RAdwords)

google_auth <- doAuth()

statement <- statement(select=c('Date','Ctr'),
                  report="ACCOUNT_PERFORMANCE_REPORT",
                  start="2018-01-01",
                  end="2018-01-09")

      apiVersion = "201802"
      clientCustomerId = "xxx-xxx-xxxx"
      includeZeroImpressions = F
      verbose = T

access <- google_auth$access
credlist <- google_auth$credentials
google.auth <- paste(access$token_type, access$access_token)

raw_data <-RCurl::postForm('https://accounts.google.com/o/oauth2/token',
                refresh_token=google_auth$access$refresh_token,
                client_id=google_auth$credentials$c.id,
                client_secret=google_auth$credentials$c.secret,
                grant_type="refresh_token",
                style="POST",
                .opts = list(ssl.verifypeer = FALSE))

if(is.raw(raw_data)) {
  rt = rjson::fromJSON(rawToChar(raw_data))
} else {
  rt = rjson::fromJSON(raw_data)
}

access <- rt

url <- paste("https://adwords.google.com/api/adwords/reportdownload/v",apiVersion,sep="")

header <- c("Authorization" = google.auth,
            "developerToken" = credlist$auth.developerToken,
            "clientCustomerId" = clientCustomerId,
            "includeZeroImpressions" = includeZeroImpressions)

#data <-
RCurl::getURL(url,
                      httpheader = header,
                      postfields=statement,
                      verbose = verbose,
                      #                     cainfo = cert, #add SSL certificate
                      ssl.verifypeer = TRUE)

This time I get far more output from the console.

* About to connect() to proxy proxy.xxx.xxxxx.xx port 8080 (#1)
*   Trying xx.xxx.xxx.xx...
* Connected to proxy.xxx.xxxxx.xx (xx.xxx.xxx.xx) port 8080 (#1)
* Establish HTTP proxy tunnel to adwords.google.com:443
> CONNECT adwords.google.com:443 HTTP/1.1
Host: adwords.google.com:443
Proxy-Connection: Keep-Alive
Authorization: xxx
developerToken: xxx
clientCustomerId: xxx-xxx-xxxx
includeZeroImpressions: FALSE

< HTTP/1.1 200 Connection established
<
* Proxy replied OK to CONNECT request
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSL connection using xxx
* Server certificate:
*       subject: CN=adwords.google.com,O=Google LLC,L=Mountain View,ST=California,C=US
*       start date: May 23 09:48:13 2018 GMT
*       expire date: Aug 15 09:08:00 2018 GMT
*       common name: adwords.google.com
*       issuer: CN=Google Internet Authority G3,O=Google Trust Services,C=US
> POST /api/adwords/reportdownload/v201802 HTTP/1.1
Host: adwords.google.com
Accept: */*
Authorization: Bearer xxxxx
developerToken: xxxxx
clientCustomerId: xxx-xxx-xxxx
includeZeroImpressions: FALSE
Content-Length: 92
Content-Type: application/x-www-form-urlencoded

* upload completely sent off: 92 out of 92 bytes
< HTTP/1.1 400 Bad Request
< Content-Type: text/xml
< Date: Mon, 11 Jun 2018 07:19:02 GMT
< Expires: Mon, 11 Jun 2018 07:19:02 GMT
< Cache-Control: private, max-age=0
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< X-XSS-Protection: 1; mode=block
< Server: GSE
< Alt-Svc: quic=":443"; ma=2592000; v="43,42,41,39,35"
< Accept-Ranges: none
< Vary: Accept-Encoding
< Transfer-Encoding: chunked
<
* Connection #1 to host proxy.xxx.xxxxx.xxx left intact
[1] "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><reportDownloadError><ApiError><type>AuthenticationError.OAUTH_TOKEN_INVALID</type><trigger>&lt;null&gt;</trigger><fieldPath></fieldPath></ApiError></reportDownloadError>"
jburkhardt commented 6 years ago

Please tell me after which line of code do you receive the error message? What happens if you run the code below only? Does an error pop up?

library(RAdwords)
google_auth <- doAuth()
statement <- statement(select=c('Date','Ctr'),
                  report="ACCOUNT_PERFORMANCE_REPORT",
                  start="2018-01-01",
                  end="2018-01-09")
apiVersion = "201802"
clientCustomerId = "***-***-****"
includeZeroImpressions = F
verbose = T

# for a better overview split google auth
access <- google_auth$access
credlist <- google_auth$credentials
google.auth <- paste(access$token_type, access$access_token)

# refreshToken function broken into pieces with raw data transformation
raw_data <- RCurl::postForm('https://accounts.google.com/o/oauth2/token', 
                refresh_token=google_auth$access$refresh_token, 
                client_id=google_auth$credentials$c.id,
                client_secret=google_auth$credentials$c.secret, 
                grant_type="refresh_token", 
                style="POST",
                .opts = list(ssl.verifypeer = FALSE))

if(is.raw(raw_data)) {
  rt = rjson::fromJSON(rawToChar(raw_data))
} else {
  rt = rjson::fromJSON(raw_data)
}
access <- rt

Your question concerning the url is not the issue. You don´t have to insert something different there.

devktpx commented 6 years ago

Thank you for the above code snippet @jburkhardt . It runs without an error. Please note that I edited the my post from Friday in which I inserted the entire error message and the line, where it occured.

jburkhardt commented 6 years ago

@devktpx Thank you for the update of the error message. I created a new branch refresh_token_raw_data with a patch of the refreshToken function. Could you please install this version/branch of RAdwords and test again with a standard code example.

Installation

require(devtools)
install_github('jburkhardt/RAdwords', ref = "refresh_token_raw_data")

Test Code

# load package and authentication
library(RAdwords)
google_auth <- doAuth()
# Create Statement
body <- statement(select = c('Clicks','AveragePosition','Cost','Ctr'),
report = "ACCOUNT_PERFORMANCE_REPORT",
start = "2018-01-01",
end = "2018-01-10")
# Query Adwords API and get data as dataframe
#make sure to use the Adwords Account Id (MCC Id will not work)
data <- getData(clientCustomerId='xxx-xxx-xxxx', google_auth=google_auth ,statement=body)
devktpx commented 6 years ago

Now it works! Thank you @jburkhardt .

jburkhardt commented 6 years ago

@devktpx Great! Thank you for all your help and the testing!