0

I've had success with GET requests from Youtube API v3, but am having problems getting a POST version to work, for adding a video to a playlist. I've tried many combinations of things, like putting the key in the query string, the access token in either the query string or the header, json vs. jsonp, but still no luck.

I got it to work fine in the API Explorer but the request it prints out is just the basic pieces without the context code to make it work, so I'm guessing I'm messing something up in the implementation of calling the ajax post command. Here's what I'm doing:

var myAccessToken = "blahblah"; //from oauth2, works fine for other calls

$.ajax({
  type: "POST",

  url: "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&access_token=" + myAccessToken, 

  data: {
    "snippet": {
      "playlistId": "PLIjo1t8cDbpGhOJrgEgMGFMb-VtAus_x9",  
      "resourceId": {
        "kind": "youtube#video",
        "videoId": "KMGuyGY5gvY"
      },
    }                
  },  

  success: function(data, textStatus, request) { 
    console.log("in success of ajax call, data: ", data);
  },

  dataType: 'jsonp' 
});

My current error is below. Not sure if I actually need a "filter selected" or if my syntax is just wrong somewhere.

Error 400:
domain: "youtube.parameter"
location: ""
locationType: "parameter"
message: "No filter selected."
reason: "missingRequiredParameter"

Any ideas to try?

DynamicFX
  • 46
  • 1
  • 7

3 Answers3

0

I believe you're missing part: 'snippet', before your data resource.

not_a_bot
  • 2,332
  • 2
  • 19
  • 33
  • Interesting idea. Do you mean that part would be at the same level in the ajax object as url, data and type? I don't think "part" is something it knows to look for, and when I tried it, nothing changes. I also tried taking the `part=snippet` piece out of the url query string in case there was a redundancy problem, but then it complained that it needed a part specified. (So `part` and `filter` may not be the same kind of thing...) Were you thinking of a different way though? Is there any documentation on that syntax anywhere? – DynamicFX Oct 06 '15 at 23:37
  • I was going off of the Javascript [sample code](https://developers.google.com/youtube/v3/code_samples/javascript#my_uploaded_videos) (look for "insert" for the code for adding a video to a playlist). A similar [question](http://stackoverflow.com/questions/16735327/youtube-api-v3-apiclient-errors-httperror-no-filter-selected-where-do-i-sel) (albeit in Python) also had a "no filter selected" message and required `part`in order for the request to be valid. – not_a_bot Oct 06 '15 at 23:53
  • OK, I can see why that would make sense to try, from that example. From what I can tell, though, the kind of object that `gapi.client.youtube.playlists.insert()` takes is different than the kind a jquery ajax call takes, though there are some similarities. It appears that those JS and python api's specify "part" as a passed param, but in an ajax command, having `part=snippet` in the url specifies that "part" - especially because it complains about not having one if I take it out. – DynamicFX Oct 08 '15 at 00:49
  • Researching some more, I'm suspicious that it might be a GET vs POST issue. I'm trying to use jsonp because json won't work going Cross Domain. But it looks like jsonp only works with GET. And from what I can tell, the youtube API call to insert a video is expecting POST (though I'm not positive that's a requirement). I've been trying a bunch of things but can't successfully get a POST to go through. I was looking at [this answer](http://stackoverflow.com/a/17722058/5400215). – DynamicFX Oct 08 '15 at 06:35
  • 1
    Most likely it's that you are doing get instead of post. Use CORS (CROSS-ORIGIN RESOURCE SHARING). – Ibrahim Ulukaya Oct 22 '15 at 12:42
0

I got it working, though I'm not positive exactly what part was the problem. I came across this example: https://code.google.com/p/youtube-api-samples/source/browse/yt-upload-javascript/index.js which had an example that was doing almost the same thing as what I needed, and once I changed my syntax to be like that, it worked. Here's what I ended up with:

var accessToken = "blahblah";
var metadata = {
        snippet: {
                playlistId: "WL", //specifically works for WatchLater list, 
                                 //but a playlist ID can be used too
                resourceId: {
                    kind: "youtube#video",
                    videoId: "eNAajAflpBQ"
                },
        }
};

$.ajax({
    method: "POST", 
    url: "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet", 

    data: JSON.stringify(metadata),

    headers: {
        Authorization: 'Bearer ' + accessToken
    },

    contentType: 'application/json',
}).done( function(data, textStatus, request) { 
    console.log("in success of ajax call, data: ", data);
});

Thanks to those who looked into it and gave suggestions!

DynamicFX
  • 46
  • 1
  • 7
0

Initially I requested SCOPES = 'https://www.googleapis.com/auth/youtube.readonly'

and according to this:

Authorization

This request requires authorization with at least one of the following scopes (read more about authentication and authorization).

Scope

https://www.googleapis.com/auth/youtubepartner

https://www.googleapis.com/auth/youtube

https://www.googleapis.com/auth/youtube.force-ssl

I was needed to request an additional SCOPE.

My insert looks like this:

let request = gapi.client.youtube.playlistItems.insert({
  part: 'snippet',
  resource: {
    snippet: {
      playlistId: 'PLAYLIST_ID',
      resourceId: {
        videoId: 'YOUTUBE_TRACK_ID,
        kind: 'youtube#video'
      }
    }
  }
})
request.execute(function (response) {
  ...
})
TitanFighter
  • 4,582
  • 3
  • 45
  • 73