Creating a new spreadsheet using Google Drive's REST API - javascript

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?

Related

FileReader - How to change the character encoding from UTF-8 to ANSI

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.

How to upload an image from an url to Google Drive?

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();

Facebook cutting out special chars from XMLHttpRequest image share description which contains polish symbols

Okay, so here's my problem.
I have the code which shares image directly to facebook via open graph. Even though it should send description with polish symbols without any problem it's not.
What I send as a description is this:
Zdjęcie z aplikacji http://www.xxx.pl/
What comes out on my wall as a description to the image is this:
Zdjcie z aplikacji http://www.xxx.pl/
I've spent few hours on a research why is it happening and found pretty much nothing. I'd be really grateful for any idea about it as I'm really fed up with that crap.
That's part of my code responsible for posting data to facebook:
function PostImageToFacebook(authToken, filename, mimeType, imageData, message) {
var boundary = '----ThisIsTheBoundary1234567890';
var formData = '--' + boundary + '\r\n'
formData += 'Content-Disposition: form-data; name="source"; filename="' + filename + '"\r\n';
formData += 'Content-Type: ' + mimeType + '\r\n\r\n';
for (var i = 0; i < imageData.length; ++i) {
formData += String.fromCharCode(imageData[i] & 0xff);
}
formData += '\r\n';
formData += '--' + boundary + '\r\n';
formData += 'Content-Disposition: form-data; name="caption"\r\n';
formData += 'Content-Type: text/plain; charset=utf-8\r\n\r\n';
formData += message + '\r\n'
formData += '--' + boundary + '--\r\n';
console.log(formData);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://graph.facebook.com/me/photos?access_token=' + authToken, true);
xhr.onload = xhr.onerror = function() {
console.log(xhr.responseText);
$(".photo-uploaded").fadeIn();
$(".share_to_facebook").removeClass("disabled");
};
xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary + "; charset=utf-8");
xhr.sendAsBinary(formData);
}
PostImageToFacebook(fbToken, imgDesc, "image/png", decodedPng, "Zdjęcie z aplikacji http://www.xxx.pl");

Http Post image fails in browser/Ripple emulator

I am writing a small Cordova (PhoneGap) app. that is sending an image from a file input - using a post method. It works fine in my Android device, but fails in both broswer and Ripple emulator. Here is the code:
function queryImageByData(dataURL) {
var imgType = dataURL.substring(5, dataURL.indexOf(";"));
var imgExt = imgType.split("/")[1];
var imgData = atob(dataURL.substring(dataURL.indexOf(",") + 1));
var filenameTimestamp = (new Date().getTime());
var separator = "----------12345-multipart-boundary-" + filenameTimestamp;
var formData = "--" + separator + "\r\n" +
"Content-Disposition: file; name=\"file\"; filename=\"snapshot_" + filenameTimestamp + "." + imgExt + "\"\r\n" +
"Content-Type: " + imgType + "\r\nContent-Transfer-Encoding: base64" + "\r\n\r\n" + imgData + "\r\n--" + separator + "\r\n";
var xhr = new XMLHttpRequest();
xhr.sendAsBinary = function (data) {
var arrb = new ArrayBuffer(data.length);
var ui8a = new Uint8Array(arrb, 0);
for (var i = 0; i < data.length; i++) {
ui8a[i] = (data.charCodeAt(i) & 0xff);
}
var blob = new Blob([arrb]);
this.send(blob);
};
xhr.open("POST", "https:/my_endpoint_here", true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
parseResult(xhr.responseText);
}
else {
onFailedResponse(xhr.responseText);
}
}
};
xhr.setRequestHeader("Content-type", "multipart/form-data; boundary=" + separator);
xhr.sendAsBinary(formData);
}
The error I get is:
Error: MultipartParser.end(): stream ended unexpectedly: state = HEADER_FIELD_START
at MultipartParser.end
EDIT:
I have a problem also with a get method. It fails on Ripple/Browser but runs OK on the device. here is some sample code:
var url = document.getElementById("urlInput").value;
var query = "my_url_here";
var jqxhr = $.ajax(query)
.done(function (data) {
alert("success" + data);
})
.fail(function (data) {
alert("error" + data);
})
Well I found the core issue, which cross domain calls.
The browsers do not allow it, and apperently so does Ripple emulator,
but mobile devices do allow it.
Now I just need to figure out how to make it work using CORS.

Google Drive File Upload/Update issue with Javascript API

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

Categories

Resources