google-apps-scriptfile-uploadweb-applicationsgoogle-drive-api

Upload File from Website to Google Drive works for text file but not binary


I need to upload files to my Google Drive via a Google App Script. The goal is to be able to let users upload a file to my Google Drive from my website. The code is largely the same as a tutorial I found online, I just added a link to my website banner and also added some code to send me an email when someone uploads a file.

The problem is, it works for text file but not binary files (jpeg, pdf, etc). It correctly creates a file in the appropriate folder, but the file cannot be opened. The binary file that gets created does have some data in it.. when I open the created file in TextEdit, it does look somewhat similar to the original, but some of the characters look different. The filesize of the new created file is also larger than the original.

The problem does not occur with text files. The code is listed below.

HTML code

<!doctype html>
<style type="text/css">
body {
    background-color: #FFFFFF;
}
</style>
<BR>
<BR>
<BR>
<div align="center">
  <p><img src="https://rosspalmermd.files.wordpress.com/2020/05/color-logo-with-background.png" width=320></p>
  <table width="459" border="0">
    <tbody>
      <tr>
        <td width="462"><div align="center">
          <hr>
        </div>
          <form id="myForm" align="center">
            <input type="text" name="myName" placeholder="Your name...">
            <input type="email" name="myEmail" placeholder="Your email...">
            <input type="file" name="myFile">
            <input type="submit" value="Upload File" 
           onclick="this.value='Uploading..';
                    google.script.run.withSuccessHandler(fileUploaded)
                    .uploadFiles(this.parentNode);
                    return false;">
          </form>
          <div id="output"></div>
          <script>
    function fileUploaded(status) {
        document.getElementById('myForm').style.display = 'none';
        document.getElementById('output').innerHTML = status;
    }
          </script>
        <style>
 input { display:block; margin: 20px; }
 
          </style>
        <hr></td>
      </tr>
    </tbody>
  </table>
  <h3>&nbsp;</h3>
  <p>&nbsp;</p>
</div>

Server side code:



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

function uploadFiles(form) {
  
  try {
    
    var dropbox = "DriveUploader";
    var folder, folders = DriveApp.getFoldersByName(dropbox);
    
    if (folders.hasNext()) {
      folder = folders.next();
    } else {
      folder = DriveApp.createFolder(dropbox);
    }
    
    var blob = form.myFile; 
    var file = folder.createFile(blob); 
    
    file.setDescription("Uploaded by " + form.myName);
        
    MailApp.sendEmail("email@email.com",
                  "File uploaded to website",
                  form.myName + " (" + form.myEmail + ") has uploaded a file " + file.getUrl());
    
    return "File uploaded successfully. We will contact you soon.";
    
  } catch (error) {
    
    return error.toString();
  }
}

Solution

  • I found the solution for your problem, here is the code:

    HTML code:

    <!DOCTYPE html>
    <style type="text/css">
    
    body {
        background-color: #FFFFFF;
    }
    </style>
    <BR>
    <BR>
    <BR>
    <div align="center">
      <p><img src="https://rosspalmermd.files.wordpress.com/2020/05/color-logo-with-background.png" width=320></p>
      <table width="459" border="0">
    
        <tbody>
          <tr>
            <td width="462"><div align="center">
              <hr>
            </div>
              <form id="myForm" align="center">
                <div id="data"></div>
                <input type="text" id="myName" name="myName" placeholder="Your name...">
                <input type="email" id="myEmail" name="myEmail" placeholder="Your email...">
                <input id="uploadfile" type="file" name="myFile">
                <input type="submit" value="Upload File" 
               onclick="this.value='Uploading..';
               getFiles();
                return false;">
              </form>
              <div id="output"></div>
    
              <script>
    
        function getFiles() {
         const name = document.getElementById('myName').value;
         const email = document.getElementById('myEmail').value;
         const f = document.getElementById('uploadfile');
         [...f.files].forEach((file, i) => {
          const fr = new FileReader();
          fr.onload = (e) => {
           const data = e.target.result.split(",");
           const obj = {fileName: f.files[i].name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1],myName: name,myEmail: email};
           google.script.run.withSuccessHandler(fileUploaded)
           .uploadFiles(obj);
          }
         fr.readAsDataURL(file);
        });
        }
    
         function fileUploaded(status) {
            document.getElementById('myForm').style.display = 'none';
            document.getElementById('output').innerHTML = status;
        }
        </script>
    
            <style>
     input { display:block; margin: 20px; }
    
              </style>
            <hr></td>
          </tr>
        </tbody>
      </table>
      <h3>&nbsp;</h3>
      <p>&nbsp;</p>
    </div>
    

    Server side code:

    function doGet(e) {
      return HtmlService.createHtmlOutputFromFile('form.html');
    
    }
    
    function uploadFiles(obj) {
    
      try {
    
        var dropbox = "DriveUploader";
        var folder, folders = DriveApp.getFoldersByName(dropbox);
    
        if (folders.hasNext()) {
          folder = folders.next();
        } else {
          folder = DriveApp.createFolder(dropbox);
        }
    
        var blob = Utilities.newBlob(Utilities.base64Decode(obj.data), obj.mimeType, obj.fileName);
        var file = folder.createFile(blob);
        file.setDescription("Uploaded by " + obj.myName);
    
        MailApp.sendEmail("email@email.com",
                      "File uploaded to website",
                      obj.myName + " (" + obj.myEmail + ") has uploaded a file " + file.getUrl());
    
        return "File uploaded successfully. We will contact you soon.";
    
      } catch (error) {
    
        return error.toString();
      }
    }