27

I want to create a file with content using Google Drive API v3. I have authenticated via OAuth and have the Drive API loaded. Statements like the following work (but produce a file without content):

gapi.client.drive.files.create({
    "name": "settings",
}).execute();

Unfortunately I cannot figure out how to create a file that has a content. I cannot find a JavaScript example using Drive API v3. Are there some special parameters that I need to pass?

For simplicity, assume that I have a String like '{"name":"test"}' that is in JSON format that should be the content of the created file.

3
  • Check this documentation, I know is for v2 but the process is very similar. You would need to change the version in the url to v3 and the parameter according to the v3 ( eg. instead of 'title' use 'name') developers.google.com/drive/v2/reference/files/insert#examples Commented Jan 20, 2016 at 18:22
  • Thanks for the link, but from I think this is somewhat against the spirit of using the library (at least in v3): In no other case do I have to build the request myself. Here I have to choose thinks like I want it to be a 'POST' request and have to concatenate things into a long string delimited by a boundary. I think the point of v3 was to avoid these things and I guess there should be another way to do it. Commented Jan 20, 2016 at 20:43
  • Take a look at upload.js from some devs at Google. I have a modified version for drive v3 api here Commented Jan 17, 2018 at 4:55

5 Answers 5

30

Unfortunately, I have not found an answer using only the google drive api, instead I followed Gerardo's comment and used the google request api. Below is a function that uploads a file to google drive.

var createFileWithJSONContent = function(name,data,callback) {
  const boundary = '-------314159265358979323846';
  const delimiter = "\r\n--" + boundary + "\r\n";
  const close_delim = "\r\n--" + boundary + "--";

  const contentType = 'application/json';

  var metadata = {
      'name': name,
      'mimeType': contentType
    };

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

    var request = gapi.client.request({
        'path': '/upload/drive/v3/files',
        'method': 'POST',
        'params': {'uploadType': 'multipart'},
        'headers': {
          'Content-Type': 'multipart/related; boundary="' + boundary + '"'
        },
        'body': multipartRequestBody});
    if (!callback) {
      callback = function(file) {
        console.log(file)
      };
    }
    request.execute(callback);
}
Sign up to request clarification or add additional context in comments.

6 Comments

If you ever found out how to do this via gapi.client.drive, I'd love to know.
I have file in my folder and upload using URL how to do this ?
How can I then get the contents of this file?
I know it has been a few years since this answer, but just want to add that this worked for me. Thank you so much! Note that you can also upload html (which gets converted into a google doc) in this way.
Thanks. This is great, I got mine working. Incase, it might help someone in future, I found this example in github that does the multipart upload to drive a little more cleaner way - it is in angular though: github.com/googleworkspace/drive-quickeditors/blob/main/web/src/…
|
14

here is the solution with gapi.client.drive,

var parentId = '';//some parentId of a folder under which to create the new folder
var fileMetadata = {
  'name' : 'New Folder',
  'mimeType' : 'application/vnd.google-apps.folder',
  'parents': [parentId]
};
gapi.client.drive.files.create({
  resource: fileMetadata,
}).then(function(response) {
  switch(response.status){
    case 200:
      var file = response.result;
      console.log('Created Folder Id: ', file.id);
      break;
    default:
      console.log('Error creating the folder, '+response);
      break;
    }
});

you'll need to connect/authorise with either of the following scopes

https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/drive.file

EDIT: it is possible to create google files (doc, sheets and so on) by changing the mimeType from application/vnd.google-apps.folder to one of the supported google mime types. HOWEVER, as of now it not possible to upload any content into created files.

To upload files, use the solution provided by @Geminus. Note you can upload a text file or a csv file and set its content type to google doc or google sheets respectively, and google will attempt to convert it. I have tested this for text -> doc and it works.

7 Comments

This creates a folder, not a file, though.
this creates a folder actually, I will post shortly the solution for a file
@DavidGiven, I just edited my answer, you can create a doc/sheet or any other supported file type, but you cannot use gapi.client.drive.files.create to actually upload content.
I did not edit your answer. I edited my comment above (because I misread your code and the comment was wrong).
Ah, yeah! English is a stupid language, isn't it? Anyway, I appreciate the help; I'd still like an actual solution here...
|
13

Using gapi.client.drive, it is not possible to upload file content. You can only upload metadata.

Instead it is recommended to work directly with the Google REST API. This solution uses a FormData object to build the multipart form body, which simplifies the implementation, and gapi.auth.getToken() to retrieve the required access token. The solution also works with Google shared drives:

var fileContent = "sample text"; // fileContent can be text, or an Uint8Array, etc.
var file = new Blob([fileContent], {type: "text/plain"});
var metadata = {
    "name": "yourFilename",
    "mimeType": "text/plain",
    "parents": ["folder id or 'root'"], // Google Drive folder id
};

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

fetch("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&supportsAllDrives=true", {
    method: 'POST',
    headers: new Headers({ 'Authorization': 'Bearer ' + accessToken }),
    body: form,
}).then((res) => {
    return res.json();
}).then(function(val) {
    console.log(val);
});

2 Comments

I am a bit late to the party, but do you have a source for the part where it's not possible to upload file content with gapi? I am looking at the documentation and am confused? @mario-varchmin
@bouffelec I keep only working code, not code, that is not working. I am not saying that an upload is not possible with gapi, in fact my proposed solution is using gapi. What I meant is that this was not possible (at the time of writing) using the Google API Client Library for JavaScript, which Geminus was having problems with.
-1

this works fine usin v3:

        var fileMetadata = {
            'name' : 'MaxBarrass',
            'mimeType' : 'application/vnd.google-apps.folder'
        };

        gapi.client.drive.files.create({
            resource: fileMetadata,
            fields: 'id'
        }).execute(function(resp, raw_resp) {
            console.log('Folder Id: ', resp.id);
        });

3 Comments

this appears to be for creating a folder, not a file.
yeah you can make folder with it as... it does say "files.create" in "gapi.client.drive.files.create", its all nodes in the end so and they are more like files than folders...
I realise that, but the question specifically asked about creating files. So it's hard to see why an example showing the creation of a folder would be useful.
-1
/*  Now to create a new file */ 
function insertNewFile(folderId) 
{   
    var content = " ";  
    var FolderId = ""; 
    var contentArray = new Array(content.length);
    for (var i = 0; i < contentArray.length; i++) 
    {
        contentArray[i] = content.charCodeAt(i);
    }
    var byteArray = new Uint8Array(contentArray);
    var blob = new Blob([byteArray], {type: 'text/plain'});     
    insertFile(blob, fileInserted, folderId); 
} 
function fileInserted(d) 
{   
    setPercent("100");   
    var FI = FolderId;  
    if(FI !== myRootFolderId)
    {           
        insertFileIntoFolder(FI, d.id);         
        removeFileFromFolder(d.parents[0].id,d.id);     
    }   
    openFile(d.id); 
} 
function insertFileIntoFolder(folderId, fileId) 
{   
    var body = {'id': folderId};   
    var request = gapi.client.drive.parents.insert({
        'fileId': fileId,
        'resource': body   });   
    request.execute(function(resp) { }); 
 } 

Source: https://gist.github.com/mkaminsky11/8624150

1 Comment

You missed out insertFile(), which is actually doing the work; it's the same as @Geminus' answer above, using an explicit post to upload the data.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.