Retrieve Oauth 2.0 refresh token with R httr google demo - r

A refresh token is not available when I follow Hadley's R google Oauth2.0 demo to access Fusion tables.
Demo: https://github.com/hadley/httr/blob/master/demo/oauth2-google.r
Example of modified "offline" attempt:
google_token <- oauth2.0_token(oauth_endpoints("google"), myapp,
scope = "https://www.googleapis.com/auth/fusiontables",
type= "offline",
use_oob = FALSE,
cache = TRUE)
Any direction on how to retrieve a refresh token is much appreciated.
UPDATE:
Using the follow code a character string is returned with google_token$credentials. Is this the authorization code referenced here:https://developers.google.com/accounts/docs/OAuth2WebServer#offline
google_token <- oauth2.0_token(oauth_endpoints("google"), myapp,
scope = "https://www.googleapis.com/auth/fusiontables",
type= "access_type='offline'",
use_oob = FALSE,
cache = TRUE)
Thank you.

I'm a bit late to the party here but hopefully this helps someone. I found this question last week because I was struggling with the same issue. Like you, I read the API documentation and tried the "offline" in the "type" field of the "oauth2.0_token()" function but it messed up the response. I downloaded the httr package source files from the github repository and had a look around. After some digging I found a way around it.
if you modify the "authorize-url" variable in oauth-init from this:
authorize_url <- modify_url(endpoint$authorize, query = compact(list(
client_id = app$key,
scope = scope_arg,
redirect_uri = redirect_uri,
response_type = "code",
state = state)))
to this:
authorize_url <- modify_url(endpoint$authorize, query = compact(list(
client_id = app$key,
scope = scope_arg,
redirect_uri = redirect_uri,
response_type = "code",
state = state,
access_type="offline")))
and then source the oauth-token and all the dependent functions (including oauth-init) you'll get a refresh token. For some reason, when oauth_token calls init_oauth2.0 it doesn't pass the "type" argument.
It's a nasty workaround and I've probably committed several sins but it does work. and you do get a refresh token.

Related

Paginated API - R

With a paginated oAuth2.0 API, how do I use the response headers to view the next page?
So far I have successfully created an endpoint, app, token, and response:
# here's the key and username
API_KEY = 'my key'
API_USER = 'my username'
# set up the endpoint
api_endpoint= httr::oauth_endpoint(
authorize = "https://www.hydrovu.com/public-api/oauth/authorize",
access = "https://www.hydrovu.com/public-api/oauth/token"
)
# heres the app we will use to download data to
App = httr::oauth_app("xxx", key = API_USER, secret = API_KEY)
# heres the token we will use as a password
API.token = httr::oauth2.0_token(api_endpoint,
App,
scope = "https://www.hydrovu.com/public-api/oauth/token",
client_credentials=TRUE,
cache = FALSE,
config_init = user_agent("Testing Oauth with httr"))
# this is the response or the data
res <- httr::GET(url = "https://www.hydrovu.com/public-api/v1/locations/{id}/data?startTime=0",
user_agent("Testing Oauth with httr"),
config(token = API.token))
The response headers from res include next-page, which has a long string as the value. E.g. 6haGnbeLO09jlwe6poy7erT43qp
How to I use this next-page information to actually get the next page?
I am using the HydroVu API: https://www.hydrovu.com/public-api/docs/index.html
Let me know if you need more information!
After speaking to the excellent Hadley Wickham from httr maintenance, I have found the solution.
I was originally trying to pass x-isi-next-page to x-isi-next-page through add_headers() like so:
# original GET
res <- httr::GET(url,
user_agent("Testing Oauth with httr"),
config(token = API.token))
# write x-isi-next-page to object
nextpage = res$headers$`x-isi-next-page`
# pass to add_headers()
res <- httr::GET(url,
user_agent("Testing Oauth with httr"),
config(token = API.token),
add_headers(`x-isi-next-page` = nextpage))
When in fact I should have been passing it to x-isi-start-page
resp <- httr::GET(url,
user_agent("Testing Oauth with httr"),
config(token = API.token),
add_headers(`x-isi-start-page` = nextpage))
Thus, giving me the next page of results.
Now, to decode the json and create a compiled csv...

How to connect to Slack via slackr package in R

I'm trying to set up the slackr package in R to allow me to post to Slack through RStudio, but it seems the connection isn't working.
I've installed the package, set up the required App in my Slack Workspace, have a webhook and access tokens, manually granted all of Scopes needed in Slack, set up the config file and have confirmed via the cmd line that this works by sending a message to the channel through that successfully. Unfortunately nothing is working via R.
slackr_msg(paste("test"),
,channel = "#it-reports")
slackr_ims(api_token="xoxb-...")
When run the above both produce Error: Join columns must be present in data. x Problem with 'id'. which I can't find anybody else experiencing. It sounds like an issue with the user, but the app is in the channel, has permission to access all public channels, and this error appears regardless of whether I try and send it via my logged in account or just from the bot. When I just try and return something simple like listed channels with slackr_channels I get NULL. I've tried both OAuth Access Token and Bot User OAuth Access Token with all permissions needed in the scope but neither are letting me access Slack.
I'm not sure you still need an answer, but in case anyone else is looking - I've run into the same issue. I think the underlying method that your slack channel name "#my_excellent_named_channel" is converted to the channel id is deprecated.
"https://slack.com/api/channels.list" has been changed to "https://slack.com/api/conversations.list" in the methods.
I couldn't find a better way than brute forcing my channel id because I only need to publish to a notifications channel.
nextCursor=""
for (j in c(1:10)){
resp<-GET(url = "https://slack.com/api/conversations.list",
query = list(token=YOUR_BOT_TOKEN,
cursor=nextCursor
))
foo=fromJSON(content(resp, as="text"))
for (i in c(1:100)){
if(foo$channels[[i]]$name %like% 'my_excellent_named_channel'){
print(paste(nextCursor, "\n"))
print(paste(i,foo$channels[[i]]$name,"\n"))
print(paste(foo$channels[[i]]$id))
}
}
nextCursor=foo$response_metadata[[1]]
}
You'll probably need to run through a few more than the 10 top level iterations, but if you go too fast it locks you out. I then just exchanged the channel name in my config file for the channel id, and rewrote the functions to avoid the conversion.
Here's slackMsg (conversion of slackrMsg)
slackMsg=function (txt = "", channel = Sys.getenv("SLACK_CHANNEL"), username = Sys.getenv("SLACK_USERNAME"),
icon_emoji = Sys.getenv("SLACK_ICON_EMOJI"), api_token = Sys.getenv("SLACK_API_TOKEN"),
...)
{
if (api_token == "") {
stop("No token specified. Did you forget to call slackr_setup()?",
call. = FALSE)
}
if (icon_emoji != "") {
icon_emoji <- sprintf(", \"icon_emoji\": \"%s\"", icon_emoji)
}
output <- paste0(txt, collapse = "\n\n")
loc <- Sys.getlocale("LC_CTYPE")
Sys.setlocale("LC_CTYPE", "C")
on.exit(Sys.setlocale("LC_CTYPE", loc))
resp <- POST(url = "https://slack.com/api/chat.postMessage",
body = list(token = api_token, channel = channel,
username = username, icon_emoji = icon_emoji, text = output,
as_user = TRUE, link_names = 1, ...))
warn_for_status(resp)
return(invisible())
}
Don't forget to give your bot chat.write permissions in your Slack App.

Using Rtweet's search_fullarchive in R

I am trying to use rtweet's search_fullarchive using my premium token registered at Twitter Developer. However, I got an error message of:
Warning: list(message = "Forbidden: Authentication succeeded but account is not authorized to access this resource.", sent = "2019-07-14T14:30:11+00:00", transactionId = "xxxxxxxxxx")
How do I get past this problem? Is there an error in the way i code?
I ensured my token is working well by testing it using httr's POST method and it worked completely fine.
I also tested my token using normal search_tweets, and also worked fine.
cons_key = "xxx"
cons_sec = "xxx"
acc_tok = "xxx"
acc_sec = "xxx"
app = "abc"
token = rtweet::create_token(app,cons_key,cons_sec,acc_tok,acc_sec)
manutd = search_fullarchive("manchester united",n=500,
fromDate = "201812010000",toDate = "201902010000",
env_name = app,token = token)
I expected a tibble dataframe as usually Rtweet's returns. However this is what i received:
"Warning: list(message = "Forbidden: Authentication succeeded but account is not authorized to access this resource.", sent = "2019-07-14T14:30:11+00:00", transactionId = "xxxxxxxxxx")"
data frame with 0 columns and 0 rows
To help anyone who might have trouble with the same thing, i'll write down a bit of explanation. Firstly, if you have registered a premium account, go to
To create the token, you need the App Name.
token = rtweet::create_token(app_name,cons_key,cons_sec,acc_tok,acc_sec)
To do query, you need the environment name.
search_fullarchive(q, n = 100, fromDate = NULL, toDate = NULL, env_name = "dev_name", safedir = NULL, parse = TRUE, token = token)
Hope it helps beginners or anyone who might have the same troubles.

How to fetch Shopify store orders using Shopify's API

I'm struggling to import the orders for a Shopify development store using the httr package in R. Here's what I've tried.
I've created a development store and made some fake orders.
Within my development store, I added a private app and generated my API key and Password
Following this article, I tried implementing the following request
Code
apikey <- "foo"
pass <- "bar"
shop <- GET(
url = "my-test-store.myshopify.com/orders.json",
authenticate(user = apikey, password = pass)
)
But this gives a 401 status code. However, this works but returns xml instead of json
shop <- GET(
url = "my-test-store.myshopify.com/orders",
authenticate(user = apikey, password = pass)
)
How can I retrieve the results as JSON instead of XML?
Note that I can also fetch the orders using the R package shopifyr but would rather not use that package as it is no longer maintained.
You're close. Try this:
library(httr)
apikey <- "foo"
pass <- "bar"
orders <- GET(
url = "https://yourshop.myshopify.com/admin/orders.json",
authenticate(user = apikey, password = pass)
)
content(orders)
Update 2019-05-13
I created an R package called shopr for querying data via the Shopify API. Fetching orders looks like this
library(shopr)
shopr_get_orders(
shopURL = "https://my-test-store.myshopify.com",
APIKey = "abc123",
APIPassword = "def456"
)
Old Answer
Figured it out.
orders <- GET(
url = "https://my-test-store.myshopify.com/admin/orders",
add_headers(Accept = "application/json"),
authenticate(user = apikey, password = pass)
)
orders
The trick was to explicitly put "https://..." in the url otherwise httr was prepending "http://" to the url, causing my 401 problem.

RGA (CRAN) - "get_accounts" gives wrong accounts

Note it says: RGA package from CRAN. Which is different from "rga"
package from Github. Nevertheless, i have the same problem with both
packages. But for the question let's stick just to RGA from CRAN.
**The questions is updated and edited, because the first aid was not enough. I still have the problems with the accounts.
I work with 2 emails for accesing Google Analtics. Each one has access to diffent accounts within Google Analytics. I use email A at my house, and email B at work.
Now, im using RGA (from CRAN) within R, and at my house i need to access the Google Analytics accounts from the Email B (work email, that has access to specific Google Analytics accounts).
The problem is that when using this code:
For Account 1: Email A (home email):
client.id1 <- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
client.secret1 <- "bbbbbbbbbbbbbb"
ga_token1 <- authorize(client.id1, client.secret1, cache = TRUE, verbose = getOption("rga.verbose", FALSE))
get_accounts(start.index = NULL, max.results = NULL, ga_token1, verbose = getOption("rga.verbose", FALSE))
For Account 2: Email B (work email):
client.id2 <- "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
client.secret2 <- "yyyyyyyyyyyyyyy"
ga_token2 <- authorize(client.id2, client.secret2, cache = TRUE, verbose = getOption("rga.verbose", FALSE))
get_accounts(start.index = NULL, max.results = NULL, ga_token2, verbose = getOption("rga.verbose", FALSE))
What ever, i use at my Home computer, i get the same accounts fro both my Home Gmail accounts for GA, and my Work Gmail account for GA.
Is there any step that i'm missing?
I want to get the accounts for email B, but no matter what i just get the accounts related with email A.
I've delated all my Google Analytics API projects (from A and B), and recreated the API for Email B. But no matter what, i just get the accounts for email A.
**My Google Api project was created with B (the email with the access to the desire account). But i just see accounts related to A.
You need to create two different tokens which will have the authorization for the email you authenticate via the Google login page. Its also a lot easier to get data via the method described in the readme (?rga.open), but for your examples:
##authenticate with first email
ga_token1 <- authorize(client.id, client.secret, cache = TRUE, verbose = getOption("rga.verbose", FALSE))
##authenticate with second email
ga_token2 <- authorize(client.id, client.secret, cache = TRUE, verbose = getOption("rga.verbose", FALSE))
Then to get accounts:
get_accounts(start.index = NULL, max.results = NULL, ga_token1, verbose = getOption("rga.verbose", FALSE))
get_accounts(start.index = NULL, max.results = NULL, ga_token2, verbose = getOption("rga.verbose", FALSE))
But I would do it this way:
## authenticate under first email
rga.open(instance = "ga1")
## authenticate under second email
rga.open(instance = "ga2")
Then to call data such as profiles:
profiles1 <- ga1$getProfiles()
profiles2 <- ga2$getProfiles()
It appears because tokens stored in the same cache file (.ga-token.rds by default), i.e. second token replaced first. When tokens are used it read into cache file.
To Solve this issue you should set cache = FALSE or define specific cache path for each token. Examples below:
First, disabling cache:
work_token <- authorize(client.id1, client.secret1, cache = FALSE)
home_token <- authorize(client.id2, client.secret2, cache = FALSE)
Second, different cache paths:
work_token <- authorize(client.id1, client.secret1, cache = "work.token")
home_token <- authorize(client.id2, client.secret2, cache = "home.token")
To check it:
list_profiles(token = work_token)
list_profiles(token = home_token)

Resources