I am doing a web app using javascript and j query.
I want to take notes from a input text field from my web page and want to save that content in a text file on Gdrive.
I am able to sign in and authorize the user but cant able to save that content to gdrive.
Can any body help me, how to create a file using javascript, or how to upload it to g drive.
I am following the google drive sdk documentation.
https://developers.google.com/drive/manage-uploads
These methods are used to upload a file to gdrive from local machine. I dont have a file.
I have a variable which is a string of words. i want to save them as a text file in g drive.
/**
* Start the file upload.
*
* #param {Object} evt Arguments from the file selector.
*/
function uploadFile(evt) {
gapi.client.load('drive', 'v2', function() {
var file = evt.target.files[0];
insertFile(file);
});
}
/**
* Insert new file.
*
* #param {File} fileData File object to read data from.
* #param {Function} callback Function to call when the request is complete.
*/
function insertFile(fileData, callback) {
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
};
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);
}
}
Thankyou.
from https://developers.google.com/drive/v2/reference/files/insert
/**
* Insert new file.
*
* #param {File} fileData File object to read data from.
* #param {Function} callback Function to call when the request is complete.
*/
function insertFile(fileData, callback) {
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.fileName,
'mimeType': contentType
};
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);
}
}
Related
I am trying to upload files to Google Drive through the API provided for the product. However, I think there is a problem with the encoding - in particular, the FileReader.readAsText() function.
I tried adding the optional parameter for encoding to make it look like r.readAsText(f,'ANSI') but it seems to not work.
The readAsText() function defaults to UTF-8 encoding for some weird reason. When I try to upload image files with UTF-8 encoding, they're corrupted and do not open properly.
function readFile(evt) {
var fData = [];
var f = evt.target.files[0];
if (f) {
var r = new FileReader();
r.readAsText(f);
fData.unshift(f.name, f.type);
var myInt = setInterval(function() {
if (r.readyState == 2) {
fData.push(r.result);
uploadFiles(fData);
clearInterval(myInt);
}
}, 50);
} else {
alert("Failed to load file");
}
}
function uploadFiles(dataArray,callback) {
const boundary = '-------314159265358979323846';
const delimiter = "\r\n--" + boundary + "\r\n";
const close_delim = "\r\n--" + boundary + "--";
const contentType = 'application/json';
var metadata = {
'name': dataArray[0],
'mimeType': dataArray[1]
};
var multipartRequestBody =
delimiter +
'Content-Type: application/json\r\n\r\n' +
JSON.stringify(metadata) +
delimiter +
'Content-Type: ' + contentType + '\r\n\r\n' +
dataArray[2] +
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);
}
document.getElementById('upFile').addEventListener('change', readFile, false);
You want to upload files to Google Drive using Drive API by JavaScript. How about this workaround? In this workaround, the file is converted to base64 and uploaded to Google Drive.
Modification points :
Use readAsDataURL() instead of readAsText().
Define data as base64 in request body.
Modified script :
Please modify 2 parts as follows.
1. From :
r.readAsText(f);
1. To :
r.readAsDataURL(f);
2. From :
var multipartRequestBody =
delimiter +
'Content-Type: application/json\r\n\r\n' +
JSON.stringify(metadata) +
delimiter +
'Content-Type: ' + contentType + '\r\n\r\n' +
dataArray[2] +
close_delim
2. To :
var multipartRequestBody =
delimiter +
'Content-Type: application/json\r\n\r\n' +
JSON.stringify(metadata) +
delimiter +
'Content-Type: ' + contentType + '\r\n' + // Modified
'Content-Transfer-Encoding: base64\r\n\r\n' + // Added
dataArray[2].split(",")[1] + // // Modified
close_delim
Reference :
FileReader.readAsDataURL()
Also I have experienced the same situation with you. At that time, I resolved this using base64.
I've had a working application but today it has decided to break so I assume Google has made some sort of changes. CSV data is passed to my function which then uploads the file and converts it to google sheet format (well this is what it did do)
I'm working with JS and there are no examples of in the docs on how to do it with V3. I have read that instead of running 'conver':true in the request paramters in the client you just specify your desired mimeType and the API will do that for you.
here is where it states that in the docs ->
https://developers.google.com/drive/v3/web/migration#other_changes
Imports to Google Docs formats are now requested by setting the appropriate target mimeType in the resource body, rather than specifying ?convert=true.
here is the code I am looking at now. It is returning a 400 error whenever I leave the mimeType as 'application/vnd.google-apps.spreadsheet'
gapiService.uploadCSVToGoogleSheet =function(data, sheetTitle) {
// create file
cnsl("in gapiService.uploadCSVToGoogleSheet()!!!", "start");
gapi.client.load('drive', 'v3',
upload
);
function upload (){
var fileData = new Blob(data, {type: "text/csv-creation", fileName: "testName"});
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) {
console.log("loaded reader ");
console.log(contentType);
var metadata = {
'name': sheetTitle + "-" + getCurrentDate(),
'mimeType': 'application/vnd.google-apps.spreadsheet'
};
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;
// POST INFO
var request = gapi.client.request({
'path': '/upload/drive/v3/files',
'method': 'POST',
'params': {
'uploadType': 'multipart'
// 'convert': true
},
'headers': {
'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'
},
'body': multipartRequestBody
});
request.execute(gapiService.afterFileInsert);
} //endof reader onload
}
function getCurrentDate() {
console.log("in get GetCurrentDATE");
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth() + 1; //January is 0!
var yyyy = today.getFullYear();
if (dd < 10) {
dd = '0' + dd
}
if (mm < 10) {
mm = '0' + mm
}
today = mm + '_' + dd + '_' + yyyy;
return today;
};
// console.log(fileData, null, 0);
};
`
You received error 400 if a required field or parameter has not been provided, the value supplied is invalid, or the combination of provided fields is invalid.
This error also can be thrown when trying to add a duplicate parent to a Drive item. It can also be thrown when trying to add a parent that would create a cycle in the directory graph.
For more information on how to upload Google sheet formatting in Google Drive, check these related SO questions:
Upload CSV to Google Drive Spreadsheet using Drive v2 API
Convert and create a Google Drive Spreadsheet from a local CSV file via the Google Drive API
I am trying to upload an image from an url to Google Drive. The JavaScript Quickstart from Google Drive work perfectly in my web app. But now I want to upload this image to the Google Drive. I have searched in Google's documentation and I found an article Files: Insert. But in this article you get only an example with a file object.
Do some one know how to upload an image from an url to Google Drive?
This is what I have:
<html> <head>
<script type="text/javascript">
var CLIENT_ID = <CLIENT_ID>;
var SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly'];
/**
* Check if current user has authorized this application.
*/
function checkAuth() {
gapi.auth.authorize(
{
'client_id': CLIENT_ID,
'scope': SCOPES.join(' '),
'immediate': true
}, handleAuthResult);
}
/**
* Handle response from authorization server.
*
* #param {Object} authResult Authorization result.
*/
function handleAuthResult(authResult) {
var authorizeDiv = document.getElementById('authorize-div');
if (authResult && !authResult.error) {
// Hide auth UI, then load client library.
authorizeDiv.style.display = 'none';
loadDriveApi();
} else {
// Show auth UI, allowing the user to initiate authorization by
// clicking authorize button.
authorizeDiv.style.display = 'inline';
}
}
/**
* Initiate auth flow in response to user clicking authorize button.
*
* #param {Event} event Button click event.
*/
function handleAuthClick(event) {
gapi.auth.authorize(
{client_id: CLIENT_ID, scope: SCOPES, immediate: false},
handleAuthResult);
return false;
}
/**
* Load Drive API client library.
*/
function loadDriveApi() {
gapi.client.load('drive', 'v2', insertFile(callback));
}
function callback(){
console.log("It works.");
}
/**
* Insert new file.
*
* #param {File} fileData File object to read data from.
* #param {Function} callback Function to call when the request is complete.
*/
function insertFile(callback) {
const boundary = '-------314159265358979323846';
const delimiter = "\r\n--" + boundary + "\r\n";
const close_delim = "\r\n--" + boundary + "--";
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function() {
var reader = new FileReader();
reader.onloadend = function () {
var fileData =reader.result;
var contentType = "image/jpg";
var metadata = {
'title': "cat.jpg",
'mimeType': contentType
};
var base64Data = btoa(fileData);
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);
console.log(fileData);
};
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', "https://scontent.cdninstagram.com/hphotos-xpt1/t51.2885-15/e15/11324950_950675781667048_1239101466_n.jpg");
xhr.send();
/**
* Append a pre element to the body containing the given message
* as its text node.
*
* #param {string} message Text to be placed in pre element.
*/
function appendPre(message) {
var pre = document.getElementById('output');
var textContent = document.createTextNode(message + '\n');
pre.appendChild(textContent);
}
</script>
<script src="https://apis.google.com/js/client.js?onload=checkAuth">
</script> </head> <body> <div id="authorize-div" style="display: none">
<span>Authorize access to Drive API</span>
<!--Button for the user to click to initiate auth sequence -->
<button id="authorize-button" onclick="handleAuthClick(event)">
Authorize
</button> </div> <pre id="output"></pre> </body> </html>
Took me some time to figure out, but this worked for me. I know that 2 years later someone will be looking for this. use this code after your authorized connection to Google Drive.
var image_location = 'https://your_url_location.image.jpg';
var request22 = new XMLHttpRequest();
request22.open('GET', image_location, true);
request22.responseType = 'blob';
request22.onload = function() {
var fileData = request22.response;
const boundary = '-------314159265358979323846';
const delimiter = "\r\n--" + boundary + "\r\n";
const close_delim = "\r\n--" + boundary + "--";
var reader = new FileReader();
reader.readAsDataURL(fileData);
reader.onload = function(e){
var contentType = fileData.type || 'application/octet-stream';
var metadata = {
'name': fileData.fileName,
'mimeType': contentType
};
var data = reader.result;
var multipartRequestBody =
delimiter + 'Content-Type: application/json\r\n\r\n' +
JSON.stringify(metadata) +
delimiter +
'Content-Type: ' + contentType + '\r\n';
//Transfer images as base64 string.
if (contentType.indexOf('image/') === 0) {
var pos = data.indexOf('base64,');
multipartRequestBody += 'Content-Transfer-Encoding: base64\r\n' + '\r\n' +
data.slice(pos < 0 ? 0 : (pos + 'base64,'.length));
} else {
multipartRequestBody += + '\r\n' + data;
}
multipartRequestBody += close_delim;
var request = gapi.client.request({
'path': '/upload/drive/v3/files',
'method': 'POST',
'params': {'uploadType': 'multipart'},
'headers': {
'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'
},
'body': multipartRequestBody
});
request.execute(function(file){
if(file.id){
// send id to STM and mark uploaded
alert("request execute: "+JSON.stringify(file));
}
});
};
};
request22.send();
I am building a chrome-extension and would like to enable users to create a new spreadsheet. Per the documentation. Here is how I am attempting to do it:
Sweeper.GSheets.prototype.createSpreadsheet = function(title) {
var data, headers, callback, delimiter, boundary;
callback = function(status, responseText){
console.log(responseText);
};
title = title + ' --CD.xls';
delimiter = '\r\n';
boundary = '--Sweeper';
data = boundary + delimiter + 'Content-Type: application/json; charset=UTF-8' + delimiter + delimiter + '{' + delimiter + '"title"' + ': ' + '"' + title + '"' + delimiter + '}' + delimiter + delimiter + boundary + delimiter + 'Content-Type: application/vnd.google-apps.spreadsheet' + delimiter + ' ' + delimiter + boundary + '--';
headers = { 'Content-Type': 'multipart/related; boundary="Sweeper"', "Convert": "true" };
this.makeRequest('post','https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart', callback, data, headers );
};
Sweeper.GSheets.prototype.makeRequest = function(method, url, callback, opt_data, opt_headers) {
setTimeout(function(){
var data = opt_data || null;
var headers = opt_headers || {};
var xhr = new XMLHttpRequest();
xhr.open(method, url, true);
// Include common headers (auth and version) and add rest.
xhr.setRequestHeader('Authorization', 'Bearer ' + State.authToken());
for (var key in headers) {
xhr.setRequestHeader(key, headers[key]);
}
xhr.onload = function(e) {
this.lastResponse = e.srcElement;
callback(e.srcElement.status, e.srcElement.responseText);
}.bind(this);
xhr.onerror = function(e) {
Sweeper.log(this, this.status, this.response,
this.getAllResponseHeaders());
};
xhr.send(data);
}.bind(this), 500);
};
This actually creates a document that Google Drive recognizes as a spreadsheet, however, I cannot view the sheet. When I click on it, I receive a generic error.
Does anyone know how to make this request so that it creates an empty spreadsheet?
I am trying to integrate Google drive resumable file upload/update with my application. But when i update the file, file is updating in encoded format it is not taking the actual content. Please find the below details
Step 1 : Start the resumable session
var request = gapi.client.request({
"path": "/upload/drive/v2/files/"+fileId,
"method": "PUT",
"params": {
"uploadType": "resumable",
},
"headers": {
"X-Upload-Content-Type": "multipart/mixed",
},
"body": {
}
});
if (!callback) {
callback = function(file) {
console.log(file)
};
}
request.execute(callback);
Step 2 : Resumable session initiation request
const boundary = '-------314159265358979323846';
const delimiter = "\r\n--" + boundary + "\r\n";
const close_delim = "\r\n--" + boundary + "--";
//console.log(fileData.size);return false;
var reader = new FileReader();
reader.readAsBinaryString(fileData);
reader.onload = function(e) {
var contentType = fileData.type || 'application/octet-stream';
//TO UPDATE A SLIDE YOU NEED TO UPLOAD SLIDE ONLY
if(fileMetadata.mimeType == "application/vnd.google-apps.presentation" && contentType != "application/vnd.openxmlformats-officedocument.presentationml.presentation"){
alert("Please upload a slide to update the file");
return false;
}
// Updating the metadata is optional and you can instead use the value from drive.files.get.
var base64Data = btoa(reader.result);
var multipartRequestBody =
delimiter +
'Content-Type: application/json\r\n\r\n' +
JSON.stringify(fileMetadata) +
delimiter +
'Content-Type: ' + contentType + '\r\n' +
'Content-Transfer-Encoding: base64\r\n' +
'\r\n' +
base64Data +
close_delim;
var accessToken = gapi.auth.getToken().access_token;
var request = gapi.client.request({
'path': sessionPath,
'method': 'PUT',
'headers': {
'Content-Type': 'multipart/mixed; boundary="' + boundary + '";Content-Length='+fileData.size,
'Authorization ': 'Bearer'+ accessToken,
},
'body': multipartRequestBody});
if (!callback) {
callback = function(file) {
console.log(file)
};
}
request.execute(callback);
}
Result : Updated file in google drive
---------314159265358979323846
Content-Type: application/json
{"mimeType":"application/vnd.google-apps.document","title":"sample doc 2201.docx","description":"test description.."}
---------314159265358979323846
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document
Content-Transfer-Encoding: base64
UEsDBBQACAgIAEMyN0YAAAAAAAAAAAAAAAALAAAAX3JlbHMvLnJlbHOtkk1LA0EMhu/9FUPu3WwriMjO9iJCbyL1B4SZ7O7Qzgczaa3/3kEKulCKoMe8efPwHNJtzv6gTpyLi0HDqmlBcTDRujBqeNs9Lx9g0y+6Vz6Q1EqZXCqq3oSiYRJJj4jFTOypNDFxqJshZk9SxzxiIrOnkXHdtveYfzKgnzHV1mrIW7sCtftI/Dc2ehayJIQmZl6mXK+zOC4VTnlk0WCjealx+Wo0lQx4XWj9e6E4DM7wUzRHz0GuefFZOFi2t5UopVtGd/9pNG98y7zHbNFe4ovNosPZG/SfUEsHCOjQASPZAAAAPQIAAFBLAwQUAAgICABDMjdGAAAAAAAAAAAAAAAAEQAAAHdvcmQvc2V0dGluZ3MueG1sRY5BTgMxEATvvMKae2KTQ0CreCNx4AMJDxjsye4Ke8byOFnC6zFw4NiqrlYfjp85mRtVXYQ9PG4dGOIgceHJw9v5dfMMRhtyxCRMHu6kcBwfDuug1FpvqekLrMPqYW6tDNZqmCmjbqUQd3aRmrH1WCe7So2lSiDVruZkd87tbcaFYeyTXyLZrEOhGohbv+Mc2B8QFy0J7y8YPqYqV46nGQv9IbrgNbUzvp+alG7fMHl42v2a9v/m+A1QSwcIJamct7kAAADrAAAAUEsDBBQACAgIAEMyN0YAAAAAAAAAAAAAAAAcAAAAd29yZC9fcmVscy9kb2N1bWVudC54bWwucmVsc62RTQrCMBCF954izN6mVRCRpm5EcCv1ADGdtsE2CckoensDiloo4sLl/H3vMS9fX/uOXdAH
Can you please tell me what am i doing wrong. I am new to google drive apis.
Thanks