Create File with Google Drive API V3 (Javascript)

Create File with Google Drive Api v3 (javascript)

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.

Google Drive API V3 Javascript - Create File with Content

How about this sample script? In my environment, although gapi.client.drive.files.create() can create an empty file on Google Drive, it cannot directly upload files including contents. I think that this might not be able to upload files and metadata with the multipart/related, although this might be resolved by the future update. So now, as one of workarounds, I use XMLHttpRequest.

Before you use this sample script, please confirm the following points.

  • In your situation, you have already been able to create files using gapi. In my script, the access token is retrieved using gapi.
  • When you use this script, please set fileContent and metadata.

Sample script :

In this sample script, a text file including contents is created under a folder.

var fileContent = 'sample text'; // As a sample, upload a text file.
var file = new Blob([fileContent], {type: 'text/plain'});
var metadata = {
'name': 'sampleName', // Filename at Google Drive
'mimeType': 'text/plain', // mimeType at Google Drive
'parents': ['### folder ID ###'], // Folder ID at Google Drive
};

var accessToken = gapi.auth.getToken().access_token; // Here gapi is used for retrieving the access token.
var form = new FormData();
form.append('metadata', new Blob([JSON.stringify(metadata)], {type: 'application/json'}));
form.append('file', file);

var xhr = new XMLHttpRequest();
xhr.open('post', 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id');
xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
xhr.responseType = 'json';
xhr.onload = () => {
console.log(xhr.response.id); // Retrieve uploaded file ID.
};
xhr.send(form);

Request body :

In this script, form is as follows. This is sent to Google Drive using the create method of Drive API.

------WebKitFormBoundaryxX0XmxgooMjdUECR
Content-Disposition: form-data; name="metadata"; filename="blob"
Content-Type: application/json

{"name":"sampleName","mimeType":"text/plain","parents":["#####"]}
------WebKitFormBoundaryxX0XmxgooMjdUECR
Content-Disposition: form-data; name="file"; filename="blob"
Content-Type: text/plain

sample text
------WebKitFormBoundaryxX0XmxgooMjdUECR--

In my environment, I confirmed that this works fine. But if this didn't work in your environment, I'm sorry.

Google Drive API Not Writing Body To File

You are mentioning that you are using the Google APIs for browser, and not node.js.

I would recommend to send the request directly against the Google REST API, as gapi.client.drive.create() appears to have problems sending the actual binary file (while sending metadata appears to work). Look here, for example: https://stackoverflow.com/a/53841879/7821823, https://stackoverflow.com/a/35182924/7821823 or https://stackoverflow.com/a/68595887/7821823

You can send the data as a blob and create the request using the FormData class.

  async upload(blob, name, mimeType, parents = ["root"]) {
const metadata = { name, mimeType, parents };
const form = new FormData();
form.append("metadata", new Blob([JSON.stringify(metadata)], { type: "application/json" }));
form.append("file", blob);
return fetch("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&supportsAllDrives=true", {
method: "POST",
headers: new Headers({ Authorization: `Bearer ${gapi.auth.getToken().access_token}` }),
body: form,
});
}

I have not tested if you can send a String instead of a Blob, but you can easily create a Blob from a String:

const content = "this is some content";
const blob = new Blob([content], { type: 'text/plain' });

Google Drive API: How to create a file in appDataFolder?

I believe the reason for this error is that you are only using the scope to access the appdata folder, but not the scope to create files. Accessing the app data folder and creating files are two different things. According to your code, you are trying to create a file in the appdata folder.

I suggest you to include both scopes:

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

If you are not using incremental authorization, make sure to revoke access and reauthorize again.

Reference: https://developers.google.com/drive/api/v3/about-auth#OAuth2Authorizing

Uploading file via Google Drive API with simple upload (uploadType=media)

The request body should consist of a form that contains both metadata and the file, like so:

const metadata = {
"name": "yourFilename",
"mimeType": "text/plain", // whatever is appropriate in your case
"parents": ["folder id or 'root'"], // Google Drive folder id
};

const form = new FormData();
form.append('metadata', new Blob([JSON.stringify(metadata)], { type: 'application/json' }));
form.append('file', file); // file could be a blob or similar

You might also need to add an uploadType parameter to your path property. The multipart value works even for simple uploads.

See also here: https://stackoverflow.com/a/68595887/7821823

How I can upload file to google drive with google drive api?

Issue and workaround:

  • When I tested gapi.client.drive.files.create, it seems that although this method can create new file with the metadata, the file content cannot be included. So in this answer, in order to upload a file by including the file metadata, I would like to propose to upload a file with multipart/form-data using fetch of Javascript. In this case, the access token is retrieved by gapi.auth.getToken().access_token.

  • Unfortunately, from your script, I couldn't understand about e.target. So in this sample script, I would like to propose the sample script for uploading a file, which is retrieved from the input tag, with the metadata.

Sample script:

HTML side:

<input type="file" id="files" name="file">

Javascript side:

const files = document.getElementById("files").files;

const file = files[0];
const fr = new FileReader();
fr.readAsArrayBuffer(file);
fr.onload = (f) => {
const fileMetadata = {
name: file.name,
parents: this.currentDirectoryId ? [this.currentDirectoryId] : [] // This is from your script.
}
const form = new FormData();
form.append('metadata', new Blob([JSON.stringify(fileMetadata)], {type: 'application/json'}));
form.append('file', new Blob([new Uint8Array(f.target.result)], {type: file.type}));
fetch('https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart', {
method: 'POST',
headers: new Headers({'Authorization': 'Bearer ' + gapi.auth.getToken().access_token}),
body: form
}).then(res => res.json()).then(res => console.log(res));
};
  • In this script, the file retrieved from input tag is uploaded to Google Drive with multipart/form-data.

Note:

  • In this script, it supposes that your authorization script can be used for uploading a file to Google Drive. Please be careful this.
  • In this answer, as a sample script, the file is uploaded with uploadType=multipart. In this case, the maximum file size is 5 MB. Please be careful this. When you want to upload the file with the large size, please check the resumable upload. Ref

References:

  • Using Fetch
  • Files: create
  • Upload file data
  • Perform a resumable upload

Google Drive Api v3 Create Shared File

There's no shared attribute on the request body of create. This has been discussed

Its discussed int he Share Files section of the Drive API documentation, you'll need to call drive.permissions.create and set the appropriate permission of the account you'll share with.

I tested this on the API Explorer as well, and it works.

var fileId = '1sTWaJ_j7PkjzaBWtNc3IzovK5hQf21FbOw9yLeeLPNQ';
drive.permissions.create({
resource: {
'type': 'user',
'role': 'writer',
'emailAddress': 'example@appsrocks.com'
},
fileId: fileId,
fields: 'id',
}, function(err, res) {
if (err) {
// Handle error
console.log(err);
} else {
console.log('Permission ID: ', res.id)
drive.permissions.create({
resource: {
'type': 'domain',
'role': 'reader',
'domain': 'appsrocks.com'
},
fileId: fileId,
fields: 'id',
}, function(err, res) {
if (err) {
// Handle error
console.log(err);
} else {
console.log('Permission ID: ', res.id)
}
});
}
});


Related Topics



Leave a reply



Submit