2

I have been trying to upload a simple text file that holds a user's email and name to a folder that is in the root of my drive. I create the folder and then upload the file to that folder using its ID.

Everything works fine except for the config file not being added to the new folder. It just sits in the root along with the new folder.

I have looked over many of the questions related to this and have tried solutions from almost all of them. This question in particular (Insert a file to a particular folder using google-drive-api) seems like my exact problem. But as you can see, I implemented his change, and I still have the same problem.

Below is the function that is called to do this.

/**
 * Creates the correct directory structure and a config file in the user's drive;
 */
function setupDrive(email, name) {
    // TODO create CSR folder and config file inside
    createFolder('CSR');
    uploadConfig(email, name);
    checkAuth();
}

This is the createFolder() function.

/**
 * Creates a folder with the given name in the drive;
 */
function createFolder(dirName) {
    var metadata = {
        'name' : dirName,
        'mimeType' : 'application/vnd.google-apps.folder'
    };

    var request = gapi.client.request({
        'path': '/drive/v3/files',
        'method': 'POST',
        'body': JSON.stringify(metadata)});
    request.execute();
}

This is the uploadConfig() function.

/**
 * Uploads a config file to the CSR folder with the given email and name;
 */
function uploadConfig(email, name) {    
    var request = gapi.client.request({
        'path': '/drive/v3/files',
        'method': 'GET',
        'q': 'name="CSR", trashed="false", mimeType="application/vnd.google-apps.folder"',
        'fields': "nextPageToken, files(id, name)"
    });

    request.execute(function (results) {
        var files = results.files;
        var csrID = '';
        if (files && files.length > 0) {
            csrID = files[0].id;
        }
        uploadFile('config', email + '\n' + name, 'plain', csrID);
    });
}

And finally, the uploadFile() function.

/**
 * Uploads either a plain text file or a CSV file to the user's Google Drive in the CSR folder;
 */
function uploadFile(fileName, fileContent, mimeType, parentID) {
    console.log(parentID); //check that a parentID is being passed in
    var auth_token = gapi.auth.getToken().access_token;

    var metaType = '';
    var bodyType = '';
    if (mimeType == 'csv') {
        metaType = 'application/vnd.google-apps.spreadsheet';
        bodyType = 'text/csv\r\n\r\n';
    } else if (mimeType == 'plain') {
        metaType = 'text/plain\r\n\r\n';
        bodyType = 'text/plain\r\n\r\n';
    }

    const boundary = '-------314159265358979323846';
    const delimiter = "\r\n--" + boundary + "\r\n";
    const close_delim = "\r\n--" + boundary + "--";

    var metadata = {
        'name': fileName,
        'mimeType': metaType,
        'parents':[{'id': parentID}]
    };  

    var multipartRequestBody =
        delimiter +  'Content-Type: application/json\r\n\r\n' +
        JSON.stringify(metadata) +
        delimiter + 'Content-Type: ' + bodyType +
        fileContent +
        close_delim;

    var request = gapi.client.request({ 
        'path': '/upload/drive/v3/files',
        'method': 'POST',
        'params': {'uploadType': 'multipart'},
        'headers': { 'Content-Type': 'multipart/form-data; boundary="' + boundary + '"', 'Authorization': 'Bearer ' + auth_token, },
        'body': multipartRequestBody 
    })

    request.execute(function (file) {
        console.log("Wrote to file " + file.name + " id: " + file.id); 
        }); 
}

Any help is greatly appreciated, and I apologize for so much code!

EDIT: I was able to get it to work when I did everything through REST V2. However, I'd still be interested in seeing a solution that would allow me to use V3.

Community
  • 1
  • 1
stparham
  • 475
  • 5
  • 7

2 Answers2

0

I don't see any error with your code as compared with this related SO post. It stated that v2 process is very similar with v3. You already changed the version in the url to v3 and the parameter according to the v3. Also stated in this thread, be noted that in v3, there is no longer a parents collection. Instead, you get the parents property by doing a files.get with the child's ID. Ideally, you would use the fields parameter to restrict the response to just the parent(s). This SO answer might also help wherein the OP only used parents: ['parentID'] in the metadata.

Community
  • 1
  • 1
abielita
  • 13,147
  • 2
  • 17
  • 59
  • Correct. You sould use parents field this way: parents: [ folderId ] as in the node.js example from here: https://developers.google.com/drive/v3/web/folder – Skalár Wag Jan 19 '17 at 15:29
0

This works fine with V3

function createFile(){
const boundary = '-------314159265358979323846';
const delimiter = "\r\n--" + boundary + "\r\n";
const close_delim = "\r\n--" + boundary + "--";

var fileContent = 'It works :)';

var metadata = {
    'name': 'myFile',
    'mimeType': 'text/plain\r\n\r\n'
};

var multipartRequestBody = delimiter +  'Content-Type: application/json\r\n\r\n' + JSON.stringify(metadata) + delimiter + 'Content-Type: ' + 'text/plain\r\n\r\n' + fileContent + close_delim;

gapi.client.request({
    'path': '/upload/drive/v3/files',
    'method': 'POST',
    'params': {
        'uploadType': 'multipart'
    },
    'headers': {
        'Content-Type': 'multipart/related; boundary="' + boundary + '"'
    },
    'body': multipartRequestBody
}).then(function(response){
    console.log(response);
});
}
  • 7
    You could improve the quality of your answer by also explaining what your code does, the difference to OPs code and so on. Explanation is always more helpful than just a bunch of code lines :) – Zabuzard Jul 28 '17 at 15:09