Half of information uploaded, only images no data in google sheets - google-apps-script

I created an app that at the same time sends data to a google sheet and image to a drive where the uploaded image URL is displayed alongside the data sent.
My issue is that the image is uploaded properly with the date and time in the title but my data aren't sent to the google script.
I tried but didn't found any workable solution.
here is my code
function doGet(e) {
SpreadsheetApp.openById('XXXXXXXXXXXXXXX').getSheetByName("Test_Sheet");
return addUser(e);
}
function doPost(e) {
SpreadsheetApp.openById('XXXXXXXXXXXXXXX').getSheetByName("Test_Sheet");
return addUser(e);
}
function addUser(e) {
var tag1 = e.parameter.tag1;
var tag2 = e.parameter.tag2;
var nameTag = e.parameter.nameTag;
var mimetypeTag = e.parameter.mimetypeTag;
var dataTag = e.parameter.dataTag;
var filename = nameTag + Utilities.formatDate(new Date(), "GMT+4", "dd-MM-yyyy HH:mm");
var data = Utilities.base64Decode(dataTag);
var blob = Utilities.newBlob(data, mimetypeTag, filename);
var file = DriveApp.getFolderById('XXXXXXXXXXXXXXX').createFile(blob).getID();
file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
var fileId = file.getId();
var fileUrl = "https://drive.google.com/uc?export=view&id=" + fileId;
var sheet = SpreadsheetApp.openById('16T_51Xtjm5udbYBAEfSbNpo--ox9PQZddT39Ty0Zky8').getSheetByName("Test_Sheet");
sheet.appendRow([tag1, tag2, nameTag, mimetypeTag, dataTage, filename, fileUrl])
return ContentService.createTextOutput("Data uploaded");
}

Replace dataTage with dataTag.

Related

Google apps script running slow

I have a homemade script for saving attachments to Drive from Gmail. I'm looping through the attachments and Logging the time when each attachment is saved. I've noticed some weird discrepancies between some saves. As the following image shows. Sometimes there is a minute and a half between loops. Each file is a pdf and they are all roughly the same size, e.g. 100 kb. each. It's not unusual that this script processes 50 attachments from a single email.
My for loop is as follows:
for (var k in attachments) {
var attachment = attachments[k];
var isDefinedType = checkIfDefinedType_(attachment);
if (!isDefinedType) continue;
var attachmentBlob = attachment.copyBlob();
var file = DriveApp.createFile(attachmentBlob);
if (parentFolder.addFile(file)) {
root.removeFile(file);
writeToSheet(file, message, msgId, k, totalattachments)
}
}
Below are the relevant functions.
function checkIfDefinedType_(attachment) {
var fileName = attachment.getName();
var temp = fileName.split('.');
var fileExtension = temp[temp.length - 1].toLowerCase();
if (fileTypesToExtract.indexOf(fileExtension) !== -1) return true;
else return false;}
function writeToSheet(file, message, msgId, k, totalattachments) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var fileId = file.getId();
var fileUrl = file.getUrl();
var formattedDate = Utilities.formatDate(new Date(), "GMT", "dd-MM-yyyy HH:mm:ss");
var emailSubject = message.getSubject();
var emailFrom = message.getFrom();
var sheet = ss.getSheetByName('Log');
sheet.appendRow([msgId, formattedDate, emailFrom, emailSubject, k, totalattachments, file, fileId, fileUrl]);}
Is there something wrong with my code?
Well turns out, saving a file to the root, then copying it to another directory and then delete the original file takes longer than just put it in the correct directory to begin with.
I changed this:
var file = DriveApp.createFile(attachmentBlob);
if (parentFolder.addFile(file)) {
root.removeFile(file);
}
to this:
var file = parentFolder.createFile(attachmentBlob);
Although I'm pretty sure this method wasn't always possible. Maybe I'm mistaken.

Google Apps Script - Using URL of File in Drive in =IMAGE() Spreadsheet Formula

In the below code, I'm getting the URL of a file in my Drive and using that in the formula =IMAGE(). However, the image isn't being displayed in the cell. I copied and pasted the URL that was being retrieved into my browser and it pulls up the image file. I also tried entering a different URL (from a Google image search) and it displayed the image in the cell. Here is a snippet of my code that isn't working:
//Function to populate Packing Instructions sheet
function createPackingInstructions() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var entryFormSheet = ss.getSheetByName('Entry Form');
var packingInstructionsSheet = ss.getSheetByName('Packing Instructions');
var poNumber = entryFormSheet.getRange(2, 2).getValue();
var drive = DriveApp;
var proofHorizontal = drive.getFilesByName('PO ' + poNumber + ' Proof Horizontal.png');
var proofRange = packingInstructionsSheet.getRange(1, 7);
Logger.log(poNumber);
//Starts by clearing the Instructions sheet
packingInstructionsSheet.getRange(11, 1, 30, 11).clear();
proofRange.clearContent();
Logger.log(proofHorizontal.hasNext());
//Gets image file URL
while (proofHorizontal.hasNext()) {
var file = proofHorizontal.next();
var proofName = file.getName();
var proofUrl = file.getUrl();
Logger.log(proofName);
Logger.log(proofUrl);
proofRange.setFormula('IMAGE("' + proofUrl + '", 1)');
}
}
I adjusted the code based on the advice in here to use the permalink version of the URL, but it has the same behavior; it inputs the formula correctly and the URL works when entered into my browser, but the image won't display in the cell. Here is the updated code:
//Function to populate Packing Instructions sheet
function createPackingInstructions() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var entryFormSheet = ss.getSheetByName('Entry Form');
var packingInstructionsSheet = ss.getSheetByName('Packing Instructions');
var poNumber = entryFormSheet.getRange(2, 2).getValue();
var drive = DriveApp;
var proofHorizontal = drive.getFilesByName('PO ' + poNumber + ' Proof Horizontal.png');
var proofRange = packingInstructionsSheet.getRange(1, 7);
var baseUrl = "http://drive.google.com/uc?export=view&id=";
Logger.log(poNumber);
//Starts by clearing the Instructions sheet
packingInstructionsSheet.getRange(11, 1, 30, 11).clear();
proofRange.clearContent();
Logger.log(proofHorizontal.hasNext());
//Gets image file URL
while (proofHorizontal.hasNext()) {
var file = proofHorizontal.next();
//file.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.VIEW);
var proofId = file.getId();
var proofUrl = baseUrl+proofId;
Logger.log(proofUrl);
proofRange.setFormula('IMAGE("' + proofUrl + '", 1)');
}
}
Necro-ing my own questions, since I found a working solution:
My second code example above was close, but you need to use the "download" version of the URL, not the "view" version. See below:
var baseUrl = "https://drive.google.com/uc?export=download&id=";
//Gets image file URL
while (proofHorizontal.hasNext()) {
var file = proofHorizontal.next();
//This line may be necessary, depending on permissions
//file.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.VIEW);
var proofId = file.getId();
var proofUrl = baseUrl+proofId;
}
Here is a link to some info on this: https://blog.appsevents.com/2014/04/how-to-bypass-google-drive-viewer-and.html

Google script save / update file

I am again creating a simple script to save a daily menu cart. Aim is, that the file (PDF) can be shared with a static link. Base for the PDF is a Google spreadsheet.
Currently I have the following code:
// Add new menu to sheet
function onOpen() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [
{name: "Speichern", functionName: "savepdf"},
];
spreadsheet.addMenu("Als PDF speichern", entries);
};
// Add function to save sheet as PDF
function savepdf () {
// Get spreadsheet file
var fileid = 'FILEIDGOESHERE';
// Create date for file name
var ss = SpreadsheetApp.openById(fileid);
var name = ss.getName();
var sheet = ss.getSheetByName('Tageskarte');
var range = sheet.getRange(12,1);
var d = range.getValue();
var curr_date = d.getDate();
var curr_month = d.getMonth() + 1;
var curr_year = d.getFullYear();
var theDate = curr_year + "-" + curr_month + "-" + curr_date + "-";
var namearchive = "Tageskarte-"+ theDate +".pdf";
var name = "Tageskarte-Allweglehen.pdf";
// Choose folder where PDFs are saved
var foldersave=DriveApp.getFolderById('FOLDERIDGOESHERE');
var foldersavearchive=DriveApp.getFolderById('FOLDERIDGOESHERE');
// OAuth
var request = {
"method": "GET",
"headers":{"Authorization": "Bearer "+ScriptApp.getOAuthToken()},
"muteHttpExceptions": true
};
// Create PDF + update current file
var fetch='https://docs.google.com/spreadsheets/d/'+fileid+'/export?format=pdf&size=A4&portrait=true&gridlines=false'
var pdf = UrlFetchApp.fetch(fetch, request);
pdf = pdf.getBlob().getAs('application/pdf').setName(name);
var file = foldersave.createFile(pdf);
// Create PDF for archive and save
var pdfarchive = UrlFetchApp.fetch(fetch, request);
pdfarchive = pdfarchive.getBlob().setName(namearchive);
var file = foldersavearchive.createFile(pdfarchive);
}
/*
fmcmd=12
size=legal/A4
fzr=true/false
portrait=false/true
fitw=true/false
gid=0/1/2
gridlines=false/true
printtitle=false/true
sheetnames=false/true
pagenum=UNDEFINED
attachment=false/true
*/
My problem is the point "Create PDF + update current file. The code is saving a new file with the same name, but than I have of course a new static share link of the menu.
I think I have to use something with the "getblob" function to update the current file.
Would be very good, if anybody would have an idea.
Many thanks.
I was able to find a working solution with Drive.Files.update
// Create PDF + update current file
var fetch='https://docs.google.com/spreadsheets/d/'+fileid+'/export?format=pdf&size=A4&portrait=true&gridlines=false'
var pdf = UrlFetchApp.fetch(fetch, request);
pdf = pdf.getBlob().getAs('application/pdf').setName(name);
var deleteexisting = foldersave.getFilesByName(name);
if (deleteexisting.hasNext() === false) {
// if no file is found then create it
foldersave.createFile(pdf);
} else {
while (deleteexisting.hasNext()) {
var updatedPDF = deleteexisting.next();
Drive.Files.update({mimeType: 'application/pdf'}, updatedPDF.getId(), pdf);
}
}

How to write google script to automatically call data from a google folder drive that contains a CSV file into one Google Sheets

I am trying to write a google script that will allow me to go into my google drive folder called "MeadJohsnon" and pull 'Temperature Calibration.csv' to google sheets. I have never used google script before. Currently I have the "Save Email and Attachment" Add-ons. This add-on is pulling .cvs files that my team is sending me from the field. They use "TapForms" and then send the form via email to my gmail. So, I got the email sending that attachment to my google drive but I need help with the script, so Drive will automatically get those .cvs files and put the information into one google sheet. I say ONE google sheet because although I have a team sending in forms, all the forms have the same information on them.
This is what I have done so far. The fourth line gives me a
function loadingCSV() {
var ss=SpreadsheetApp.getActiveSpreadsheet()
var sht=ss.getActiveSheet();
sht.clearContents();
var data = loadFile();
var dataA =Utilities.parseCsv(data);
var rng = sht.getRange(1, 1, dataA.length, dataA[0].length);
rng.setValues(dataA);
}
I would just like feedback on how to fix my error or what I could do instead. As stated this is my first time using google script, my specialty is ASP.net lol not script. Thank you.
function loadingCSV() {
var ss=SpreadsheetApp.getActiveSpreadsheet()
var sht=ss.getActiveSheet();
sht.clearContents();
var data = loadFile();
var dataA =Utilities.parseCsv(data);
var rng = sht.getRange(1, 1, dataA.length, dataA[0].length);
rng.setValues(dataA);
}
function loadFile(filename,folderID)
{
var filename = (typeof(filename) !== 'undefined')? filename : 'Temperature Calibration.csv';
var folderID = (typeof(folderID) !== 'undefined')? folderID : '0B8m9xkDP_TJxUUlueHhXOWJMbjg';
var fldr = DriveApp.getFolderById(folderID);
var file = fldr.getFilesByName(filename);
var s = '';
while(file.hasNext())
{
var fi = file.next();
var target = fi.getName();
if(target == filename)
{
s = fi.getBlob().getDataAsString();
}
}
return s;
}
Okay this will append the files to the active spreadsheet you'll probably have to open the spreadsheet by id and use getSheetByName to get the sheet you want because this spreadsheet probably won't be active all the time when the trigger is running. I assume the the files all end in .csv. I rename them to .old after reading the data so that the program won't read them multiple times.
function appendingCSV() {
var ss=SpreadsheetApp.getActiveSpreadsheet()
var sht=ss.getActiveSheet();
var drng = sht.getDataRange();
var lastRow = drng.getLastRow();
var data = loadFiles();
var dataA =Utilities.parseCsv(data);
if(dataA.length>0)
{
var rng = sht.getRange(lastRow + 1, 1, dataA.length, dataA[0].length);
rng.setValues(dataA);
}
else
{
SpreadsheetApp.getUi().alert('No Data Returned from LoadFiles');
}
}
function loadFiles(folderID)
{
var folderID = (typeof(folderID) !== 'undefined')? folderID : '0B8m9xkDP_TJxUUlueHhXOWJMbjg';
var fldr = DriveApp.getFolderById(folderID);
var files = fldr.getFiles();
var s='';
var re = /^.*\.csv$/i;
while (files.hasNext())
{
var file = files.next();
var filename = file.getName();
if(filename.match(re))
{
s += file.getBlob().getDataAsString() + '\n';
file.setName(filename.slice(0,-3) + 'old');
}
}
return s;
}

Downloading a PDF version of the open spreadsheet in Google Drive via scripts

I've been reading up on how to save a spreadsheet to PDF via Google Docs Scripting. Most suggestions I've come across reference using something like:
theOutputFile.saveAndClose();
DocsList.createFile(theOutputFile.getAs('application/pdf')).rename(theOutputName+".pdf");
That is, they reference the saveAndClose() function. I don't want to save or close my spreadsheet - but I do want to download the current sheet as a PDF.
Any suggestions? Thanks.
For saving the current sheet as a PDF, you can hide all the other sheets, save the current, & then show all sheets again.
The pdf creation might start before the end of the sheets' hiding and then will include 2 sheets - the current & the last sheets - in the pdf file.
Adding a sleep or a confirmation msgbox, between showOneSheet & createPdf eliminated the problem.
This answer is a variation of Marco Zoqui's answer: "To send a single sheet you may hide all other before sending" in Google Apps Script to Email Active Spreadsheet
var sheet = SpreadsheetApp.getActiveSheet();
var sheetToSave = sheet.getName();
showOneSheet(sheetToSave);
Utilities.sleep(2000);
createPdf("TestFolder", "TestPDF");
showAllSheets();
function showOneSheet(SheetToShow) {
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
for(var i in sheets){
if (sheets[i].getName()==SheetToShow){
sheets[i].showSheet();
}
else {
sheets[i].hideSheet();
}
}
}
function showAllSheets() {
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
for(var i in sheets){
sheets[i].showSheet();
}
}
function createPdf(saveToFolder, fileName){
var ssa = SpreadsheetApp.getActiveSpreadsheet();
var pdf = ssa.getAs("application/pdf");
try {
var folder = DocsList.getFolder(saveToFolder);
}
//Create Folder if not exists
catch(error){
folder = DocsList.createFolder(saveToFolder);
}
var file = folder.createFile(pdf);
file.rename(fileName);
return file;
}
I was able to get it to work using #hsgv's answer, however, this is the version I ended up using based on this.
// global save to folder variable:
var folderName = "My/Special/Folder";
function createInvoiceInGoogleDrive(){
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
// getting some values from the spreadhseet for the file name
var invoiceNumber = sheet.getRange("E3").getValue();
var vendor = sheet.getRange("A9").getValue();
var fileName = invoiceNumber + ' - ' + vendor + " - Invoice.pdf";
var pdfBlob = sheetToPDF(spreadsheet, sheet);
pdfBlob.setName(fileName);
var folder = getOrCreateFolder(folderName);
var matchingFileList = folder.find(fileName);
if ( matchingFileList.length > 0 ) {
Browser.msgBox("ERROR: New invoice not created. " + fileName + " already exists at " + folderName);
return false;
} else {
var f = folder.createFile(pdfBlob);
spreadsheet.toast('Created a new invoice on Google Drive!');
return true;
}
}
// thanks: https://gist.github.com/gregorynicholas/9008572
function sheetToPDF(spreadsheet, sheet) {
var ssID = spreadsheet.getId();
var gid = sheet.getSheetId();
// &gid=x at the end of above url if you only want a particular sheet
var url2 = "http://spreadsheets.google.com/feeds/download/spreadsheets/Export?key=" + ssID +
"&gid=" + gid +
"&fmcmd=12&size=7&fzr=true&portrait=true&fitw=true&locale=en&gridlines=false&printtitle=false&sheetnames=false&pagenum=UNDEFINED&attachment=true";
// AUTH TOKEN required to access the UrlFetchApp call below. You can receive it
// from https://appscripts.appspot.com/getAuthToken
var AUTH_TOKEN = "{GET YOUR OWN AUTH TOKEN}";
var auth = "AuthSub token=\"" + AUTH_TOKEN + "\"";
var res = UrlFetchApp.fetch(url2, {headers: {Authorization: auth}}).getBlob();
return res;
}
/**
* Get or create a folder based on its name/path
*/
function getOrCreateFolder(folderName) {
try {
var theFolder = DocsList.getFolder(folderName);
} catch(error){
var theFolder = DocsList.createFolder(folderName);
}
return theFolder;