Iterate over gmail threads and add a label with addlabel - javascript

I wish to run this standalone code twice a day, but cannot solve the exception on the addLabel, which is "impossible to find the method", any suggestion? I tried to change the for cycle as well as to assign a var to the threads[i] but nothing changed.
function salvaNote(){
var d = new Date();
d.setMonth(d.getMonth()-6);
var n = d.getFullYear() + "/" + addZero(d.getMonth()+1) + "/" + addZero(d.getDate());
var folderName = 'tavoloTecnico';
labelName = GmailApp.createLabel('tavoloTecnico');
var query = 'in:anywhere from:mariano.casillo#mit.gov.it OR from:donato.castigliego#mit.gov.it has:attachment subject:previsioni filename:xls '+ 'after:'+n;
var threads = GmailApp.search(query);
var quanteMail = threads.length;
for ( var i = 0 ; i < quanteMail; i++) {
threads[i].addLabel(labelName);
var mesgs = threads[i].getMessages();
for(var j in mesgs){
var attachments = mesgs[j].getAttachments();
for(var k in attachments){
var attachment = attachments[k];
var attachmentBlob = attachment.copyBlob();
var file = DriveApp.createFile(attachmentBlob);
DriveApp.getFoldersByName(folderName).next().addFile(file);
}
}
}
}

Related

Certain number question being missed in regex

I have the following if statement that removes the first instances of a number followed by the period. However, I am noticing it is missing to catch some of them (ex. "16.", "23.", "24.", etc.) and not sure why.
Here is the function:
function quesCleanUp(ques){
//Checks the first instance of "." and removes it and the number
if(ques.match(/[0-9]\./g)?.length > 1){//(ques.match(/./g)?.length > 1){
var quesClean = ques.replace(/^[^\.]*\./, '').trim();
} else{
var quesClean = ques.trim();
}
return quesClean;
}
The following for loop extracts the question from the google form:
for (var i = 0; i < items.length; i++) {
var item = items[i];
switch(item.getType()) {
case FormApp.ItemType.MULTIPLE_CHOICE:
var question = item.asMultipleChoiceItem();
var ques = quesCleanUp(question.getTitle().trim());//replace(/\s/g, "");
var question_type = "Multiple Choice";
var optns = [];
var answr;
var answers = question.getChoices();
answer_val = false;
for (var j = 0; j < answers.length; j++) {
var clean = answers[j].getValue().trim();
optns.push(clean);
if(answers[j].isCorrectAnswer()){
answr = answers[j].getValue().trim();
for(var x = 0; x < optns.length; x++){
if(answr == optns[x]){
answer_val = true;
break;
}
}
}
}
var multiJSON = makeJSON(ques, question_type, optns, answr);
console.log("JSON1: " + JSON.stringify(multiJSON));
constructedJSON[i+1] = multiJSON;
break;
case FormApp.ItemType.CHECKBOX:
var question = item.asCheckboxItem();
//var ques = question.getTitle().trim();//.replace(/\s/g, "");
var ques = quesCleanUp(question.getTitle().trim());//replace(/\s/g, "");
var question_type = "CheckBox";
var optns = [];
var answr = [];
var answers = question.getChoices();
for (var j = 0; j < answers.length; j++) {
var clean = answers[j].getValue().trim();//replace(/\s/g, "");
optns.push(clean);
if(answers[j].isCorrectAnswer()){
answr.push(answers[j].getValue().trim());
}
}
var checkJSON = makeJSON(ques, question_type, optns, answr);
console.log("JSON2: " + JSON.stringify(checkJSON));
constructedJSON[i+1] = checkJSON;
break;
case FormApp.ItemType.PARAGRAPH_TEXT:
var question = item.asParagraphTextItem();
//var ques = question.getTitle().trim();//.replace(/\s/g, "");
var ques = quesCleanUp(question.getTitle().trim());//replace(/\s/g, "");
var question_type = "free response";
var optns = [];
var answr;
var paraJSON = makeJSON(ques, question_type, optns, answr);
console.log("JSON3: " + JSON.stringify(paraJSON));
constructedJSON[i+1] = paraJSON;
break;
case FormApp.ItemType.TEXT:
var question = item.asTextItem();
//var ques = question.getTitle().trim();
var question_type = "free response";
var ques = quesCleanUp(question.getTitle().trim());//replace(/\s/g, "");
var optns = "";
var answr = "";
var textJSON = makeJSON(ques, question_type, optns, answr);
console.log("JSON4: " + JSON.stringify(textJSON));
constructedJSON[i+1] = textJSON;
break;
}
The following example is the type of question 16. What is the meaning of life?
And the expected output: What is the meaning of life?
Try using /[0-9]+./g to catch more than one digit
As a quick fix, in the function quesCleanUp() try to change the line:
if(ques.match(/[0-9]\./g)?.length > 1){//(ques.match(/./g)?.length > 1){
With:
if (ques.match(/^[0-9]+\./g).length > 0) {
I suspect you got the downvotes because you posted the code with glared typos. It looks like you didn't even try to debug it first. And as the icing on the cake you accepted a wrong answer.
And probably the function can be boiled down to just one line:
const quesCleanUp = q => q.replace(/^\d+\./,'').trim();
Here is how it works:
var questions = ['1. aaa', '16. What', '23. That', 'No nums'];
const quesCleanUp = q => q.replace(/^\d+\./,'').trim();
questions.forEach(q => console.log(quesCleanUp(q)));
Expected output:
aaa
What
That
No nums

Bootstrap modal populated by selected row in table data

The code below works fine on my computer, however when I am trying it on different workstations it does not work unless you do a hard refresh SHIFT + F5 then it will work but, when the page is reloaded it will go back to not working. Any help if you can tell me where this script is wrong would be greatly appreciated.
function run() {
var table = document.getElementById('call-logs-table');
var rows = table.rows;
for (var i=0; i<rows.length; i++) {
rows[i].onclick = function (event) {
var cells = this.cells;
var person_contacted = cells[0].innerHTML;
var date = cells[1].innerHTML;
var c_purpose = cells[2].innerHTML;
var c_notes = cells[3].innerHTML;
var sales_rep = cells[4].innerHTML;
var timestamp = cells[5].innerHTML;
var potential = cells[6].innerHTML;
var catalog_num = cells[7].innerHTML;
var dateplanner_num = cells[8].innerHTML;
var calendar_num = cells[9].innerHTML;
document.getElementById('call-log-title').innerHTML = 'Call Log Entered at ' + timestamp + ' by ' + sales_rep;
document.getElementById('lbl_contact').innerHTML = person_contacted;
document.getElementById('lbl_date').innerHTML = date;
document.getElementById('lbl_catalogs').innerHTML = catalog_num;
document.getElementById('lbl_calendars').innerHTML = calendar_num;
document.getElementById('lbl_planners').innerHTML = dateplanner_num;
document.getElementById('lbl_purpose').innerHTML = c_purpose;
document.getElementById('lbl_notes').innerHTML = c_notes;
document.getElementById('lbl_potential').innerHTML = potential;
};
}
}
window.onload = function() { run(); }

Google App script takes 10 mins for one function but exceeds time limit when replicated

first time poster so I apologise if if im not following the correct etiquette.
So I have code that, in essence, creates 70 forecast docs in specified folders. This works fine.
I have used the same code, repointed the all the folder references, but now times out.
Code is as follows, any suggestions on how I can make this run faster?
function createFiles(weeknr, masterIDs, masterfolders, mastercodes, archivefolders) {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var date = new Date()
var textdate = Utilities.formatDate(date, "Europe/London", "dd/MM/YYYY HH:mm")
var fileslog = ss.getSheetByName("FileList")
var year = date.getYear()
var mainfolder = DriveApp.getFolderById("1HdG3eJZrIMF-CRpx17Reqdyd7JM5v5ZW")
var weekfolder = mainfolder.createFolder('Week ' + weeknr + ' ' + year)
var tempArray = []
for (var i = 0; i < masterIDs.length; i++) {
// for (var i=0;i<masterIDs.length;i++){
var folderID = masterfolders[i]
var masterID = masterIDs[i]
var code = mastercodes[i]
var archivefolder = archivefolders[i]
var newfile = DriveApp.getFileById(masterID).makeCopy(code + ' DCS WK' + weeknr,
DriveApp.getFolderById(folderID))
var newID = newfile.getId()
tempArray.push([newfile.getName(), newID, newfile.getUrl(),
newfile.getDateCreated(), "Created", folderID, archivefolder, weeknr])
SpreadsheetApp.openById(newID).getSheetByName("Main").getRange(3, 3).setValue(weeknr)
weekfolder.addFile(newfile)
//NEW UPDATE 14/02 to set the owner to network finance
newfile.setOwner('network.finance#dpdgroup.co.uk')
//End of UPDATE
fileslog.getRange(fileslog.getLastRow() + 1, 1, 1, 8).setValues([tempArray[i]])
}
// Logger.log(tempArray )
// if(tempArray.length>0){
// fileslog.getRange(fileslog.getLastRow()+1, 1, tempArray.length,
8).setValues(tempArray)
// }
}
function archiveFiles(weeknr, fileIDs, masterfolders, mastercodes, archivefolders) {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var date = new Date()
var textdate = Utilities.formatDate(date, "Europe/London", "dd/MM/YYYY HH:mm")
var fileslog = ss.getSheetByName("FileList")
//var year = date.getYear()
//var mainfolder = DriveApp.getFolderById("1HdG3eJZrIMF-CRpx17Reqdyd7JM5v5ZW")
//var weekfolder = mainfolder.createFolder('Week '+weeknr+' '+year)
var tempArray = []
for (var i = 0; i < fileIDs.length; i++) {
// for (var i=0;i<masterIDs.length;i++){
var folderID = masterfolders[i]
var fileID = DriveApp.getFileById(fileIDs[i])
var code = mastercodes[i]
var archivefolder = archivefolders[i]
DriveApp.getFolderById(archivefolder).addFile(fileID)
DriveApp.getFolderById(folderID).removeFile(fileID)
//var newfile = DriveApp.getFileById(masterID).makeCopy(code + ' DCS WK'+weeknr,
DriveApp.getFolderById(folderID))
//var newID = newfile.getId()
tempArray.push([fileID.getName(), fileIDs[i], fileID.getUrl(),
fileID.getLastUpdated(), "Archived", masterfolders[i], archivefolders[i], weeknr])
//weekfolder.addFile(newfile)
}
Logger.log(tempArray)
if (tempArray.length > 0) {
fileslog.getRange(fileslog.getLastRow() + 1, 1, tempArray.length, 8).setValues(tempArray)
}
}
Posted the answer for documentation purpose.
As discussed in the comments the problem was the file size, splitting the copied files in batches did the trick:
So turns out, the file was simply too large to create 70 files in the allotted time. So I split it down to batches of 30 and its worked perfectly. thanks for your help

For loop with if/else statement not working as expected

The function I'm struggling with is part of a script that creates folders and copies a certain spreadsheet into each folder 15 times and names them.
I have a loop to create the files and inside of it I have an if..then..else statement to use a certain name for the file if j>10 and another name (else) if it's not. It always names the file one name and doesn't seem to recognize the if/else statement to change the name if j is over 10.
Basically what I want is to name the file
var namedFileCopy = fileCopy.setName(newFileName);
if j is less than 10 and...
var _namedFileCopy = fileCopy.setName("_" + newFileName);
if j isn't less than 10.
I'm wondering if I need to add a break in there somewhere, but I'm not really familiar with how to use breaks.
This is the function that is giving me a problem, and you'll find all my code in the snippet following it.
function putFilesIntoFolders(arrayOfFolderNames,theFolderNames,cell) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var theSheet = ss.getSheetByName('Sheet1');
var folderType = theSheet.getRange(2,1);
var cell = folderType.getValue();
var file = DriveApp.getFileById("ID");
var dest_folder = "";
var baseFileName = "",
newfile,
newFileName = "",
i=0,
j=0;
for (i=0;i<arrayOfFolderNames.length;i+=1) {
var source_folder = DriveApp.getFolderById("ID");
dest_folder = DriveApp.getFolderById(folderIds[i]);
Logger.log('dest_folder' + dest_folder);
baseFileName = arrayOfFolderNames[i];
for (j=1; j<16; j+=1) {
var newFileName = baseFileName + " " + cell + " " + j.toString();
var fileCopy = file.makeCopy();
var namedFileCopy = fileCopy.setName(newFileName);
var _namedFileCopy = fileCopy.setName("_" + newFileName);
if (j<10) {
dest_folder.addFile(namedFileCopy);
source_folder.removeFile(fileCopy);
} else {
dest_folder.addFile(_namedFileCopy);
source_folder.removeFile(fileCopy);
};
};
};
};
var folderIds = [];
function onOpen(e) {
SpreadsheetApp.getUi()
.createMenu('Data System Tool')
.addItem('Create Data System Folders', 'copyAndRenameTemplate')
.addToUi();
}
function copyAndRenameTemplate() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var theSheet = ss.getSheetByName('Sheet1');
var rangeOfFileNames = ss.getRange("B4:B");
var twoD_Array = rangeOfFileNames.getValues();
var arrayOfFileNames = twoD_Array.join().split(",");
var folderType = theSheet.getRange(2,1);
var cell = folderType.getValue();
Logger.log(folderType);
Logger.log(cell);
// throw new Error('This is not an error. This is just to abort javascript');
var fldrNamesRng = theSheet.getRange(4,1,theSheet.getLastRow()-3,1);
Logger.log('fldrNamesRng: ' + fldrNamesRng);
var folderNames = fldrNamesRng.getValues();
Logger.log('folderNames: ' + folderNames);
var oneD_FolderNames = folderNames.join().split(",");
Logger.log('oneD_FolderNames: ' + oneD_FolderNames);
makeTheFolders(oneD_FolderNames);
putFilesIntoFolders(oneD_FolderNames);
};
function makeTheFolders(theFolderNames,cell) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var theSheet = ss.getSheetByName('Sheet1');
var folderType = theSheet.getRange(2,1);
var cell = folderType.getValue();
var i=0,
folderObj;
for (i=0;i<theFolderNames.length;i+=1) {
folderObj = DriveApp.createFolder(theFolderNames[i] + " " + cell);
folderIds.push(folderObj.getId())
};
};
function putFilesIntoFolders(arrayOfFolderNames,theFolderNames,cell) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var theSheet = ss.getSheetByName('Sheet1');
var folderType = theSheet.getRange(2,1);
var cell = folderType.getValue();
var file = DriveApp.getFileById("ID");
var dest_folder = "";
var baseFileName = "",
newfile,
newFileName = "",
i=0,
j=0;
for (i=0;i<arrayOfFolderNames.length;i+=1) {
var source_folder = DriveApp.getFolderById("ID");
dest_folder = DriveApp.getFolderById(folderIds[i]);
Logger.log('dest_folder' + dest_folder);
baseFileName = arrayOfFolderNames[i];
for (j=1; j<16; j+=1) {
var newFileName = baseFileName + " " + cell + " " + j.toString();
var fileCopy = file.makeCopy();
var namedFileCopy = fileCopy.setName(newFileName);
var _namedFileCopy = fileCopy.setName("_" + newFileName);
if (j<10) {
dest_folder.addFile(namedFileCopy);
source_folder.removeFile(fileCopy);
} else {
dest_folder.addFile(_namedFileCopy);
source_folder.removeFile(fileCopy);
};
};
};
};
There's no issue about your loops, no need to break; out of them.
Your problem occurs in these lines of code:
var fileCopy = file.makeCopy();
var namedFileCopy = fileCopy.setName(newFileName);
var _namedFileCopy = fileCopy.setName("_" + newFileName);
The makeCopy() method will create a new file object, representing a new file in your Google Drive.
After that, you call the setName() method on the fileCopy object, which changes the name of the associated file. That's fine, except that you've assigned the return value of the method call to a new variable, namedFileCopy. You've now got two variables that reference the same object, because this method simply returns the original object for chaining. (Chaining is when we call multiple methods on on object in the same statement; it's only possible if each method returns the original object reference for the next method.)
Next, you call setName() on fileCopy again, assigning the return value to _namedFileCopy; that's the third reference to the exact same object. Oh, and that file - the file that all three object references point to - is now named with an underscore.
After this, your if..then..else is doomed to name the resulting file with an underscore. Actually... the file is already named with an underscore, from the third operation above.
Separate concerns some more; you've got to make a decision about a file name, so do that in isolation. Once you've completed that concern, you are ready to manipulate the file, which is a separate concern.
The resulting loop should look something like this:
for (i=0; i<arrayOfFolderNames.length; i++) {
var source_folder = DriveApp.getFolderById("ID");
dest_folder = DriveApp.getFolderById(folderIds[i]);
Logger.log('dest_folder' + dest_folder);
baseFileName = arrayOfFolderNames[i];
for (j=1; j<16; j++) {
// Determine the name for the new file
var newFileName = baseFileName + " " + cell + " " + j.toString();
// Prepend file name with underscore if j >= 10
if (j >= 10) newFileName = "_" + newFileName;
// Copy "file" and apply our newFileName, then move to new destination.
var fileCopy = file.makeCopy()
.setName(newFileName);
dest_folder.addFile(fileCopy);
source_folder.removeFile(fileCopy);
}
}
(I suspect this is what being said in Alvaz' answer.)
fileCopy.setName() changes the filename property of the file object. You should move your calls to fileCopy.setName() inside of your conditional branches.

ActiveXObject Number of rows counter

I have this piece of code:
function GetData(evt){
var adresses = new Array();
var j = 0;
var excel = new ActiveXObject("Excel.Application");
var fil = document.getElementById("file");
var excel_file = excel.Workbooks.Open(fil.value);
var excel_sheet = excel.Worksheets(1);
for(var i=2;i<500;i++){
var morada = excel_sheet.Range("E"+ i );
var localidade = excel_sheet.Range("C"+ i );
var pais = excel_sheet.Range("A"+i);
adresses[j] = (morada + ", " + localidade + ", " + pais);
j++;
}
for(var k = 0; k<j; k++) {
codeAddress(adresses[k]);
}
}
It receives an excel file and processes the data like I want. The thing is, it is very hard coded.
For instant, in this for:
for(var i=2;i<500;i++)
I am using 500, but I would like to use the number of rows in the sheet. I have already tried a few things like rows.count and whatever and I gave some alerts to see the results, but I just can't find the one who tells me the number of rows.
Anyone know how to do it?
Try that :
excel_sheet.UsedRange.Rows.Count
Does it works ?

Categories

Resources