Quickbooks Online API Oauth2.0 using httr - r

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!

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!

Related

Log in a webpage which uses github OAuth

I want to log in https://adventofcode.com/2021 programatically using httr.
I have only a very superficial understanding of the OAuth "dance", so to understand the principles I did the following:
Create an OAuth App on GitHub
Used the following code to authenticate (N.B. I know I could simply use oauth2.0_token but I felt that this workflow helped me to better understand the different messages, which are exchanged).
library(httr)
client_id <- "<my client id>"
base_url <- "https://github.com"
path <- "login/oauth/authorize"
client_secret <- "<my secret>"
url <- modify_url(base_url, path = path,
query = list(client_id = client_id,
redirect_uri = oauth_callback()))
code <- oauth_listener(url) ## needed to provide credentials in the web browser
access_token <- POST(modify_url(base_url, path = "login/oauth/access_token"),
add_headers(Accept = "application/json"),
body = list(client_id = client_id,
client_secret = client_secret,
code = code$code))
## successfully returns the values
GET("https://api.github.com/rate_limit",
add_headers(Authorization = paste(content(access_token)$access_token,
"OAUTH-TOKEN")))
From this example I think I understand the steps as highlighted in the documentation.
However, I fail to see how I could use this to login to https://adventofcode.com/2021. I have, of course, not the client_secret nor can I redirect the response to my localhost (as GitHub requires that the stored callback matches the redirect URI).
Thus, I was wondering how I could programatically login to https://adventofcode.com/2021 to fetch my task data, say?
I think you are mismatching OAuth2 roles. If you want to use adventofcode.com, you are a resource owner, adventofcode.com is a client and github is an authorization server. So you authenticate, adventofcode.com gets an auth code and then tokens. They can use the tokens to get information about your github account.
The example code you posted is different - your application is a client that gets a code and tokens from the authorization server (github) after a user was authenticated and gave a consent to passing the tokens to your app (permission delegation). So you probably cannot include adventofcode.com into this scenario.
The only way is if adventofcode.com takes a role of a resource server and their API accepts github tokens from different clients. But I know nothing about their API.

R httr Linkedin API: Bad Request (HTTP 400)

My question is closely related to this one: LinkedIn API error of redirect uri from httr
Here is my code:
library(httr)
clientid <- "MY-ID"
secret <- "MY-SECRET"
app <- oauth_app(appname = "app name", key = clientid, secret = secret)
endpoint <- oauth_endpoint(base_url = "https://www.linkedin.com/uas/oauth2",
authorize = "authorization", access = "accessToken")
token <- oauth2.0_token(endpoint = endpoint, app = app)
As I do this, the browser opens with the message Authentication complete. Please close this page and return to R.
In R I get this:
Waiting for authentication in browser...
Press Esc/Ctrl + C to abort
Authentication complete.
Error in oauth2.0_access_token(endpoint, app, code = code, user_params = user_params, :
Bad Request (HTTP 400). Failed to get an access token.
I use the client id and secret given to my app on https://www.linkedin.com/developers/ and I did set the redirect URL there to http://localhost:1410/.
I'm on Ubuntu 18.04, R version 3.6.3, httr version ‘1.4.2’.
I think you might be missing the scope argument in oauth2.0_token().
Examples of LinkedIn scopes you could use would be: scope = "r_organization_social" or scope = "rw_organization_admin".
So it could look like:
token <- oauth2.0_token(endpoint = endpoint, app = app, scope = "rw_organization_admin")
It depends on how much access you've got and what data you'd like to request through the API
I solved the problem changing :token <- oauth2.0_token(endpoint = endpoint, app = app, scope = "w_member_social")

LinkedIn API error of redirect uri from httr

I'm trying to access LinkedIn's API using R and the httr package.
When I execute the last oauth2.0_token() function, in order to gain an authorization token, I get the following error from LinkedIn: "The redirect_uri does not match the registered value".
I've set my redirected url on the LinkedIn Developer site to http://my_app_54321
Does anyone know what the solution is?
# Packages
library(httr)
# Client info
clientid <- "my_id"
secret <- "my_secret"
# App
app <- oauth_app(appname = "app name", key = clientid, secret = secret)
# Endpoints
endpoint <- oauth_endpoint(base_url = "https://www.linkedin.com/uas/oauth2",
authorize = "authorization", access = "accessToken")
# Access token
token <- oauth2.0_token(endpoint = endpoint, app = app)
token
Changing my redirected url to the following solved it since I just needed the application to run locally.
http://localhost:1410/
The comments from the GitHub of httr package pointed in this direction:
https://github.com/r-lib/httr/blob/master/demo/oauth2-linkedin.r

(R) Generating an oauth 1.0 token for Flickr using httr

I'm trying to generate an access token for my Flickr app in httr. My goal is to download images from certain geographical co-ordinates. To my understanding this isn't something the FlickrAPI package can do, so I've decided to use httr.
Running the below code brings up the authorization page but when I submit the authorization I get a localhost error (localhost unexpectedly closed the connection).
What am I forgetting here? I haven't set a callback URL, if that's relevant.
library(httr)
setwd("G:\\Project\\R Code\\")
api_key <- "<TOKEN>"
secret <- "<SECRET>"
flickr.app <- oauth_app("App Name", api_key, secret)
flickr.endpoint <- oauth_endpoint(
request = "https://www.flickr.com/services/oauth/request_token",
authorize = "https://www.flickr.com/services/oauth/authorize",
access = "https://www.flickr.com/services/oauth/access_token"
)
token <- oauth1.0_token(
flickr.endpoint,
flickr.app,
cache = FALSE
)

OAuth2 authentication with R using httr

I am trying to read some data from the Polar Accesslink API. I have read the documentation and examples (I'm not that familiar with Python) as well as httr examples/demos of Oauth2.0:
https://www.polar.com/accesslink-api/#polar-accesslink-api
https://github.com/polarofficial/accesslink-example-python
Here is my code:
library(httr)
client_id <- rstudioapi::askForPassword()
client_secret <- rstudioapi::askForPassword()
# redirect_uri determined in registration to http://localhost:1410/
app <- oauth_app(appname = "polar_app",
key = client_id,
secret = client_secret)
endpoint <- oauth_endpoint(
request = NULL,
authorize = "https://flow.polar.com/oauth2/authorization",
access = "https://polarremote.com/v2/oauth2/token")
token <- oauth2.0_token(endpoint = endpoint,
app = app,
scope = "accesslink.read_all", # tested also without scope
use_basic_auth = T # tested both T and F
)
Last part of the code (token) produces the following error:
Waiting for authentication in browser...
Press Esc/Ctrl + C to abort
Authentication complete.
Error in oauth2.0_access_token(endpoint, app, code = code, user_params = user_params, :
Bad Request (HTTP 400). Failed to get an access token.
It opens browser with url localhost:1410/?state={STATE}&code={CODE} and says:
"Authentication complete. Please close this page and return to R."
Based on the API documentation and github Python examples, I can't figure out if I need to set some values for user_params or query_authorize_extra in oauth2.0_token.
Having the same issue. Sent a message off to support and they came back with making sure that you include header "Content-Type: application/x-www-form-urlencoded" and that the body gets sent as plain/raw text and contains "grant_type=authorization_code&code=<AUTHORIZATION_CODE>".
I have not tested this out but hoping it helps you out if you have not already found a solution

Resources