MarkEdmondson1234 / youtubeAnalyticsR

YouTube Analytics API into R
Other
17 stars 7 forks source link

Better error when not including sort #2

Open Phippsy opened 7 years ago

Phippsy commented 7 years ago

I'm trying to pull a report of top 150 videos for my channel using youtubeAnalyticsR, but getting an error message 'query is not supported'.

Expected return data is a data frame containing views by video. I'm trying to recreate the 'top videos report' example from the YT analytics API documentation..

Here is my code:

clientID <-  "XXXX"
clientSecret <- "XXXX"

library(googleAuthR); library(youtubeAnalyticsR)

options("googleAuthR.client_id" = clientID)
options("googleAuthR.client_secret" = clientSecret)

yt_auth()

# Get views by video for top 150
ya <- yt_analytics(id = "UC-XXXX", # my channel ID, starting with 'UC'
                   type = "channel",
                   start.date = "2015-09-01", end.date = "2016-10-01", 
                   metrics = c("views"),
                   dimensions = c("video"),
                   max.results = 150)

However, I get an error message when trying this:

Request Status Code: 400
Error in checkGoogleAPIError(req) : 
  JSON fetch error: The query is not supported. Check the documentation at https://developers.google.com/youtube/analytics/v1/available_reports for a list of supported queries.

I am able to successfully run the example code from your github README and can authenticate succesfully.

No doubt this is a foolish error on my part, but I can't figure out how to get the expected output. I checked the documentation to verify I'm using the correct dimensions/metrics and type/id.

Thanks in advance for any help and thank you for creating this package - should be very useful for me.

Phippsy commented 7 years ago

Having found and tested this query using the the API explorer I can see this is an error with my query, not with the youTubeAnalyticsR package.

Here is the corrected query - I failed to include a sorting dimension previously.

ya <- yt_analytics(id = "UC-XXXX",
                   type = "channel",
                   start.date = "2016-09-01", end.date = "2016-10-01", 
                   metrics = c("views"),
                   dimensions = c("video"),
                   max.results = 150,
                   sort = "-views")
MarkEdmondson1234 commented 7 years ago

Cool, is there a correct query I can put in?

Phippsy commented 7 years ago

Only the one from my message above - I missed out the sort = "-views". I don't think there's anything you need to change with the package, though.

Next step for me is to join up the list of video IDs with video titles. Am working my way through your gar_api_generator and data_parse_function to hopefully do this - will let you know if anything useful comes of it. Thanks as always!

MarkEdmondson1234 commented 7 years ago

Ok, I can at least put in a check to include the sort (or default it to first metric?) to give a better error message.

Phippsy commented 7 years ago

Yeah that would be great if possible. Thanks! I guess the API response text doesn't give you much to go on to automate that.

fwiw, I made a function to match video titles with IDs. Does the job for now.


options("googleAuthR.client_id" = clientID)
options("googleAuthR.client_secret" = clientSecret)

options("googleAuthR.scopes.selected" = 
          c("https://www.googleapis.com/auth/youtube"))

gar_auth()

yt_titles <- function(ids) {
  # In the response, we want each result from the array of 'items'
  # items = [ { id, snippet.title }]

  url <- "https://www.googleapis.com/youtube/v3/videos/"

  results <- NULL

  for ( id in ids ) {
    pars <- list(part = "snippet",
                 id = id)

    f <- gar_api_generator(baseURI = url,
                           http_header = "GET",
                           pars_args = pars,
                           data_parse_function = yt_data_parse)

    res <- f()  
    results <- rbind(results, res)
  }

  return(results)

}

# Read the json
yt_data_parse <- function(x){

  stopifnot(x$kind == "youtube#videoListResponse")

  if(!is.null(x$items)){
    ids <- x$items$id
    titles <- x$items$snippet$title
    results <- data.frame(id = ids, title = titles)

  } else {
    message("No data found")
    results <- NULL
  }

  results

}

# Get some test data
test <- yt_titles(ids = c("Dj-bMNzf8_c", "9JwRfNHbBPk"))

Need to improve it so I only supply a single comma-separated list of ids instead of looping / running a fresh call for each one. Currently I get an error message "JSON fetch error: Required parameter: part" if I try to do more than 1. Will update if I get this fixed.