Search code examples
node.jsgoogle-chrome-extensiongoogle-drive-api

Find or create folder in Google Drive


Context: Building on the wonderful Screenity Chrome Extension:

  • Existing: Functionality to save to Google Drive
  • Addition: I'm trying to save to a specific folder (eg, "Screenity"), and create that folder if it doesn't currently exist. (This makes sharing much easier, since I can share an entire folder with my team, rather than each individual video.)

Problem: I've been able to successfully create a new folder with the desired name, but I've been unable to locate said folder even after having created it.

This bit of node.js should GET my folder id, but instead it's simply returning "undefined":

function saveDrive() {
        chrome.identity.getAuthToken({ 'interactive': true }, function(token) {
            if (!token) {
              return;
            }

            var metadata = {
                q: "mimeType = 'application/vnd.google-apps.folder' and name = 'TESTSCREENITYFOLDER'"
            };
            var form = new FormData();
            form.append('metadata', new Blob([JSON.stringify(metadata)], {type: 'application/json'}));

            // Upload to Drive
            var xhr = new XMLHttpRequest();
            xhr.open('GET', 'https://www.googleapis.com/drive/v3/files');
            xhr.setRequestHeader('Authorization', 'Bearer ' + token);
            xhr.responseType = 'json';
            xhr.onload = () => {
                var folderId = xhr.response.files.data.id;
                
                // Open folder in Drive in a new tab
                chrome.tabs.create({
                     url: "https://drive.google.com/drive/u/0/folders/"+folderId
                });
            };
            xhr.send(form);
        });
    }

On the other hand, this is working perfectly for creating a folder:

function saveDrive() {
        chrome.identity.getAuthToken({ 'interactive': true }, function(token) {
            if (!token) {
              return;
            }

            var folderName = "Screenity"
            var metadata = {
                name: [folderName],
                mimeType: 'application/vnd.google-apps.folder'
            };

            var form = new FormData();
            form.append('metadata', new Blob([JSON.stringify(metadata)], {type: 'application/json'}));

            var xhr = new XMLHttpRequest();
            xhr.open('POST', 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart');
            xhr.setRequestHeader('Authorization', 'Bearer ' + token);
            xhr.responseType = 'json';
            xhr.onload = () => {
                var folderId = xhr.response;
                $("#share span").html("Save to Drive");
                $("#share").css("pointer-events", "all");
                
                // Open file in Drive in a new tab
                chrome.tabs.create({
                     url: "https://drive.google.com/drive/u/0/folders/"+folderId
                });
            };
            xhr.send(form);
        });
    }

Any idea what I'm getting wrong in the first code chunk, where I'm trying to GET the ID of a specifically named folder?


Solution

  • Modification points:

    • At the method of "Files: list" of Drive API v3, the GET method is used. So the request body of form is not used in the request. In this case, the search query of q is required to be used as the query parameter.

    When above points are reflected to your script, it becomes as follows.

    From:

    var metadata = {
        q: "mimeType = 'application/vnd.google-apps.folder' and name = 'TESTSCREENITYFOLDER'"
    };
    var form = new FormData();
    form.append('metadata', new Blob([JSON.stringify(metadata)], {type: 'application/json'}));
    
    // Upload to Drive
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'https://www.googleapis.com/drive/v3/files');
    xhr.setRequestHeader('Authorization', 'Bearer ' + token);
    xhr.responseType = 'json';
    xhr.onload = () => {
        var folderId = xhr.response.files.data.id;
        
        // Open folder in Drive in a new tab
        chrome.tabs.create({
             url: "https://drive.google.com/drive/u/0/folders/"+folderId
        });
    };
    xhr.send(form);
    

    To:

    const url = 'https://www.googleapis.com/drive/v3/files?q=' + encodeURIComponent("mimeType = 'application/vnd.google-apps.folder' and name = 'TESTSCREENITYFOLDER'");
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url);
    xhr.setRequestHeader('Authorization', 'Bearer ' + token);
    xhr.responseType = 'json';
    xhr.onload = () => {
      var res = xhr.response.files;
      if (res.length > 0) {
        var folderId = res[0].id;
        console.log(folderId);  // You can check the retrieved folder ID here.
    
        // Open folder in Drive in a new tab
        chrome.tabs.create({
          url: "https://drive.google.com/drive/u/0/folders/"+folderId
        });
      } else {
        console.log("The folder of 'TESTSCREENITYFOLDER' was not found.");
      }
    };
    xhr.send();
    

    Note:

    • In this modification, it supposes that your token can be used for using the method of "Files: list". Please be careful this.
    • When there are several folders with the same folder names in your Google Drive, you can check with var res = xhr.response.files.

    Reference: