2
votes

I am trying to create a function that uploads an image from the users local memory and sends it to the Google Drive connected, in apps script. I seem to be able to interact with the drive and the file, but whenever I upload the image, the google drive has a file in it with the right name but it is not an image, it seems like a text file containing all of the data of the image.

I can't seem to tell where the error is or where things are going wrong. If someone could even give me a hint of something I need to learn or read up on so I can find my own error, or give me the answer, either way I just want to learn where I am going wrong :)

thanks for your help

I have read the documentation on the FileReader API believing I wasn't using the onloadend event properly, I have tried converting an image into a blob, and a string and tried to create the files from that.

function addImageToDrive() {
  var file = $('#capture')[0].files[0];
  var reader = new FileReader();

  reader.readAsDataURL(file);

  reader.onloadend = function(e) {
    google.script.run
      .withSuccessHandler()
      .withFailureHandler(errorAlert)
      .uploadFileToGoogleDrive("regNo","Test",e.target.result);
  });
}

<fieldset>
  <div>
    <button type = "button" id = "submitPhoto" 
       onclick="addImageToDrive()">PHOTO</button>
    <input type="file" accept="image/*" capture="camera" id = "capture">
    <p><img src="" id="img_preview" alt="No Image Selected"/></p>
  </div>
</fieldset>    
function uploadFileToGoogleDrive(regNo,fileName,data) {  
  try {         
    var regFolder = checkIfFolderExists(regNo);      
    // var blob = DriveApp.createFile("test File",data);
    var contentType = data.substring(5,data.indexOf(';')),
        bytes = Utilities.base64Decode(data.substr(data.indexOf('base64,')+7)),
        blob = Utilities.newBlob(bytes, contentType, regNo + fileName);

    DriveApp.getFolderById(regFolder).createFile(blob);

    Logger.log("Complete");
    return "OK";      
  } catch (f) {
    Logger.log(f.toString());
    return f.toString();
  }
}    

it works, but the resulting file uploaded is not an image.

3
If checkIfFolderExists(regNo) returns the valid folder ID, I think that your script works. So can you provide the whole script and sample image for replicating your situation? By this, I would like to confirm it. Of course, please remove your personal information. - Tanaike
I tested your code only changing regFolder for a valid folder Id and is working perfectly. I uploaded .png and .jpeg images to Drive and I was able to opened them in the browser. Please provide an example image. - Andres Duarte

3 Answers

0
votes
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);

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

You have a extra ) in the last line of your addImageToDrive function, probably this is causing the problem.

0
votes

You need to upload the data in arraybuffer instead of binary large object

var blob;//image data
var imageSize;//image size
var reader= new FileReader();
reader.readAsArrayBuffer(blob).then((response)=>{
var viewArraybuffer=new Uint8Array(response);
var xhr=new XMLHttpRequest();
xhr.open("POST", "https://www.googleapis.com/upload/drive/v3/files?uploadType=media", true);
          xhr.setRequestHeader("Authorization", `Bearer ${token.accessToken}`);
          xhr.setRequestHeader("Content-Type", `image/png`);
          xhr.setRequestHeader("Content-Length",imageSize );
})
xhr.send(viewArrayBuffer);

xhr.onreadystatechange=function () {
            if(xhr.readyState === 4 && xhr.status === 200) {
              console.log(xhr.responseText);
            }
          }