0

I'm trying to call the youtube API to make a playlist on my channel from a chrome extension and I keep getting this error code returned back to me;

domain: "youtube.parameter"
location: "parameters."
locationType: "other"
message: "No filter selected. Expected one of: channelId, id, mine"
reason: "missingRequiredParameter"

this is my manifest file:

"action": {
      "default_title": "multi monitor for youtube"
    },
"oauth2": {
      "client_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "scopes": [
        "https://www.googleapis.com/auth/youtube.force-ssl",
        "https://www.googleapis.com/auth/youtubepartner",
        "https://www.googleapis.com/auth/youtube"
      ]
    },
    "permissions": [
      "identity"
    ],
    "host_permissions": ["https://www.googleapis.com/"],
    
    "background": {
      "service_worker": "background.js"
    },
    
     "manifest_version": 3

and this is my background file

chrome.action.onClicked.addListener(function(){
  chrome.identity.getAuthToken({ interactive: true }, function (token) {
    console.log(token);
    let fetch_options = {
      //method: 'POST',
      headers: {
        Authorization: `Bearer ${token}`,
        'Content-Type': 'application/json',
      },
      "part": [
        "snippet,status"
      ],
      "resource": {
        "snippet": {
          "title": "Sample playlist created via API",
          "channelId": "UC0E5pDp_c2riLV4UhEgynKA",
          "description": "This is a sample playlist description.",
          "tags": [
            "sample playlist",
            "API call"
          ],
          
          "defaultLanguage": "en"
        },
        "status": {
          "privacyStatus": "private"
        },
      }
    };

    fetch(
      'https://www.googleapis.com/youtube/v3/playlists',
      fetch_options
    )
      .then((response) => response.json()) // Transform the data into json
      .then(function (data) {
        console.log(data);//contains the response of the created event
    });
  });
});

I tried to use the second answer from this question but there are some changes that had to be made in order to call the youtube API instead of the calendar. Because I was getting the error I tried adding the channel ID to the snippet and it still doesn't work. I'm very new to creating chrome extensions so please forgive me if there is an obvious mistake here.

Peter
  • 15
  • 6
  • Do you have `"host_permissions": ["https://www.googleapis.com/"]`? – wOxxOm Apr 29 '22 at 16:40
  • @wOxxOm I had it there before but it was set to youtube.com, I deleted it because I tested it and it didn't change the error. I just added that to it and it still didn't change it. – Peter Apr 29 '22 at 17:04
  • Assuming you've reloaded the extension afterwards, is there anything unusual in the request/response if you inspect the [background.js console?](/a/10258029) – wOxxOm Apr 29 '22 at 17:33
  • @wOxxOm Yes I did reload the extension, I even reinstalled it just to be sure. I don't really see anything in the console other than the error I don't really know how to read it to see if there is anything else that is wrong with it. Also, it was a 400 error code I don't know if that changes anything. – Peter Apr 29 '22 at 18:13
  • According to [Playlists: insert](https://developers.google.com/youtube/v3/docs/playlists/insert) you have to use a POST HTTP request, so why do you have commented `method: 'POST'` ? – Benjamin Loison Apr 29 '22 at 18:40
  • Check the network panel in devtools, not the console. – wOxxOm Apr 29 '22 at 18:48
  • @wOxxOm ok I found another error when I clicked on the playlist object in the network tab it gave me this error: ` { "error": { "code": 403, "message": "The request is missing a valid API key.", "errors": [ { "message": "The request is missing a valid API key.", "domain": "global", "reason": "forbidden" } ], "status": "PERMISSION_DENIED" } } ` how would I include the API key in my code? Also sorry for the code looking like a mess I'm new to stack overflow and I don't really know how you wrote the code block. – Peter Apr 29 '22 at 19:02
  • @BenjaminLoison I had it commented out because I got another error when I didn't have it commented out it gave me another error. I don't remember exactly what it was, but now I think I know that the problem is that I don't have my API key specified in my code anywhere. I looked on the documentation and it says to use gapi.client.setApiKey but I tried to use gapi before and it said it couldn't recognize gapi. I think this is due to the fact that chrome extensions have limited js capability but I'm sure there is a way to do this I just don't know how. – Peter Apr 29 '22 at 19:14
  • In general we specify the API key in the URL as a GET parameter. So by using `https://www.googleapis.com/youtube/v3/playlists?key=YOUR_API_KEY` instead of `https://www.googleapis.com/youtube/v3/playlists` but I have doubts that it will work. – Benjamin Loison Apr 29 '22 at 19:16
  • I just uncommented `method: 'POST',` and I added my API key to the end of the URL in the fetch method header and I no longer get the error that the API key is missing so I think that it did work however now I still get the original error in the network tab. – Peter Apr 29 '22 at 19:23
  • ok I just looked at it again and now in the console, I'm getting this error { "error": { "code": 400, "message": "'{0}'", "errors": [ { "message": "'{0}'", "domain": "youtube.part", "reason": "unexpectedPart", "location": "part", "locationType": "parameter" } ] } } and in the network, I'm getting the original error – Peter Apr 29 '22 at 19:31
  • As far as I understand [Playlists: Insert](https://developers.google.com/youtube/v3/docs/playlists/insert) the part `"part":["snippet,status"],` isn't required. – Benjamin Loison Apr 29 '22 at 19:47
  • I removed the `"part":["snippet,status"],` and it still gave me the same error so I just put it back. Also I looked it up and I did get [this](https://stackoverflow.com/questions/37183584/youtube-api-unexpected-part-on-update-message-0) thread but they're using java and not javascript. – Peter Apr 29 '22 at 19:56

1 Answers1

0

I finally figured it out! so the first thing that I had to change was I had to add my API key and part=snippet to the fetch URL. Second I looked into the fetch method and I found out that you needed to specify the body of the message with body : JSON.stringify(). so this is the background.js that I ended up with

chrome.identity.getAuthToken({ interactive: true }, function (token) {
    console.log(token);      
    let fetchString = 'https://www.googleapis.com/youtube/v3/playlists?part=snippet&key=<API key>'
    let post = 
    {
      "part": [
        "kind,snippet,channelTitle,status"
      ],
      "kind": "youtube#playlistItem",
      "snippet":{
        "title": "Sample playlist created via API",
        "channelID": "<channel ID>",
        "description": "This is a sample playlist description.",
        "tags": [
          "sample playlist",
          "API call"
        ],
        "defaultLanguage": "en",
      "status": {
          "privacyStatus": "private"
        }
      }
    }
    let fetchOptions = {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${token}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(post),
    }
    
    fetch(fetchString,fetchOptions)
      .then((response) => response.json()) // Transform the data into json
      .then(function (data) {
        console.log(data);//contains the response of the created event
    });
  });
Peter
  • 15
  • 6