Google Drive API uploading a file to team drive in

2019-04-07 00:03发布

I have been having some issues with the google drive API and teamdrives. I can't for the life of me, figure out how to upload a file to team drive.

I'm able to upload a file to my personal drive, using this function:

 function insertFile(fileData, callback, desc) {
                const boundary = '-------314159265358979323846';
                const delimiter = "\r\n--" + boundary + "\r\n";
                const close_delim = "\r\n--" + boundary + "--";

                var reader = new FileReader();
                reader.readAsBinaryString(fileData);
                reader.onload = function(e) {
                    var contentType = fileData.type || 'application/octet-stream';
                    var metadata = {
                        'title': fileData.name,
                        'mimeType': contentType,
                        'description': desc,
                        "parents": [
                            {
                                "id": "1hBdtlAFrL2zljEcq2QVbqj14v_-SJarc"
                            }
                        ]

                    };

                    var base64Data = btoa(reader.result);
                    var multipartRequestBody =
                        delimiter +
                        'Content-Type: application/json\r\n\r\n' +
                        JSON.stringify(metadata) +
                        delimiter +
                        'Content-Type: ' + contentType + '\r\n' +
                        'Content-Transfer-Encoding: base64\r\n' +
                        '\r\n' +
                        base64Data +
                        close_delim;

                    var request = gapi.client.request({
                        'path': '/upload/drive/v2/files',
                        'method': 'POST',
                        'params': {'uploadType': 'multipart'},
                        'headers': {
                            'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'
                        },
                        'body': multipartRequestBody


                    });
                    if (!callback) {
                        callback = function(file) {
                            console.log(file)
                        };
                    }
                    request.execute(callback);
                }
            }

I'm not sure how I can adapt this for Team Drives, I have been able to view files in team drives. I do have the team drive ID, as well as the folderID that I would like to insert the files into.

An example in javascript would be greatly appreciated, I can't seem to find one.

EDIT:

I'm able to make new files on team drives by adding the teamdrivesupport boolean, I can even make new files, however I'm unsure how to upload the file data using:

 gapi.client.drive.files.create({
                'supportsTeamDrives':"true",
                'teamDriveId': 'TEAMDRIVEID',
                  "name" : 'test',
                  "mimeType" : "application/vnd.google-apps.folder",
                    'parents': ['FILEID']

}).then(function(response) {
               console.log(response)
            });

I've read through all the docs, and tried countless different ways, but no luck. Any help will be greatly appreciated.

4条回答
混吃等死
2楼-- · 2019-04-07 00:11

After trying many different ways, I was unable to find a direct solution to this problem. Instead, I decided to use my personal drive and move the files across to to my team drive.

It is possible to move a file from your personal drive to your team drive, but you cannot move a folder. So first I made the folders on my team drive with the following code:

gapi.client.drive.files.create({
                'supportsTeamDrives':"true",
                'teamDriveId': 'teamID',
                  "name" : 'test',
                  "mimeType" : "application/vnd.google-apps.folder",
                    'parents': ['folderID']

}).then(function(response) {
               console.log(response)
            }

);

This will make a empty folder on your team drive.

Then you can upload a file to your personal drive using this:

function insertFile(fileData, callback, desc, folderID) {
                const boundary = '-------314159265358979323846';
                const delimiter = "\r\n--" + boundary + "\r\n";
                const close_delim = "\r\n--" + boundary + "--";

                var reader = new FileReader();
                reader.readAsBinaryString(fileData);
                reader.onload = function(e) {
                    var contentType = fileData.type || 'application/octet-stream';
                    var metadata = {
                        'title': fileData.name,
                        'mimeType': contentType,
                        'description': desc,
                        "parents": [
                            {
                                "id": folderID
                            }
                        ]

                    };

                    var base64Data = btoa(reader.result);
                    var multipartRequestBody =
                        delimiter +
                        'Content-Type: application/json\r\n\r\n' +
                        JSON.stringify(metadata) +
                        delimiter +
                        'Content-Type: ' + contentType + '\r\n' +
                        'Content-Transfer-Encoding: base64\r\n' +
                        '\r\n' +
                        base64Data +
                        close_delim;

                    var request = gapi.client.request({
                        'path': '/upload/drive/v2/files',
                        'method': 'POST',
                        'params': {'uploadType': 'multipart'},
                        'headers': {
                            'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'
                        },
                        'body': multipartRequestBody

                    });
                    if (!callback) {
                        callback = function(file) {
                            console.log(file)
                        };
                    }
                    request.execute(callback);
                }
            }

This will upload the file to your personal drive, you can then get the file ID from the response and change its parents to move it onto the team drive:

gapi.client.drive.files.update({
      fileId: fileId,
        'supportsTeamDrives':"true",
                    'corpora':"teamDrive",
                    'teamDriveId': teamdriveID,
                     addParents: folderID,
                    removeParents: previousParents,
                    fields: 'id, parents'
    }).then(function(response) {           
                console.log(response.result.parents)                
            });

This will then move the file you uploaded yo your personal drive, into the folder you created on your team drive.

I know this is a sloppy solution, but I couldn't find another work around to date.

I hope someone finds this useful.

EDIT: The solution to this, written as async functions

      /* This function reads the filedata asynchronously for insert*/

        async function readFile(file){
                    let reader = new FileReader();
                    reader.readAsBinaryString(file);
                    return await new Promise(resolve => {
                        reader.onload = e => {
                            resolve(btoa(e.target.result));
                        };

                    });
                }

    /* This function inserts the file into the root of your personal drive, again this happens asynchronously */
    async function insertFile(fileData) {
                    try {
                        const boundary = '-------314159265358979323846';
                        const delimiter = "\r\n--" + boundary + "\r\n";
                        const close_delim = "\r\n--" + boundary + "--";

                        let base64Data = null;
                        await readFile(fileData).then(function(e) {
                            base64Data = e;
                        });

                        var contentType = fileData.type || 'application/octet-stream';
                        var metadata = {
                            'title': fileData.name,
                            'mimeType': contentType,                

                            "parents": [
                            {
                                "id": 'root'
                            }
                        ]

                        };

                        var multipartRequestBody =
                            delimiter +
                            'Content-Type: application/json\r\n\r\n' +
                            JSON.stringify(metadata) +
                            delimiter +
                            'Content-Type: ' + contentType + '\r\n' +
                            'Content-Transfer-Encoding: base64\r\n' +
                            '\r\n' +
                            base64Data +
                            close_delim;

                        const fulfilledValue = await gapi.client.request({
                            'path': '/upload/drive/v2/files',
                            'method': 'POST',
                            'params': {'uploadType': 'multipart'},
                            'headers': {
                                'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'
                            },
                            'body': multipartRequestBody

                        });
                        let result = await fulfilledValue.result;
                        return result;

                    }
                    catch (rejectedValue) {
                        console.log("Failed to insert file into folder", rejectedValue);
                    }
                }

/*This function ties everything together and moves the file to your team drive, and removes it from your personal drive, you need to provide the file data, team drive ID, and the ID of the folder on the team drive, again this is asynchronous*/

 async  function insertTeamDrive(file, teamdriveID, folderID) {
                try {

                    let id = null;
                    await insertFile(file).then(function(e) {               
                        id = e.id;
                    });

                    await gapi.client.drive.files.update({
                        fileId: id,
                        'supportsTeamDrives':"true",
                        'corpora':"teamDrive",
                        'teamDriveId': teamdriveID,
                        addParents: folderID,
                        removeParents: 'root',
                        fields: 'id, parents'
                    }).then(function(response) {           
                        console.log(response.result)                
                    });

                }
                catch (rejectedValue) {
                    console.log("Failed to insert into team drive", rejectedValue);
                }
            }

Calling insertTeamDrive will upload the given file to the folder specified on the given team drive.

查看更多
戒情不戒烟
3楼-- · 2019-04-07 00:13

You have put the supportsTeamDrives:"true" in the wrong place.

the docs https://developers.google.com/drive/api/v2/reference/files/insert specify that it needs to be a query parameter.

So simply change your request query params to this:

'params': {'uploadType': 'multipart', supportsTeamDrives: 'true' }

So the whole request becomes:

var request = gapi.client.request({
  'path': '/upload/drive/v2/files',
  'method': 'POST',
  'params': {'uploadType': 'multipart', 'supportsTeamDrives': 'true' },
  'headers': {
    'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'
  },
  'body': multipartRequestBody
});
查看更多
何必那么认真
4楼-- · 2019-04-07 00:29

Try this one from Google uploads
Also read this: Simple upload

var fileMetadata = {
      'name': 'photo.jpg'
    };
    var media = {
      mimeType: 'image/jpeg',
      body: fs.createReadStream('files/photo.jpg')
    };
    drive.files.create({
      resource: fileMetadata,
      media: media,
      fields: 'id'
    }, function (err, file) {
      if (err) {
        // Handle error
        console.error(err);
      } else {
        console.log('File Id: ', file.id);
      }
    });

查看更多
何必那么认真
5楼-- · 2019-04-07 00:30

You can refer to the documentation how you can use the file picker with team drives.

There is an available example, this one is an image selector or uploader page.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>Google Picker Example</title>

    <script type="text/javascript">

    // The Browser API key obtained from the Google API Console.
    // Replace with your own Browser API key, or your own key.
    var developerKey = 'xxxxxxxYYYYYYYY-12345678';

    // The Client ID obtained from the Google API Console. Replace with your own Client ID.
    var clientId = "1234567890-abcdefghijklmnopqrstuvwxyz.apps.googleusercontent.com"

    // Replace with your own project number from console.developers.google.com.
    // See "Project number" under "IAM & Admin" > "Settings"
    var appId = "1234567890";

    // Scope to use to access user's Drive items.
    var scope = ['https://www.googleapis.com/auth/drive'];

    var pickerApiLoaded = false;
    var oauthToken;

    // Use the Google API Loader script to load the google.picker script.
    function loadPicker() {
      gapi.load('auth', {'callback': onAuthApiLoad});
      gapi.load('picker', {'callback': onPickerApiLoad});
    }

    function onAuthApiLoad() {
      window.gapi.auth.authorize(
          {
            'client_id': clientId,
            'scope': scope,
            'immediate': false
          },
          handleAuthResult);
    }

    function onPickerApiLoad() {
      pickerApiLoaded = true;
      createPicker();
    }

    function handleAuthResult(authResult) {
      if (authResult && !authResult.error) {
        oauthToken = authResult.access_token;
        createPicker();
      }
    }

    // Create and render a Picker object for searching images.
    function createPicker() {
      if (pickerApiLoaded && oauthToken) {
        var view = new google.picker.View(google.picker.ViewId.DOCS);
        view.setMimeTypes("image/png,image/jpeg,image/jpg");
        var picker = new google.picker.PickerBuilder()
            .enableFeature(google.picker.Feature.NAV_HIDDEN)
            .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
            .setAppId(appId)
            .setOAuthToken(oauthToken)
            .addView(view)
            .addView(new google.picker.DocsUploadView())
            .setDeveloperKey(developerKey)
            .setCallback(pickerCallback)
            .build();
         picker.setVisible(true);
      }
    }

    // A simple callback implementation.
    function pickerCallback(data) {
      if (data.action == google.picker.Action.PICKED) {
        var fileId = data.docs[0].id;
        alert('The user selected: ' + fileId);
      }
    }
    </script>
  </head>
  <body>
    <div id="result"></div>

    <!-- The Google API Loader script. -->
    <script type="text/javascript" src="https://apis.google.com/js/api.js?onload=loadPicker"></script>
  </body>
</html>
查看更多
登录 后发表回答