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 scopeshttps://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 withmultipart/form-data
usingfetch
of Javascript. In this case, the access token is retrieved bygapi.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 withmultipart/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
Why Threre Is No Way to Download File Using Ajax Request
Sampling a Random Subset from an Array
Angularjs Communication Between Directives
Regular Expression to Match A, Ab, Abc, But Not Ac. ("Starts With")
Javascript: Dynamically Creating Variables for Loops
Why Use Redux Over Facebook Flux
Differencebetween JavaScript and Ecmascript
How to Auto-Reload a Chrome Extension I'm Developing
How to Add My Own Methods to HTMLelement Object
How to Change the Pop-Up Position of the Jquery Datepicker Control
How to Execute a Function on Pressing the Enter Key in an <Input> Field
Google Spreadsheet Script - How to Transpose/Rotate Multi-Dimensional Array
How to Replace Last Occurrence of Characters in a String Using JavaScript
Pass Parameter with Python Flask in External JavaScript
How to Load All Files in a Directory Using Webpack Without Require Statements