-1

I prepared a simple Google Apps Script with Upload form to allow my friend without google account uploading some files (different types - pics, docx, png etc. ; rather small files - under 10MB)

function doGet(e) {
  return HtmlService.createHtmlOutputFromFile('form.html');
}

function uploadFiles(form) {
  try {
    var mainFolder = "Tmp_Uploads";

    var folder = DriveApp.getFoldersByName(mainFolder).next();
    var file = folder.createFile(form.myFile);
    
    return "File uploaded successfully " + file.getUrl();
  } catch (error) {
    return error.toString();
  }
}

Mechanism works -> after uploading file shows in my "Tmp_Uploads" folder in Google Drive. But when I download it to my PC -> file is broken.

I tested it with .jpg, .png, .doc and all of them are broken - cannot open them (they also have different size than original one).

When I upload simple .txt file -> it works fine.

Quastions:

  1. What is wrong?
  2. Can I somehow recover file which was uploaded with above mechanism? Decode it after downloading to PC or postprocess to be able to open it?

Cheers and thanks in advance!

Marios
  • 26,333
  • 8
  • 32
  • 52
Mattorw88
  • 3
  • 1
  • Are running V8? – Cooper Apr 27 '20 at 00:10
  • https://stackoverflow.com/a/61349555/7215091 – Cooper Apr 27 '20 at 00:12
  • Does this answer your question? [Moving google apps script to v8 file upload stopped working from sidebar](https://stackoverflow.com/questions/60742695/moving-google-apps-script-to-v8-file-upload-stopped-working-from-sidebar) – TheMaster Apr 27 '20 at 05:15
  • Please [search](https://stackoverflow.com/questions/tagged/google-apps-script+file-upload+google-apps-script-web-application?sort=newest) before asking questions. – TheMaster Apr 27 '20 at 05:18
  • Agree - was trying to search but somehow haven't found that which you mentioned. Thanks. Didn't know that it is V8 issue (even didn't know I use V8 of app script). Do you have maybe any suggestions for question 2? – Mattorw88 Apr 28 '20 at 14:33

1 Answers1

1

Try this Javascript function in your html before calling your google script uploadFiles() function.

<script>
function uploadFile(form) {
    const file=form.File.files[0];
    const fr=new FileReader();//all this FileReader code originally came from Tanaike
    fr.onload=function(e) {
      const obj={filename:file.name,mimeType:file.type,bytes:[...new Int8Array(e.target.result)]};
      google.script.run.uploadFiles(obj);
    }
    fr.readAsArrayBuffer(file);
  }
  </script>

Then your Google Script Function looks like this:

function uploadFiles(form) {
   var mainFolder = "Tmp_Uploads";
    var folder = DriveApp.getFoldersByName(mainFolder).next();
    var blob = Utilities.newBlob(form.bytes, form.mimeType, form.filename);
    var file=folder.createFile(blob); 
    return "File uploaded successfully " + file.getUrl();
}

Example

Reference

If you have more data in your form rather than just a file upload then take a look at this example.

<script>
function uploadFile(form) {
    console.log('form.elements.Destination.value= %s',form.elements.Destination.value);
    console.log('format.elements.FileName.value= %s',form.elements.FileName.value);
    $('#msg').css('display','block');
    $('#msg').html('UpLoading...Please Wait');
    const file=form.File.files[0];
    const fr=new FileReader();//all this FileReader code originally came from Tanaike
    fr.onload=function(e) {
      const obj={FileName:form.elements.FileName.value,Destination:form.elements.Destination.value,mimeType:file.type,bytes:[...new Int8Array(e.target.result)]};//this allowed me to put the rest of the Form.elements back into the object before sending it to google scripts
      google.script.run
      .withSuccessHandler(function(msg){
        $('#msg').css('display','block');
        $('#msg').html(msg);//I returned a message after the download 
      })
      .uploadFile(obj);
    }
    fr.readAsArrayBuffer(file);
  }
  </script>



<form>
  <br /><select id="sel1" name="Destination"></select> Upload Destination
  <br /><input type="text" name='FileName' /> File Name
  <br /><input type="file" name='File'; />
  <br /><input type="button" value="Upload" onClick="uploadFile(this.parentNode);" />
  <br /><input type="button" value="Close" onclick="google.script.host.close();" />
  <div id="msg"></div>
</form>
Cooper
  • 59,616
  • 6
  • 23
  • 54
  • Thanks - that's the way - I adjusted my code with your suggestions - now it's ok. But what about second question? Do you think there is possibility to postprocess file which was uploaded as broken with mechanism which I described on first post? Can I somehow decode it to be able to read it properly? – Mattorw88 Apr 28 '20 at 14:30
  • I’d recommend that you ask that again as another separate question. In my situation I was happy to learn about the file reader I’ve never used it before and I assumed that the files that I attempted to upload before using it weren’t actually getting uploaded if you say they are getting uploaded then I don’t know the answer to your question so I would redirect it to another person by asking another question. – Cooper Apr 28 '20 at 15:31