Reputation: 107
I am trying to access the QuickBooks online API via R. Here is what I have so far:
library(httr)
library(httpuv)
endPoint <- oauth_endpoint(request = NULL,
authorize = "https://appcenter.intuit.com/connect/oauth2",
access = "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer")
App <- oauth_app("Untitled",
key = "xxxx",
secret = "xxxxx",
redirect_uri = "http://localhost:1410/")
QBOtoken <- oauth2.0_token(endpoint = endPoint,
app = App,
scope = "com.intuit.quickbooks.accounting",
type = "code",
cache = T)
GET("https://sandbox-quickbooks.api.intuit.com/v3/company/193514718345164/query?query=Select * from Payment", config(token = QBOtoken))
When run the code above through QBOtoken, I go through the whole Oauth2.0 "dance" and get the response:
Waiting for authentication in browser...
Press Esc/Ctrl + C to abort
Authentication complete.
However, when I execute the GET command, it returns:
Error in self$credentials$access_token :
$ operator is invalid for atomic vectors
The .httr-oauth
file that is generated is filled with 284 rows of 32 characters. Is that normal?
I have connected to the API via Postman and it generates an access token allowing me to execute queries like the GET request in my code. There is also an Oauth 2.0 playground on Intuit Developer. Somehow, in R, I am not getting the access token and refresh token.
Another concern, is that I am currently trying to connect to a development environment. For QuickBooks Online, the redirect URL can be the localhost in the development environment, but if I want to connect to the production company(my company) data I will need a https redirect URL. Will this be possible through R?
My ultimate goal for this project is for the script to automatically run on a nightly basis, connect to the API, and ETL the data into a Relational Database for reporting/analytics purposes. Any help would be greatly appreciated!
Upvotes: 1
Views: 1051
Reputation: 107
I did get this "functional," but it is by no means good code. Some of this, like storing tokens in a csv, is not best practice, just a band-aid to test the code.
I created a tokens.csv file in the structure:
"RefreshToken","AccessToken"
"<RefreshToken>","<AccessToken>"
Below is my script that retrieved customer data from the QBO api sandbox.
library(httr)
library(httpuv)
library(curl)
library(jsonlite)
library(base64enc)
#Client ID and Client Secret were retrieved from the online explorer
clientID <- "<ClientID>"
clientSecret <- "<ClientSecret>"
scope <- "com.intuit.quickbooks.accounting"
tokens <- read.csv("tokens.csv")
RefreshToken <- as.character(tokens$RefreshToken[1])
AccessToken <- as.character(tokens$AccessToken[1])
authorize <- base64enc::base64encode(charToRaw(paste0(clientID,":",clientSecret)))
oauth_refresh <- httr::POST("https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer",
add_headers('Content-Type'= "application/x-www-form-urlencoded",
'Accept'= 'application/json',
'Authorization'= paste0('Basic ',authorize)
),
body = list('grant_type'='refresh_token',
'refresh_token'=RefreshToken),
encode = "form")
oaJSON <- fromJSON(content(oauth_refresh, as = "text"))
RefreshToken <- oaJSON[["refresh_token"]][1]
AccessToken <- oaJSON[["access_token"]][1]
tokens <- as.data.frame(list('RefreshToken'=RefreshToken,'AccessToken'=AccessToken))
write.csv(tokens,file = "tokens.csv", row.names = F)
datas <- httr::GET("https://sandbox-quickbooks.api.intuit.com/v3/company/<ID>/query?query=SELECT%20%2a%20FROM%20Customer",
accept_json(),
add_headers('Authorization'= paste0("Bearer ",AccessToken))
)
#datas$status_code
j_son <- content(datas, as = "text")
customers <- fromJSON(j_son)
customer_df <- customers$QueryResponse$Customer
Hopefully this gets the ball rolling correctly for you. Let me know if you have any feedback!
Upvotes: 1