I've been using the HTTR package to make requests to the YouTube Data API. I have two channels that I am getting stats for. Upon the first use, when requesting an access token I did the whole OAuth dance where I was redirected to Google as expected. However, I saved the tokens in .httr-oauth
files. I developed a for loop similar to the following for me to get my statistics:
channelOneFile <- ".httr-oauth-channel1"
channelTwoFile <- ".httr-oauth-channel2"
myData <- list()
for(i in 1:2){
token <- try(suppressWarnings(readRDS(tokenFile)), silent = TRUE)[[1]]
# And Then I get stats with a GET Request
url <- paste0("https://youtube.googleapis.com/youtube/v3/videospart=contentDetails%2Csnippet",
"&id=",videoId)
request <- GET(url, token)
myData[[i]] <- request
}
which worked well for a while. However, after running this code roughly 20x or so (due to some testing and tweaking parameters, ONE of the get requests came back with
Auto-refreshing stale OAuth token.
Warning: Unable to refresh token: invalid_grant
Token has been expired or revoked.
At this point I'd just delete the ".httr-oauth" file, reauthenticate, save the new file, and then my code works again. However, I'm hoping to have this code automated on a local server, where the server (I think) can't do the OAuth dance if the token doesn't work.
When I make a request, I know HTTR automatically uses the refresh token to get a new access token, and I know that Google APIs has a limit of how many times a refresh token can be used. I think that perhaps when it gets the new token it doesn't update the ".httr-oauth" file? How can I get it to do that? If that's not an option, what can I do to do the authentication ONCE, save the credentials and access token and such in a file, and then refer to that file when making server requests?
UPDATE: Here is my OAuth flow:
if (file.exists(tokenFile)) {
token <- try(suppressWarnings(readRDS(tokenFile)), silent = TRUE)[[1]]
} else if (is.null(appId) | is.null(appSecret)) {
stop("Missing App Credentials")
} else {
token <- httr::oauth2.0_token(httr::oauth_endpoints("google"),
httr::oauth_app("google", appId, appSecret),
scope = c("https://www.googleapis.com/auth/youtube.readonly",
"https://www.googleapis.com/auth/yt-analytics.readonly"))
}