Sunday, 16 April 2017

Using Google Apps Script, Upload file to google drive and insert data into spreadsheet

For inserting the data into the spreadsheet, i have created a sample form which is having a limited no of fields. And on the form action, i am submitting a post request to the server.
The action tag in the form is pointing to the google app script end point.
Please do watch this video for better clarity.

Also, to upload multiple files in the google drive, please refer the
updated code in the below mentioned repository.

Upload multiple files to google drive using google app script.

Here is the snippet for the html form:
<article id="content1" contenteditable="true">
<p>
<form id="uploadForm" action="Your script end point" method="POST">
<input type="hidden" value="" name="fileContent" id="fileContent">
<input type="hidden" value="" name="filename" id="filename">
<label> Name : </label><input required type="text" value="" name="name" id="name">
<label> Email :</label> <input required type="text" value="" name="email" id="email">
<label> Contact : </label><input required type="text" value="" name="contact" id="contact">
<label> SkillSets :</label> <input required type="text" value="" name="skillsets" id="skillsets">
<label> LinkedIn Account:</label><input type="text" value="" name="linkedinUrl" id="linkedinUrl">
</form>
<input required id="attach" name="attach" type="file"/>
<input value="Submit" type="button" onclick="UploadFile();" />
function UploadFile() {
var reader = new FileReader();
var file = document.getElementById('attach').files[0];
reader.onload = function(){
document.getElementById('fileContent').value=reader.result;
document.getElementById('filename').value=file.name;
document.getElementById('uploadForm').submit();
}
reader.readAsDataURL(file);
}
</p>
</article>
And Here is the google script snippet :
<article id="content2" contenteditable="true">
<p>
// Do change it your email address.
var emailTo= "emailaddress@anydomain.com"
function doPost(e) {
try {
var data = e.parameter.fileContent;
var filename = e.parameter.filename;
var email = e.parameter.email;
var name = e.parameter.name;
var result=uploadFileToGoogleDrive(data,filename,name,email,e);
return ContentService // return json success results
.createTextOutput(
JSON.stringify({"result":"success",
"data": JSON.stringify(result) }))
.setMimeType(ContentService.MimeType.JSON);
} catch(error) { // if error return this
Logger.log(error);
return ContentService
.createTextOutput(JSON.stringify({"result":"error", "error": error}))
.setMimeType(ContentService.MimeType.JSON);
}
}
// new property service GLOBAL
var SCRIPT_PROP = PropertiesService.getScriptProperties();
// see: https://developers.google.com/apps-script/reference/properties/
/**
* select the sheet
*/
function setup() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
SCRIPT_PROP.setProperty("key", doc.getId());
}
/**
* record_data inserts the data received from the html form submission
* e is the data received from the POST
*/
function record_data(e,fileUrl) {
try {
var doc = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
var sheet = doc.getSheetByName('responses'); // select the responses sheet
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
var nextRow = sheet.getLastRow()+1; // get next row
var row = [ new Date() ]; // first element in the row should always be a timestamp
// loop through the header columns
for (var i = 1; i < headers.length; i++) { // start at 1 to avoid Timestamp column
if(headers[i].length > 0 && headers[i] == "resume") {
row.push(fileUrl); // add data to row
}
else if(headers[i].length > 0) {
row.push(e.parameter[headers[i]]); // add data to row
}
}
// more efficient to set values as [][] array than individually
sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
}
catch(error) {
Logger.log(e);
}
finally {
return;
}
}
function uploadFileToGoogleDrive(data, file, name, email,e) {
try {
var dropbox = "Demo";
var folder, folders = DriveApp.getFoldersByName(dropbox);
if (folders.hasNext()) {
folder = folders.next();
} else {
folder = DriveApp.createFolder(dropbox);
}
var contentType = data.substring(5,data.indexOf(';')),
bytes = Utilities.base64Decode(data.substr(data.indexOf('base64,')+7)),
blob = Utilities.newBlob(bytes, contentType, file);
var file = folder.createFolder([name, email].join("-")).createFile(blob);
var fileUrl=file.getUrl();
//Generating Email Body
var html =
'<body>' +
'<h2> New Job Application </h2>' +
'<p>Name : '+e.parameters.name+'</p>' +
'<p>Email : '+e.parameters.email+'</p>' +
'<p>Contact : '+e.parameters.contact+'</p>' +
'<p>Skill Sets : '+e.parameters.skillsets+'</p>' +
'<p>LinkedIn Url : '+e.parameters.linkedinUrl+'</p>' +
'<p>File Name : '+e.parameters.filename+'</p>' +
'<p><a href='+file.getUrl()+'>Resume Link</a></p><br />' +
'</body>';
record_data(e,fileUrl);
MailApp.sendEmail(emailTo, "New Job Application Recieved","New Job Application Request Recieved",{htmlBody:html});
return file.getUrl();
} catch (f) {
return ContentService // return json success results
.createTextOutput(
JSON.stringify({"result":"file upload failed",
"data": JSON.stringify(f) }))
.setMimeType(ContentService.MimeType.JSON);
}
}</p>
</article>


10 comments:

  1. I am using your script to create a form that accepts file uploads and saves the data to a google sheet, however, I am having trouble figuring out how to get it to accept multiple files. Can you help me with this?

    The idea would be to create a column after the 'file' column (or 'resume' column in your example) with the name 'file_1, file_2, file_3, etc.' (or 'resume_1, resume_2, resume_3, etc.' in your example) and then write the subsequent file url to that row.

    Ideally this would be done in an iterative fashion, but I am stuck, if I get the files to process on the client side, it only uploads one file on the server (google scripts) side. Can you offer any help on this?

    ReplyDelete
    Replies
    1. Sure, I am going through the code and trying to achieve this.

      Delete
    2. @corey : I have updated the script to upload multiple files in the google drive. Please find the link below:

      https://github.com/UtkarshYeolekar/googleAppScriptUploadFiles

      Delete
  2. Not working i alosfollow Github Code
    error:ReferenceError: log is not defined (line 15, file "Code")

    ReplyDelete
  3. Hi bro, i want to change "select, textare", follow your new multiple upload file code, but sheet not receive. Pls help fix this. Thank you so much

    ReplyDelete
  4. Hi bro, i want to change "select, textare", follow your new multiple upload file code, but sheet not receive. Pls help fix this. Thank you so much

    ReplyDelete
  5. Hi bro, i want to change "select, textare", follow your new multiple upload file code, but sheet not receive. Pls help fix this. Thank you so much

    ReplyDelete
    Replies
    1. Hello, I will look into the app script code, and will revert you on this. Let me check the code. Also you can share your html part of the code as well, so I can reproduce it on my side.

      Delete
  6. Thanks for the code, it works great.
    Is there a way to add a validation error message for required fields when submitting the form? And a loading button when the file is being uploaded and when the form is being submitted?

    ReplyDelete