So I have a Google Form that feeds a Google Docs Spreadsheet. This form is for new people to our town to signup for our newcomers group.
I want to write a Google Apps script that will programmatically send a reminder e-mail to users who have not paid their dues 10 days after they submitted the form.
Should be easy, right?
Here's a link to a copy of the Spreadsheet with personal data redacted out:
https://docs.google.com/spreadsheet/ccc?key=0AjsoIob8dJfodG9WN0ZmWUE1ek9rc3JrVFpDQ0J0OGc
Seems as if I should be able use Column A ("Timestamp") with some sort of a comparison to now() to determine the 10 day part. And to get the have not paid their dues just has to be Column D does not equal Yes. The recipient's e-mail address is, obviously, in Column X.
I've already written a script to send a confirmation e-mail to the recipient "On Form Submit." So I'm comfortable with the MailApp.sendEmail class.
And if you notice the "Updaid" tab, you'll see that I've tackled using a query to pull out people who haven't paid.
But I'm not sure how to get the MailApp.sendEmail class to operate on data that's already IN a sheet. That is not triggering automatically when the form is submitted.
And I don't know how to adapt my query to account for the 10 days ago bit.
And I'm not even sure I should be USING a query for this application.
Can anybody right my path?
Thanks.
The easiest way to know if a date is 10 days later is probably to count the milliseconds !
I know it sounds like a joke but it isn't ;-)
Example :
function test(){
var today = new Date();
var tendaysBefore = new Date(today.getTime()-10*24*60*60*1000);// 10 times 24 hours
Logger.log(today+' is 10 later than '+tendaysBefore);
}
The method getTime() returns the number of milliseconds from the reference date, it will work till 2070 so I guess it is safe to use for now ;-)
The trigger issue is already solved in Cornelius's answer, thx
EDIT : here is a possible code to do what you want : (tested on your sheet)
var sh = SpreadsheetApp.getActiveSheet();
var ss = SpreadsheetApp.getActiveSpreadsheet();// replace these with openbyId''ID') and getSheetByName(name) when you run it with trigger since the sheet wil be 'closed'
var lastrow = ss.getLastRow();
function onOpen() {
var menuEntries = [ {name: "check late paiments", functionName: "test"},
{name: "send mails to tagged users", functionName: "mailunpaid"},
];
ss.addMenu("custom functions",menuEntries);// custom menu
}
function test(){ // check column D and set it to "no" if not paid
var paidcol = sh.getRange(2, 4, lastrow-1, 1).getValues();//read only col D
for(nn=0;nn<paidcol.length;++nn){
if(paidcol[nn][0].toString().toLowerCase().match('yes')!='yes'){
paidcol[nn][0]='no'
}
}
sh.getRange(2, 4, lastrow-1, 1).setValues(paidcol);// write back to sheet
}
function mailunpaid(){
var data = sh.getDataRange().getValues();//read the whole sheet in an array, col D is idx3, timestamp is idx0 email is idx 23
var today = new Date();
var tendaysBefore = new Date(today.getTime()-10*24*60*60*1000);// 10 times 24 hours
for (nn=1;nn<data.length;++nn){ // iterate from row 2 to end ie idx 0 to last
// Logger.log(data[nn][3]+' '+data[nn][0])
if(data[nn][0]<=tendaysBefore && data[nn][3]=='no'){
// MailApp.sendEmail(data[nn][23], 'subject', 'body'); // you have to define the mail subject & content somewhere ;-) and uncomment when finished your tests
Logger.log('row '+Number(nn+1)+' = to send because '+data[nn][0])
sh.getRange(nn+1,4).setValue('SENT');// tag this user to know that mail has been sent to avoid multiple emails
}
}
}
note that I splitted the code in 2 functions for clarity but when it will run as a trigger you should combine both functions in one to get an automatic checking...
It should be pretty easy to write the compare function, you then would just need to add your own daily trigger.
Look to the Resources-> Triggers in the script editor.
Here is the link to the Triggers tutorial from Google.