How to allow users to upload files with Google Form without login?

Viewed 27731
3 Answers

This add-on converts the Google file upload into a HTML file upload. https://formfacade.com/faq/google-forms-upload-file-without-google-account.html You can enable file upload without Google signin. So your users will be able to upload a file using the upload file button from their local drives and submit the form without having to sign in with a Google account. In the Google form, the file upload question will be converted in to a short answer question, where the url location of file uploaded by the user will be displayed.

The user will be uploading the files to your drive. So, google needs to verify the user. If there is no verification, someone can fill your drive in no time.

It is for your safety to know who has uploaded, so, login is must.

There's a workaround, I'm in a hurry to write the code now, but if you're interested let me know and I'll edit later.

Basically, you set up a web app with apps script, then you setup a custom HTML form, you'll have to manually collect the file, convert is to base64 then json, then when you catch it in apps script you reverse the process and save it wherever you want in your drive.

Since the user will be executing the script as you, there's no verification required

/* 
These functions basically go through a file array and reads the files first as binary string (in second function), then converts the files to base64 string (func 1) before stringifying the files (after putting their base64 content into an object with other metadata attached; mime, name e.t.c);

You pass this stringified object into the body part of fetch(request,{body:"stringified object goes here"})

see next code block for how to read in apps script and save the files to google drive
N.B. The body data will be available under doPost(e){e.postData.contents}
*/

async function bundleFilesForUpload(){
  
    let filesDataObj = [];
    let copy = {fileInfo:{"ogname":"","meme":""},fileData:""};
    
  
    for(let i = 0 ; i < counters.localVar.counters.filesForUploadArr.length ; i++){
  
      let tempObj = JSON.parse(JSON.stringify(copy));
  
  
  
        let file = counters.localVar.counters.filesForUploadArr[i];
  
        tempObj.fileInfo.ogname = file.name;
        tempObj.fileInfo.meme = file.type;
        tempObj.fileData = await readFile(file).then((file)=>{
          file =  btoa(file);
          return file;
        }).then((file)=>{
          return file;
        })
  
        filesDataObj.push(tempObj);
  
    
      }
     
    
  
    return filesDataObj;
  
  }
  
  async function readFile (file){
  
    const toBinaryString = file => new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.readAsBinaryString(file);
      reader.onload = () => resolve(reader.result);
      reader.onerror = error => reject(error);
  });
  
  let parsedFile = null;
  parsedFile =  await toBinaryString(file);
  
    return parsedFile;
  }

/*From doPost downward, we read the file Array convert the base64 to blob and make a file in google drive using the blob and metadata we have, you may also see some sheet code, I'm using sheet as db for this */


//in buit function doPost in Code.gs
doPost(e){
  const myDataObj = JSON.parse(e.postData.contents);
  mainFileFunc(myDataObj.params[0].dataObj.images);
  //the actual object structure might look different from yours, console log around
  }

function mainFileFunc(fileArr) {

  let myArrObj = [{"madeit":"toFileF"}];
  let copy = JSON.parse(JSON.stringify(myArrObj[0]));
 

  //sheet.getRange("A1").setValue(JSON.stringify(fileArr.length));

  for(let i=0 ; i < fileArr.length ; i++){

    myArrObj.push(copy);
   let blob = doFileStuff(fileArr[i].data,fileArr[i].info[0].mime,fileArr[i].id);
    myArrObj[i] =  uploadFileOne(blob,fileArr[i].id);
    myArrObj[i].mime = fileArr[i].info[0].mime;
    myArrObj[i].realName = fileArr[i].name;

  //  sheet.getRange("A"+(i+1)).setValue(myArrObj[i].name);
   // sheet.getRange("B"+(i+1)).setValue(myArrObj[i].url);
   // sheet.getRange("C"+(i+1)).setValue(myArrObj[i].mime);
   // sheet.getRange("D"+(i+1)).setValue(myArrObj[i].size);
    

  }

  return myArrObj;
  
}


function doFileStuff(filedata,filetype,filename){
  
  
  var data = Utilities.base64Decode(filedata, Utilities.Charset.UTF_8);
  var blob = Utilities.newBlob(data,filetype,filename);
  

  
  return blob;
  
  
}


function uploadFileOne(data,filename) {
 let myObj = {} 
myObj["name"] = "";
myObj["realName"] = "Story_Picture";
myObj["url"] = "";
myObj["mime"] = "";
myObj["size"] = "";
myObj["thumb"] = "nonety";
   
  
  var folders = DriveApp.getFoldersByName("LadhaWeb");
 while (folders.hasNext()) {
 var folder = folders.next();
 folder.createFile(data);
}
  
  
var files = DriveApp.getFilesByName(filename);
 while (files.hasNext()) {
 var file = files.next();
 myObj.name = file.getName();
 myObj.url = file.getUrl();
 myObj.mime = file.getMimeType();
myObj.size = file.getSize();

  }

 return myObj;

}

You can view the full frontend code for this project here and the backend here.

Hope this helps someone.

Related