Home  >  Q&A  >  body text

Use Google Apps Script to upload files directly to my Google Drive (without using Google Forms)

So basically the task is very simple but I didn't find any feasible solution to my problem. I have a huge upload script on my website (currently localhost), but let's reduce all the complexity to only what is necessary.

So I just want to use Google App Script to upload a single file to Google Drive and receive it's URL to save it in a var so I can use that information later in my function.

Now the problem is that I already have the form on my website, I don't want the form inside script.google .com as extra html, I want to add it to my user The input is transferred to Google App Script which then uploads it to google drive and returns the url to my website which I can save into a var.

My problem now is that I can't put it all together.

This is the form on my website (simplified):

<form name="myForm" method="post">
            <!-- <form name="first-form"> -->

  <input type="text" placeholder="Name" id="myName">
  <input type="file" name="myFile" id="myFile">
  <button onclick="UploadFile()" type="submit">submit</button>

</form>

So how do I upload my information in Google Drive and get the results? How can I push data from Google App Script without using iFrames or anything else?

Thanks!

**** Working example if html is in script.google .com ****

GS

function doGet(e) {
  return HtmlService.createHtmlOutputFromFile('forms.html').setTitle("Google File Upload by CTRLQ.org");
}


function uploadFileToGoogleDrive(data, file, name, email) {
  
  try {
    
    var dropbox = "Received Files";
    var folder, folders = DriveApp.getFoldersByName(dropbox);
    
    if (folders.hasNext()) {
      folder = folders.next();
    } else {
      folder = DriveApp.createFolder(dropbox);
    }
    
    /* Credit: www.labnol.org/awesome */
    
    var contentType = data.substring(5,data.indexOf(';')),
        bytes = Utilities.base64Decode(data.substr(data.indexOf('base64,')+7)),
        blob = Utilities.newBlob(bytes, contentType, file),
        file = folder.createFolder([name, email].join(" ")).createFile(blob);
    
    return "OK";
    
  } catch (f) {
    return f.toString();
  }
  
}

html in apps.googlescript

<!DOCTYPE html>
<html>
  <head>
    <base target="_blank">
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Google File Upload by CTRLQ.org</title>
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/css/materialize.min.css">
    <style>
      .disclaimer{width: 480px; color:#646464;margin:20px auto;padding:0 16px;text-align:center;font:400 12px Roboto,Helvetica,Arial,sans-serif}.disclaimer a{color:#009688}#credit{display:none}
    </style>
  </head>
  <body>

    <!-- Written by Amit Agarwal amit@labnol.org --> 

    <form class="main" id="form" novalidate="novalidate" style="max-width: 480px;margin: 40px auto;">
      <div id="forminner">
        <div class="row">
          <div class="col s12">
            <h5 class="center-align teal-text">Upload Files to my Google Drive</h5>
            <p class="disclaimer">This <a href="http://www.labnol.org/internet/file-upload-google-forms/29170/">File Upload Form</a> (<a href="https://youtu.be/C_YBBupebvE">tutorial</a>) is powered by <a href="https://ctrlq.org/code/19747-google-forms-upload-files" target="_blank">Google Scripts</a></p>
          </div>
        </div>
        <div class="row">
          <div class="input-field col s12">
            <input id="name" type="text" name="Name" class="validate" required="" aria-required="true">
            <label for="name">Name</label>
          </div>
        </div>
        <div class="row">
          <div class="input-field col s12">
            <input id="email" type="email" name="Email" class="validate" required="" aria-required="true">
            <label for="email">Email Address</label>
          </div>
        </div>

        <div class="row">
          <div class="file-field input-field col s12">
            <div class="btn">
              <span>File</span>
              <input id="files" type="file">
            </div>
            <div class="file-path-wrapper">
              <input class="file-path validate" type="text" placeholder="Select a file on your computer">
            </div>
          </div>
        </div>

        <div class="row">
          <div class="input-field col s6">
            <button class="waves-effect waves-light btn submit-btn" type="submit" onclick="submitForm(); return false;">Submit</button>
          </div>   
        </div>
        <div class="row">
          <div class="input-field col s12" id = "progress">
          </div>
        </div>
      </div>
      <div id="success" style="display:none">
        <h5 class="left-align teal-text">File Uploaded</h5>
        <p>Your file has been successfully uploaded.</p>
        <p>The <a href="http://www.labnol.org/internet/file-upload-google-forms/29170/">pro version</a> (see <a href="">demo form</a>) includes a visual drag-n-drop form builder, CAPTCHAs, the form responses are saved in a Google Spreadsheet and respondents can upload multiple files of any size.</p>    
        <p class="center-align"><a  class="btn btn-large" href="https://gum.co/GA14?wanted=true" target="_blank">Upgrade to Pro</a></p>
      </div>
    </form>

    <div class="fixed-action-btn horizontal" style="bottom: 45px; right: 24px;">
      <a class="btn-floating btn-large red">
        <i class="large material-icons">menu</i>
      </a>
      <ul>
        <li><a class="btn-floating red"  href="https://gum.co/GA14" target="_blank" title="Buy License - File Upload Form"><i class="material-icons">monetization_on</i></a></li>
        <li><a class="btn-floating blue"  href="https://youtu.be/C_YBBupebvE" target="_blank" title="Video Tutorial"><i class="material-icons">video_library</i></a></li>
        <li><a class="btn-floating green" href="http://www.labnol.org/internet/file-upload-google-forms/29170/" target="_blank" title="How to Create File Upload Forms"><i class="material-icons">help</i></a></li>
      </ul>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/js/materialize.min.js"></script>
    <script src="https://gumroad.com/js/gumroad.js"></script>

    <script>

      var file, 
          reader = new FileReader();

      reader.onloadend = function(e) {
        if (e.target.error != null) {
          showError("File " + file.name + " could not be read.");
          return;
        } else {
          google.script.run
            .withSuccessHandler(showSuccess)
            .uploadFileToGoogleDrive(e.target.result, file.name, $('input#name').val(), $('input#email').val());
        }
      };

      function showSuccess(e) {
        if (e === "OK") { 
          $('#forminner').hide();
          $('#success').show();
        } else {
          showError(e);
        }
      }

      function submitForm() {

        var files = $('#files')[0].files;

        if (files.length === 0) {
          showError("Please select a file to upload");
          return;
        }

        file = files[0];

        if (file.size > 1024 * 1024 * 5) {
          showError("The file size should be < 5 MB. Please <a href='http://www.labnol.org/internet/file-upload-google-forms/29170/' target='_blank'>upgrade to premium</a> for receiving larger files in Google Drive");
          return;
        }

        showMessage("Uploading file..");

        reader.readAsDataURL(file);

      }

      function showError(e) {
        $('#progress').addClass('red-text').html(e);
      }

      function showMessage(e) {
        $('#progress').removeClass('red-text').html(e);
      }


    </script>

  </body>

</html>

As suggested, I'll describe the process here.

So we are on the website: www.example.com, and have a form with a text input field and a file field. Let's say we put in an image and call it an example. Now, if we press submit, I want to upload the image to Google Drive without any oAuth (that's why we need Google App Script here) and name it what we typed in the text field. Once the upload is complete, I want the url of the google drive image to be returned to the website so that the form can continue to use that information. I want to save the returned url in a var and later save it in the database. That's why I need to return the results to my website.

So the solution is as follows:

Enter information into a form on the website -> Redirect to google app script: Get the information for the website form fields and upload the file to google drive and name it text input entry -> Change the google drive's url as the final result -> Redirect the final url result back to the website -> Save the url result in var and continue to perform operations from the function on the website -> Finally save the information in var to the database -> finish

-------------------------------------------------- ------------- - edit: ------------------

Thanks to @Tanaike I'm closer to my challenge goal, so to see where I got stuck I'm copying my question now:

I got the form using the script in your example:

<form id="form">
  <input name="file" id="uploadfile" type="file">
  <input name="filename" id="filename" type="text">
  <input id="submit" type="submit">
</form>
<script>
const form = document.getElementById('form');
form.addEventLis tener('submit', e => {
  e.preventDefault();
  const file = form.file.files[0];
  const fr = new FileReader();
  fr.readAsArrayBuffer(file);
  fr.onload = f => {
    
    const url = "https://script.google .com/macros/s/###/exec";  // <--- Please set the URL of Web Apps.
    
    const qs = new URLSearchParams({filename: form.filename.value || file.name, mimeType: file.type});
    fetch(`${url}?${qs}`, {method: "POST", body: JSON.stringify([...new Int8Array(f.target.result)])})
    .then(res => res.json())
    .then(e => console.log(e))  // <--- You can retrieve the returned value here.
    .catch(err => console.log(err));
  }
});
</script>

For Google Script:

function doPost(e) {
  // const folderId = "###";  // Folder ID which is used for putting the file, if you need.

  const blob = Utilities.newBlob(JSON.parse(e.postData.contents), e.parameter.mimeType, e.parameter.filename);
  const file = DriveApp.getFolderById(folderId || "root").createFile(blob);
  const responseObj = {filename: file.getName(), fileId: file.getId(), fileUrl: file.getUrl()};
  return ContentService.createTextOutput(JSON.stringify(responseObj)).setMimeType(ContentService.MimeType.JSON);
}

Now when I try to upload something I get the following error: CORS policy could not be obtained. So I changed this part to the following and added the no cors mode:

const qs = new URLSearchParams({filename: form.filename.value || file.name, mimeType: file.type});
        fetch(`${url}?${qs}`, {method: "POST", mode: "no-cors", body: JSON.stringify([...new Int8Array(f.target.result)])})

This works. The second attempt to upload the file results in the following error: It says: syntax error: Unexpected end of input

So I changed this line and removed the brackets from res.json

JSON.stringify([...new Int8Array(f.target.result)])})
        .then(res => res.json)

The third attempt to upload an actual valid file, the console results are as follows:

ƒ json() { [native code] }

But there are no uploaded files in Google Drive. I'm missing something somewhere. Maybe we should create a folder and put the files in it.

Oh, one more info: When I run the doPost function in google app script, it says:

TypeError: Cannot read property 'postData' of undefined (line 13

Edit 2------------------------------------------------ --------

I added https://drive.google .com/uc?export=download&id=

fileId

to your code and everything works fine. File is being uploaded.

Suppose we upload the file test.mp3 and name it testdata. This is what we received:

{
  "filename": "testdata",
  "fileId": "###some id##",
  "fileUrl": "https://drive.google .com/uc?export=download&id=###fileId###"
}

Now when I open the file url the browser downloads the file but its name is: testdata instead of testdata.mp3. The end of the file type is missing.

Second task: If you click on the link, I want to open the file in the browser, for example, when it is an mp3 file, I want you to play the sound in the webview, like here: https: //files.freemusicarchive .org/storage-freemusicarchive-org/music/Creative_Commons/Dead_Combo/CC_Affiliates_Mixtape_1/Dead_Combo_-_01_-_Povo_Que_Cas_Decalo.mp3

Hope you can guide me! ######
P粉785905797P粉785905797272 days ago508

reply all(2)I'll reply

  • P粉512729862

    P粉5127298622024-01-22 14:32:10

    https://stackoverflow.com/a/63391363/1585523 Lots of helpful tips in the answers! thank you for your sharing. In addition to POST files, we can also use

    On the client: index.html

    google.script.run.withSuccessHandler(fileName => {}).withFailureHandler(error => {}).saveInDrive(fileAsByteArray);
    

    On the server: Code.gs

    function saveInDrive(f) {
      const blob = Utilities.newBlob(f, "image/jpeg", "some-name");
      const file = DriveApp.getFolderById("root").createFile(blob);
      return file.getName()
    }
    

    You can even use this method to exchange complex types such as JS objects with binary information as values.

    reply
    0
  • P粉298305266

    P粉2983052662024-01-22 13:48:47

    I believe your goals are as follows.

    • Your website is not associated with a Google Account. It is independent.
    • Your website has a form for uploading files.
    • When a user submits a form, you want to upload a file to your Google Drive without authorization, and you want to return the URL of the uploaded file on Google Drive.
    • Regarding "database", this is your database. You place the retrieved file URL into the client's "database".

    In this case, I think a web application created using Google Apps Script can achieve your goal.

    usage:

    Please perform the following process.

    1. Create a new project for Google Apps Script.

    The sample script for Web Apps is Google Apps Script. So, create a Google Apps Script project.

    If you want to create directly, please visit https://script.new/. In this case, if you are not already logged in to Google, the login screen will open. So please log into Google. This will open the Google Apps Script script editor.

    2. Prepare script.

    Please copy and paste the following script (Google Apps Script) into the script editor. This script is suitable for web applications.

    Server side: Google Apps Script

    Please set the folder ID where the file is to be placed.

    function doPost(e) {
      const folderId = "root";  // Or Folder ID which is used for putting the file instead of "root", if you need.
    
      const blob = Utilities.newBlob(JSON.parse(e.postData.contents), e.parameter.mimeType, e.parameter.filename);
      const file = DriveApp.getFolderById(folderId).createFile(blob);
      const responseObj = {filename: file.getName(), fileId: file.getId(), fileUrl: file.getUrl()};
      return ContentService.createTextOutput(JSON.stringify(responseObj)).setMimeType(ContentService.MimeType.JSON);
    }

    3. Deploy web applications.

    1. In the script editor, open a dialog box via "Publish" -> "Deploy as Web App".
    2. Select "I" for "Execute Application:" .
      • This way, the script will run as the owner.
    3. For "Who has access to the app:" Select "Anyone, even anonymously" .
    4. Click the "Deploy" button as the new "Project Version".
    5. Automatically open the "Authorization Required" dialog box.
      1. Click "View Permissions".
      2. Select your account.
      3. Click "Advanced" next to "This app is not verified".
      4. Click "Go to
      5. project name
      6. (unsafe)"
      Click the "Allow" button.
    6. Click "OK". Copy the URL of the web application. Like
        https://script.google.com/macros/s/
      • /exec.
      After modifying Google Apps Script, please redeploy to a new version. In this way, the modified script will be reflected in Web Apps. Please be careful with this.

    4. Upload files from the client to the server.

    Client: HTML and Javascript
    • Please set the URL of your web application to the following script.
    • sssccc

    On the client side, when you select a file from your local PC and press a button, the file is uploaded to your Google Drive by retrieving the data in the web app (server side).

    result:### ###When running the above script, the following values ​​will be returned. From this, you can retrieve the URL of the file. ###
    {
      "filename": "### inputted filename ###",
      "fileId": "###",
      "fileUrl": "https://drive.google.com/file/d/###/view?usp=drivesdk"
    }

    Notice:

    • When you modify the scripts of Web Apps, redeploy the Web Apps to a new version. This way, the latest scripts will be reflected in Web Apps. Please be careful with this.
    • In the above script, the maximum file size is 50 MB. Because at this stage, the maximum blob size for Google Apps Script is 50 MB.

    references:

    reply
    0
  • Cancelreply