Mahmoud Maarouf
Mahmoud Maarouf

Reputation: 185

How to get file(s) from an HTML file input and send it as an attachment to an email in Google Apps Script?

This HTML code takes file inputs using Google Script's class HTML service :

(SEE BELOW)

I would like to get the value(s)(the files) of the input field, send to the my .gs file and send that as an attachment to the email.

Getting the value from the input field simply returns the directory of the file, which is no help because Google Apps Script can't obtain files from local drive.

I have done a lengthy research with this problem and I can't find anyone with a similar issue.

Stack Code.gs

function myFunction() {
    var html = HtmlService.createHtmlOutputFromFile('Stack HTML').setWidth(250).setHeight(250);
    SpreadsheetApp.getUi().showModalDialog(html,'Get File');
}

function processEmail(files){
  
  var subject = 'Subject';
  var message = 'Test';
  var recipient = '[email protected]';
  GmailApp.sendEmail(recipient, subject, message, {attachments: files, htmlBody: message, name:'Stack Overflow Test'});  // Doesn't work

  
}

Stack HTML.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
  
     <form method="post" enctype="multipart/form-data">
     <div>
     <input type="file" id= "file" multiple = "true">
     </div>
     </form>
     <br><div style="text-align:center"> <input type="submit" name = "submitButton" onclick = "send()" id = "sendButton" value="Send"></div>
     
   <script>
   
   function done(e){
       google.script.host.close();
   }
   
   
   function send(){
      var files = document.getElementById("file").value;
      console.log(files);
      google.script.run.withSuccessHandler(done).processEmail(files);
   }
   
   </script>
  </body>
</html>



Upvotes: 0

Views: 2043

Answers (1)

Tanaike
Tanaike

Reputation: 201428

  • You want to upload multiple files from local PC to Google Drive using HTML and Javascript.
  • You want to send the uploaded files as the attachment files of an email.
  • You want to achieve this using Google Apps Script.

If my understanding is correct, how about this modification? Please think of this as just one of several answers.

Solution:

From your question, the files are used as the attachment files of an email. So I thought that the following flow can be used for your situation.

  1. Retrieve all files from the local PC.
  2. All files are summarized as an object.
    • At this time, the files are converted to the base64 string value.
  3. Send the object to Google side.
  4. Convert the object to file blob at GAS side.

Modified script:

Please modify send() in HTML side as follows.

function send() {
  const f = document.getElementById('file');
  Promise.all([...f.files].map((file, i) => {
    const fr = new FileReader();
    return new Promise(r => {
      fr.onload = e => {
        const data = e.target.result.split(",");
        r({fileName: file.name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1]});
      }
      fr.readAsDataURL(file);
    });
  }))
  .then(obj => {
    google.script.run.withSuccessHandler(done).processEmail(obj);
  });
}

And please modify processEmail() in GAS side as follows.

function processEmail(obj){
  var files = obj.map(function(e) {return Utilities.newBlob(Utilities.base64Decode(e.data), e.mimeType, e.fileName)});
  var subject = 'Subject';
  var message = 'Test';
  var recipient = '[email protected]';
  GmailApp.sendEmail(recipient, subject, message, {attachments: files, htmlBody: message, name:'Stack Overflow Test'});
}

References:

Upvotes: 2

Related Questions