4

I have an HTML sidebar in a Google spreadsheet with a file upload input field that doesn't work with the new v8 engine. It does work in the old runtimeVersion DEPRECATED_ES5.

The file upload in the sidebar is for uploading a single file to my google drive.

Html file

<body>
<h1>File Uploader</h1>
<form>
    <input type="file" name="myFile" id="file">
    <br>
    <input class="blue" type="button" id="submitBtn" value="Upload File" onclick="uploadthis(this.parentNode)">
    
</form>

<input type="button" value="Close" onclick="google.script.host.close()" />

<script>
  
function uploadthis(fileForm){

google.script.run
.uploadFiles(fileForm)
}


   
</script>
    
</body>

And here the simplified gs

function uploadContract() {
  var html = HtmlService.createHtmlOutputFromFile('ContractUpload').setTitle('Kontrakt upload').setWidth(300);
SpreadsheetApp.getUi().showSidebar(html);
}

function uploadFiles(data){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sStamdata = ss.getSheetByName('Stamdata_New');
var contractFolderId = sStamdata.getRange('D60').getValue(); 
var idag = Utilities.formatDate(new Date(), "GMT+1", "yyyyMMdd");
var title = sStamdata.getRange('D52').getValue();

var file = data.myFile;
var folder = DriveApp.getFolderById(contractFolderId);
var createFile = folder.createFile(file);
createFile.setName(idag+" - KONTRAKT - "+title);

}
Alan Wells
  • 30,746
  • 15
  • 104
  • 152
Kasper Egelund
  • 141
  • 2
  • 11
  • In my test it is faililng at that `google.script.run.uploadFiles(fileForm)` call. It doesn't even call the function. It throws some 'uncaught' error. I would submit a bug report at https://issuetracker.google.com/issues?q=componentid:191640. Let me know the # when you submit and I'll star it cause I see the same issue. – IMTheNachoMan Mar 18 '20 at 22:20
  • 1
    In fact, I tested Google's own code at https://developers.google.com/apps-script/guides/html/communication#forms, except in a sidebar, and it yields the same error. Google's code does work in a normal web-app. I wonder if the file serialization in a form is only for web-apps? – IMTheNachoMan Mar 18 '20 at 22:23
  • Is there anything that I can do for your question? If my answer was not useful for your situation. I have to apologize and modify it. If you can cooperate to resolve your issue, I'm glad. I would like to think of about the solution. – Tanaike May 12 '20 at 21:57
  • 1
    @Tanaike Just after I posted this we went into lock-down due to Covid-19. So I haven't got the time/possibility to test it. But it looks like your answer will be a good workaround I've just havn't got the possibility to test it. As soon as I'll be able too I'll give you feedback. – Kasper Egelund May 14 '20 at 17:04
  • @Kasper Egelund Thank you for replying. I can understand about this situation. Thank you, too. – Tanaike May 14 '20 at 23:16
  • Issue tracker: https://issuetracker.google.com/issues/150675170 – TheMaster Aug 17 '20 at 21:16
  • Issue tracker: https://issuetracker.google.com/issues/149980602 – Kasper Egelund Sep 08 '20 at 06:47
  • Issue tracker: https://issuetracker.google.com/issues/167972301 – Kasper Egelund Sep 08 '20 at 07:01

1 Answers1

8

Issue and workaround:

I could confirm about the same situation of your issue (this was reported on Google's Issue Tracker). In this case, I think that when V8 is enabled, the form object might not be able to be parsed when the object is sent to Google Apps Script side with google.script.run. Although I think that this might be modified in the future update, as the current workaround, I would like to propose to send the uploaded file to GAS side as the byte array.

When your script is modified, it becomes as follows.

Modified script:

HTML & JavaScript side: ContractUpload.html

Please modify uploadthis as follows.

function uploadthis(fileForm){
  const file = fileForm.myFile.files[0];
  const fr = new FileReader();
  fr.onload = function(e) {
    const obj = {
      // filename: file.name,  // In your script, the filename is given at GAS side. So I removed this.
      mimeType: file.type,
      bytes: [...new Int8Array(e.target.result)]
    };
    google.script.run.withSuccessHandler((e) => console.log(e)).uploadFiles(obj);
  };
  fr.readAsArrayBuffer(file);
}

Google Apps Script side: Code.gs

Please modify uploadFiles as follows.

function uploadFiles(data){
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sStamdata = ss.getSheetByName('Stamdata_New');
  var contractFolderId = sStamdata.getRange('D60').getValue(); 
  var idag = Utilities.formatDate(new Date(), "GMT+1", "yyyyMMdd");
  var title = sStamdata.getRange('D52').getValue();
  
  var file = Utilities.newBlob(data.bytes, data.mimeType, idag+" - KONTRAKT - "+title);  // Modified
  var folder = DriveApp.getFolderById(contractFolderId);
  var createFile = folder.createFile(file);
  return createFile.getId();  // Added
}

Note:

  • At above modification, when the file is uploaded, the file is converted to the byte array and send it to GAS side. Then, the file is created from the byte array. And the file ID is returned. You can see it at the console.

References:

halfer
  • 19,824
  • 17
  • 99
  • 186
Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • Hi, I've tried this workarround but it's not working... could you take a look? thanks. https://stackoverflow.com/questions/61730044/uploading-mp3-file-to-google-drive-from-google-apps-script?noredirect=1#comment109204569_61730044 – jbra95 May 12 '20 at 09:00
  • @Juan Bravo Roig At first, in my environment, I could confirm that this script worked. I saw your question. Although in your question, you say that you upload mp3, when I saw `console.log(file.mimeType)` in your question, it's `audio/wav`. I think that when MP3 is uploaded, the mimeType is `audio/mpeg`. How about this? By the way, can I ask you about the detail of `it doesn't work...`? And also, can you provide whole script for replicating your issue? If you can do, please add it to your question. – Tanaike May 12 '20 at 21:56
  • thanks for the quick response. The log was audio/wav because i've tested with mp3 and wav files, none of them works. Sorry for the missunderstandig. The only difference between my script and yours is that I pass the file and also a couple of form fields. The file.bytes and file.mimeType are being sended to the server function properly, but when i try to create the newBlob it just return undefined. – jbra95 May 13 '20 at 08:56
  • @Juan Bravo Roig Thank you for replying. I tested your added script. Unfortunately, I could confirm that the script worked. When the blob is created as a file, the binary file (mp3 file) can be created. So I cannot replicate your issue. This is due to my poor skill. I deeply apologize for this. Can you provide your current script for replicating your issue? – Tanaike May 13 '20 at 22:01
  • hi! I finally resolved the issue, it was really ridiculous. I've updated the question and i add the response. Thanks also! – jbra95 May 14 '20 at 08:33
  • @Juan Bravo Roig Thank you for replying. I'm glad your issue was resolved. But I deeply apologize that I couldn't notice about your issue. This is due to my poor skill. I could study from your issue. Thank you, too. – Tanaike May 14 '20 at 08:37
  • @Tanaike I find this solution worked nicely for uploading images, but I had trouble with videos which are much larger, 50MB for example should take a couple of minutes with the connection I have, but with method, the browser started using a lot of memory and became unresponsive. Could there be a solution that uses streams for example? – nwaltham Aug 13 '20 at 19:59
  • @nwaltham In that case, please use resumable upload. You can see about it at [the official document](https://developers.google.com/drive/api/v3/manage-uploads) – Tanaike Aug 13 '20 at 23:22
  • Recently, it was found that the invalid blob of sending the file of HTML form to Google Apps Script side using google.script.run has finally been resolved. But, in the current stage, this bug was resolved for only Web Apps. When this is used for a dialog and a sidebar, the file blob is not included in Google Apps Script side. Please be careful about this. I would like to believe that this situation is resolved in the future update. https://stackoverflow.com/a/41997307 – Tanaike Dec 09 '21 at 08:54