Script working when manually triggered but time trigger fails - javascript

I have a google script to add the data of the latest csv file in google folder below the last row of data in a mastersheet. The script works well when I run it manually, however when I set up a time trigger, the script fails with error message:
ERROR
No item with the given ID could be found, or you do not have permission to access it. at importData(Code:5)
My script is below. Can anyone assist? Thanks in advance.
function importData(folderID)
{
var ss = SpreadsheetApp.openById(my spreadsheet id);
var folderID = (typeof(folderID) !== 'undefined')? folderID : 'my folder id';//default folderID
var fldr = DriveApp.getFolderById(folderID);
var files = fldr.getFiles();
var dt = Utilities.formatDate(new Date(), Session.getScriptTimeZone(),"yyyyddMM");
var re =new RegExp('^' + "11286321_" + dt + '.*\.csv$','i');
while (files.hasNext())
{
var file = files.next();
var filename = file.getName();
if(filename.match(re))
{
var csvstr=file.getBlob().getDataAsString();
var csvData=Utilities.parseCsv(csvstr);
var sheet = ss.getSheetByName("EwayPayments");
var lastrow = sheet.getLastRow();
sheet.getRange(lastrow + 1, 1, csvData.length, csvData[0].length).setValues(csvData);
file.setName(filename.slice(0,-3) + 'old'); //the .old files won't pass the file re filter next time.
}
}
}

Related

I need 2 different buttons, to create new folder and create a new PDF in that folder

I've been struggling to build a specific weekly stock system reports. So to give you a basic overview, I have a mastersheet that I want to generate reports from, triggered by an UI button. The first step however is to create a folder for that week to place the PDF's in. I can create the folder, and I can generate the PDF in my root Google Drive folder, but I can't seem to move the PDF anywhere after that. I have attempted to use .moveTo() but I can't get that to work. Does anyone have any advise?
function onOpen(e)
{
SpreadsheetApp.getUi()
.createMenu('Physical')
.addItem('New folder','newFolder')
.addItem('Generate PDF','generatePDF')
.addToUi();
}
function newFolder(){
var today = new Date();
var week = Utilities.formatDate(today, "Europe/Amsterdam", "w"); //need to find a way to minus 1 for the current week
var spreadsheetId = SpreadsheetApp.getActiveSpreadsheet().getId(); //time to create a new folder
var spreadsheetFile = DriveApp.getFileById(spreadsheetId);
var folderId = spreadsheetFile.getParents().next().getId();
var parFolder = DriveApp.getFolderById(folderId)
var destFolder = parFolder.createFolder('Week ' + week);
}
function generatePDF(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var speadsheetFile = ss.getId();
var file = DriveApp.getFileById(speadsheetFile);
var folderId = file.getParents().next().getId();
var pdf = DriveApp.createFile(ss.getBlob())
pdf.moveTo(folderId); //find way to move file either to destination folder or to parent folder
}
Description
These types of situations are hard to test because the circumstances are specific to the OP questioner. However, I believe this will work.
Using the PropertyService Script Properties, store the newly created folderId and then get that id from Script Properties to move the file.
A note of caution, I didn't check for the case if the week changes and a new folder is not created, the pdf will go to the previous week folder.
Regarding creating a button and linking a function to the button see this article Buttons in Google Sheets
Script
function newFolder(){
var today = new Date();
var week = Utilities.formatDate(today, "Europe/Amsterdam", "w"); //need to find a way to minus 1 for the current week
var spreadsheetId = SpreadsheetApp.getActiveSpreadsheet().getId(); //time to create a new folder
var spreadsheetFile = DriveApp.getFileById(spreadsheetId);
var folderId = spreadsheetFile.getParents().next().getId();
var parFolder = DriveApp.getFolderById(folderId);
var folderName = 'Week '+week;
// check if folder already exists
var subFolders = parFolder.getFoldersByName(folderName);
var destFolder = null;
if( subFolders.hasNext() ) {
SpreadsheetApp.getUi().alert("Folder "+folderName+" already exists");
destFolder = subFolders.next();
}
else {
destFolder = parFolder.createFolder(folderName);
}
// store folder id to Script Properties
var props = PropertiesService.getScriptProperties();
props.setProperty("foldeId",destFolder.getId());
}
function generatePDF(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
// get folder id from Script Properties
var folderId = PropertiesService.getScriptProperties("folderId");
if( !folderId ) {
SpreadsheetApp.getUi().alert("Property folderId not found");
return;
}
var pdf = DriveApp.createFile(ss.getBlob())
pdf.moveTo(folderId); //find way to move file either to destination folder or to parent folder
}
Reference
SpreadsheetApp.getUi().alert()
PropetiesService

Google Apps Script: trying to read a text file from Google Drive with .getAs(MimeType.PLAIN_TEXT)

I'm stuck into trouble trying to read an HTML file from a Google Drive. So
I tried :
to get a text with a help of UrlFetchApp.fetch("https://googledrive.com/host/{folderID}/{filename}.html"), but it fetches some google css file instead of mine.
to convert a file from blob to a text string with file.getAs(MimeType.PLAIN_TEXT), and it just outputs "Blob" without any file content. How can I extract a file text without any specific libraries?
var dApp = DriveApp;
var folderIter = dApp.getFoldersByName("Лаборатории ФББ");
var folder = folderIter.next();
var filesIter = dApp.getFilesByName("Labs.html");
var filelist = [];
var propfiledate = 0;
var propfilename;
while(filesIter.hasNext()){
var file = filesIter.next();
var filename = file.getName();
var fileurl = file.getUrl();
var filedate = file.getDateCreated();
if(filedate >= propfiledate){
var propfiledate = filedate;
var propfileurl = fileurl;
var propfilename = filename;
var propfile = file;
}
}
Logger.log(propfile);
// 1st try var myHtmlFile = UrlFetchApp.fetch(propfileurl);
// 2nd try var myHtmlFile = propfile.getAs(MimeType.PLAIN_TEXT);
// 3rd try var myHtmlFile = propfile.getBlob().text();
var ss = SpreadsheetApp.create("test");
SpreadsheetApp.setActiveSpreadsheet(ss);
var sheet = ss.getActiveSheet();
sheet.appendRow(myHtmlFile.toString().split("\n"));
Logger.log(propfiledate);
Logger.log(propfilename);
Logger.log(propfileurl);
}
Using Apps Script on a dummy HTML file, you can get the HTML data that is inside of it.
Using DriveApp getFilesByName(name) method you retrieve the file by the name.
This will return a FileIterator since there can be many files with similar names.
Then you can get the file blob with getBlob() and the blob data as a string with getDataAsString()
I have managed to get the dummyHTML.html file data by using this previously mentioned methods:
function myFunction() {
var files = DriveApp.getFilesByName("dummyHTML.html");
while (files.hasNext()) {
var file = files.next();
Logger.log(file.getBlob().getDataAsString());
}
}

Trying to get folder path of file in Google Apps Script

I am trying to create a function in Google Apps Script that finds the file path of the folder.
Here is the error: TypeError: Cannot read property 'appendParagraph' of null (line 20, file "Code")
function getRoot() {
var doc = DocumentApp.getActiveDocument();
var header = DocumentApp.getActiveDocument().getHeader();
var name = doc.getName();
var id = doc.getId();
var txt = "Master Folder";
var parents = [];
var folders = DriveApp.getFileById(id).getParents();
while (folders.hasNext()){
var parent = folders.next();
var n = parent.getName();
parents.push(n);
}
var pLen = parents.length;
for (i = 0; i < pLen; i++){
txt = txt + "//" + parents[i];
}
var headerPar = header.appendParagraph(txt);
}
I believe your goal as follows.
You want to know the reason of the error message of TypeError: Cannot read property 'appendParagraph' of null.
You want to remove the error.
You want to retrieve the folder path of the active Google Document.
For this, how about this answer?
Modification points:
In your script, I think that the reason of your error message is the header is not existing in the Google Document. By this, header retrieved by getHeader() is null, and then, the error occurs. So in this case, please add the header using addHeader().
doc of var doc = DocumentApp.getActiveDocument(); can be used for getHeader().
If you want to retrieve the folder path from the root folder, I think that your script is required to be modified. In your current script, when the Google Document is put in the nested folders, only parent of the Document is retrieved.
When your script is modified using above points, it becomes as follows.
Modified script:
function getRoot() {
var doc = DocumentApp.getActiveDocument();
var header = doc.getHeader() || doc.addHeader(); // Modified
var name = doc.getName();
var id = doc.getId();
var txt = "Master Folder";
var parents = [];
var folders = DriveApp.getFileById(id).getParents();
// --- I modified below script
while (folders.hasNext()) {
var folder = folders.next();
parents.push(folder.getName());
folders = folder.getParents();
}
parents = parents.reverse();
// ---
var pLen = parents.length;
for (i = 0; i < pLen; i++){
txt = txt + "//" + parents[i];
}
var headerPar = header.appendParagraph(txt);
}
By this modification, when the header is existing, doc.getHeader() is used. When the header is not existing, doc.addHeader() is used. And, when the active Document is put to the folder path like root -> folder1 -> folder2, Master Folder//MyDrive//folder1//folder2 is put to the header.
References:
getHeader()
addHeader()

Fail to Send an email with attachment using Google Apps Script

function SendEmails() {
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Name List").activate();
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
var lr = ss.getLastRow();
var templateText = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Email Template").getRange(1, 1).getValue();
var quotaLeft = MailApp.getRemainingDailyQuota();
//Logger.log(quotaLeft);
if ((lr-1) > quotaLeft){
Browser.msgBox("You have " + quotaLeft + " left and you're trying to send " + (lr-1) + "emails. Emails were not sent.");
} else {
for (var i = 2;i<=lr;i++){
var currentName = ss.getRange(i, 1).getValue();
var currentAppNo = ss.getRange(i, 2).getValue();
var currentEmail = ss.getRange(i, 3).getValue();
var messageBody = templateText.replace("{First Name}",currentName).replace("{App No}",currentAppNo);
var subjectLine = "CONGRATULATION ON YOUR VAL APPROVAL " + currentName
var attachmentBody = DriveApp.getFilesByName("THE ROOM SCRIPT.pdf");
MailApp.sendEmail(currentEmail, subjectLine, messageBody)
} //close for loop
} //close else statement
}
I have a Google Spreadsheet with a list of emails. I want to build a routine that sends email automatically to those email addresses. I also want to attach a PDF to this email. The PDF file is located on my Google Drive.
This does not seem to work
Here are two things that you may want to change in your script.
getFilesByName() gets a collection of files (as a FileIterator object) with that name. If there is just one such file, you'll need to change that line to
var attachmentBody = DriveApp.getFilesByName("THE ROOM SCRIPT.pdf").next; // To get the first such file
Ref doc here.
As #ross said, the sendMail() function needs to include the attachment like so:
MailApp.sendEmail(currentEmail, subjectLine, messageBody, {
attachments: [attachmentBody.getAs(MimeType.PDF)]
});
Ref doc here.

Google Drive + Script throws permissions error even through I'm owner and granted permission

I'm trying to create a basic script on a 12-hour timer trigger that loops through each of my Google Calendars by their ICAL URL, and downloads the ICAL for a folder on my Google Drive (for backup purposes). It throws this error
"No item with the given ID could be found, or you do not have permission to access it. (line 23, file "Code")" (Line #23 is var folder... )
Running the script does download and save the ICAL file on the first run through the loop (and if I manually pass in each unique ICAL URL one at a time), but the error then terminates the loop. Seeing as how I've authorized access already and am the owner of everything here, I'm not sure what else I need.
var calendarsToSave = [
"https://calendar.google.com/calendar/ical/inXXXXXXX.com/privateXXXX/basic.ics",
"https://calendar.google.com/calendar/ical/XXXXX.com_XXXXXXup.calendar.google.com/private-XXXXXXX/basic.ics"
];
var folder = '123xxxxxxxxv789'; // my gdrive folder
function downloadFile(calendarURL,folder) {
var fileName = "";
var fileSize = 0;
for (var i = 0; i < calendarsToSave.length; i++) {
var calendarURL = calendarsToSave[i];
var response = UrlFetchApp.fetch(calendarURL, {muteHttpExceptions: true});
var rc = response.getResponseCode();
if (rc == 200) {
var fileBlob = response.getBlob()
var folder = DriveApp.getFolderById(folder); // << returns a permissions error thus terminating the for loop
var file = folder.createFile(fileBlob);
fileName = file.getName();
fileSize = file.getSize();
}
var fileInfo = { "rc":rc, "fileName":fileName, "fileSize":fileSize };
return fileInfo;
} // end for loop
}
Updated: You are also re-initializing a variable that already exists from the parameters and as a global variable so we can remove the parameter if you want to keep the global variable.
We can also move the place where you get the Google Folder object. It stays the same every time so we don't need to retrieve it again.
var calendarsToSave = [
"https://calendar.google.com/calendar/ical/inXXXXXXX.com/privateXXXX/basic.ics",
"https://calendar.google.com/calendar/ical/XXXXX.com_XXXXXXup.calendar.google.com/private-XXXXXXX/basic.ics"
];
var folder = '123xxxxxxxxv789'; // my gdrive folder
function downloadFile(calendarURL) {
var fileName = "";
var fileSize = 0;
var gfolder = DriveApp.getFolderById(folder);
for (var i = 0; i < calendarsToSave.length; i++) {
var calendarURL = calendarsToSave[i];
var response = UrlFetchApp.fetch(calendarURL, {muteHttpExceptions: true});
var rc = response.getResponseCode();
if (rc == 200) {
var fileBlob = response.getBlob()
var file = gfolder.createFile(fileBlob);
fileName = file.getName();
fileSize = file.getSize();
}
var fileInfo = { "rc":rc, "fileName":fileName, "fileSize":fileSize };
return fileInfo;
} // end for loop
}
Let see where that gets us.
Your "folder" variable is outside the function, causing the data to be inaccessible to the "downloadFile" function.
Google apps coding seems to require variables to be in a function to be defined. I would recommend moving both "calendarsToSave" and "folder" to the inside of "downloadFile"
Here is an example that will return your error:
var folder = '1HSFBPfPIsXWvFEb_AalFYalkPwrOAyxD';
function myFunction() {
var folder = DriveApp.getFolderById(folder);
var name = folder.getName();
Logger.log(name);
}
And here is one that will return the file name:
function myFunction() {
var folder = '1HSFBPfPIsXWvFEb_AalFYalkPwrOAyxD';
var folder = DriveApp.getFolderById(folder);
var name = folder.getName();
Logger.log(name);
}

Categories

Resources