Send an Email When a Cell is Edited with a Certain Value [duplicate] - email

This question already has an answer here:
For loop and if statement for multiple conditions
(1 answer)
Closed 6 years ago.
I've got a Google Form set up to record user-reported errors about a database we maintain. The responses go into a Google Sheet and the users email is recorded. Essentially, I'd like to have a status field in that Google Sheet -- and when it's set to something like "Complete" (which would be in the same row as the response) I would like an email to be automatically sent to the user that submitted the response, letting them know the status of their response is complete. So sort of like a ticket system that many companies use (but we don't have a lot of bandwidth to set this up, so we're looking for something simple/free).

You cannot send an email inside the onEdit trigger. So you'll have to save the edits somewhere, maybe inside UserProperties, and have a time-based trigger that sends this value to your email every minute.
See: Email Notifications in Google Spreadsheets.
Google Spreadsheet support email notifications for row edits (tools - notification rules) but the last time I tried it, it never worked.

Create an onEdit() function, capture the cells value when it's edited, and run the code.
function onEdit(e){
// Capture the cells value after it is edited
var valCell = e.value;
Logger.log('The cell value is: ' + valCell);
if (valCell === "Complete") {
//Get the range of the cell
var theRange = e.range;
//Get the row of the range
var theRowOfEdit = theRange.getRow();
// Returns the cell with email
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var cell = sheet.getRange("B" + theRowOfEdit.toString());
//Get the user email
var userEmail = cell.getValue();
//Send the email
}
}
This is not the complete code that you need. But, set this code up; test it, debug it, and if you have a specific question, post another question with the error message and line of code that isn't working.
Use debug in the code editor, and/or Logger.log() statements to debug the code.

Related

Google Scripts - sending email based on a cell value

This is the code I am currently trying to use to implement an email based on the cell value of C2 (see screenshot of Google sheets below).
function amberwarning() {
// Fetch the combined flow value
var combflowrange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("FloodEWS").getRange("C2");
var combflow = combflowrange.getValue();
// Check combined flow value
if (270 < combflow < 310){
// Fetch the email address
var emailRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Email").getRange("A2");
var emailAddress = emailRange.getValues();
// Send Alert Email.
var subject = 'Amber warning';
var message = 'It is possible that the Egger site will experience flooding in the coming hours. The advice is to be prepared to take action as combined river flows can increase very quickly during storms. Please keep up to date with the latest river levels for Hexham at <https://flood-warning-information.service.gov.uk/station/9006>. The latest flood warnings from the Environment Agency for Hexham are here <https://flood-warning-information.service.gov.uk/warnings?location=+hexham>. The latest MetOffice weather forecast can be found here <https://www.metoffice.gov.uk/weather/forecast/gcy2xzrne#?>. Please use all available information to inform your decision making. You will keep receiving an email as per each refresh of the latest data. The current combined flow from the North and South Tyne is' + combflow;
MailApp.sendEmail(emailAddress,subject,message);
}
}
The current error message I am receiving is "The parameters (number[],String,String) don't match the method signature for MailApp.sendEmail. (line 15, file"
The idea is that:
When cell C2 is between 270 and 310, to send an email 'Amber warning'
When cell C2 is above 310 send an email 'Red warning'
When cell C2 is less than 270, no email
This will hopefully be attached to a trigger to schedule every 15 mins
Any help on how to combine the two emails (or have single codes for each email) would be greatly appreciated.
enter image description here
It seems your "emailAddress" parameter is a number array (number[]) since the error you are receiving says so.
Try using getValue() if it is a single address, or get the first value of getValues() which is a 2D array by doing getValues()[0].
Whichever you choose, assign it to your emailAddress variable before calling MailApp.sendEmail().
Try to follow the steps in the documentation
as it explains everything clearly and how to send email through app-script

Google Apps script: Trigger does not work for e-mails to be sent out

I am writing a code that aims to inform me via e-mail if a value on a website changes. In order to do so, I use 4 functions:
function one executes functions 2-4
function 2 is a scraper
function 3 writes the data in a new line in a spreadsheet
function 4 compares the newly written line and sends out an e-mail if the new line is different from the one before.
Function one is triggered automatically every 5 minutes. The spreadsheet shows that the trigger works fine for function two and three (scrape and save the data to the spreadsheet), every five minutes the spreadsheet is being updated. I do not, however, get an e-mail when something changes.
When I execute function one manually, it works, including e-mails being send out if the data changed. I tried to add an additional trigger to just execute the function that compares the data and sends an e-mail. That, however, also did not lead to e-mails being sent to me.
If it matters: The data change about once an hour. I however, want to get informed asap, hence the frequent checks
Do you have any idea, why the trigger for sending out the e-mails does not work and do you have any solution for me?
Thanks in advance!
function scrape_save_send(){
getData();
saveData();
SendEmail();
}
function getData() { // works just fine, code cut to make it not too long
[...]
}
function saveData() { // works fine both automatically and manually
var sheet = SpreadsheetApp.getActiveSheet();
sheet.appendRow([new Date(), getData()]);
var lrow = sheet.getLastRow();
sheet.getRange(lrow,3).setFormula('=SPLIT(B'+lrow+'; "abcdefghijklmnopqrstuvwxyz=<>- /")') // workaround to extract a number from the scraped content
}
function SendEmail() { // works just fine if executed manually
Utilities.sleep(2000) // delays the check
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow();
var ui = SpreadsheetApp.getUi();
if (sheet.getRange(sheet.getLastRow()-1,2).getValue() === sheet.getRange(sheet.getLastRow(),2).getValue()) {
Logger.log('equal');
} else {
var invest = sheet.getRange(sheet.getLastRow(),8).getValue();
MailApp.sendEmail("ab#gmail.com", invest + "blablabla", "blablabla");
// Logger.log('not equal');
}
}
Try changing MailApp to GmailApp in the last line of SendEmail() function.
I found the solution: the getUi()-function apparently caused the problem. Some research showed me that the getUi()-function only works when the according sheet is opened.
Since I don't need the function (it was left over from an old function) I deleted it, the script now works automatically. Thanks!

send google form via script

I have my family cell phone bills set to autopay and sometimes forget to send each individual their portion of the bill. I wanted to setup an automated system with google apps to send me a form where I can input each person's owed amount. Then after I submit the form, the app will send the people on my plan an email with their amount due. I then want the same prefilled form sent back to me a week or two later that allows me to update my googlesheet column with people's payment status.
I have figured out how to process the form data and then send out the bill emails. However, I cannot find a way to resend a form via a google-scirpt so I can update if an individual has paid me and I have cashed their checks. I figure I will need to capture the responce.id to update the same sheet entry, but I have not been able to find a way to resend the form.
I have googled a bit and tried to some method like sendForm("email",formID) but have not been able to find anything. Everything I have seen online shows me how to send the form from my google drive. However, I was wondering if anyone knows if such a method exists.
Here is a sample of my code so far (I am in no way a professional programmer so feel free to make suggestions to improve the existing code):
/*Define key variables up here like URL for sheets */
var sheetId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var sheetName = "Form Responses";
var sheetData =SpreadsheetApp.openById(sheetId).getSheetByName(sheetName).getDataRange();
var lastRow = sheetData.getNumRows();
var monthNames = ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"];
var base = [ 1, 2];
function test(){
for (i = 0; i< base.length; i++){Logger.log(i);}
};
function lastBillComplete() {
lastRow = sheetData.getNumRows();
isSuesCheckCashed = sheetData.getValues()[lastRow-1][7];
isNancysCheckCashed = sheetData.getValues()[lastRow-1][8];
if (isSuesCheckCashed == "Yes" && isNancysCheckCashed == "Yes") {
return true;}
else{
return false;}
};
function sendBill(){
// Array of names that emails are being sent to
var emails = ["xxxxxxx#gmail.com","xxxxxxx#gmail.com"]; //the real emails will go here.
var names = ["Sue", "Mom"];
//subject line of email
var subject = "Verizon bill for " + monthNames[new Date(sheetData.getValues()[lastRow -1][2]).getMonth()];
//body of email that changes for each person
for (i = 0; i < names.length; i++){
var amount = sheetData.getValues()[lastRow-1][i+3];
var body = new String("Hi " + names[i] +",\n\nYour portion of this month's bill is $"+amount +". I have attached the .pdf of the bill to the email if you would like to look it over. Please let me know if you have any questions.\n\nTalk to you soon, \nJeremy");
MailApp.sendEmail(emails[i].toLowerCase(), subject, body);
}
};
I realize that probably the best way to set this up is to have the people on my plan just autopay to my bank account. However, the people on my account like to send actual checks, and are resistant to the idea. So I figured I would use the opportunity to improve my scripting abilities.
Thanks in advance,
Jeremy
This might be a slightly different approach than what you're doing, but if the forms that you have people fill out are connected to a spreadsheet, I think it will be easier if you use that spreadsheet as verification as to whether or not if they've filled the form. Timestamp the responses or have a field for Billing Month, just anything to identify a time period. Within that time period, check to see if your plan members have a response. You can then create a time-based trigger to have it check at regular periods and use the same email sending code you have to send the people that have not paid the form again, or just send yourself an email to take whatever appropriate action.

email reminders time driven google spread

Can anyone help.
I have a simple google spreadsheet that enables me to book delegates onto a variety of courses at different venues and at different times and dates.
I used the same spreadsheet last year, kindly set up by Bob Rashkin! It worked perfectly and sent emails when delegates booked onto the course and also sent email reminders automatically when the course was 9 days or so from starting.
I have duplicated the spreadsheet for this term but the sheet refuses to send the reminder emails, I really could do with a little help on this?
A secondary matter is that when the script sends a booking confirmation email, it sometimes sends two of them which creates a lot of phone calls asking if they've booked on twice.
Help someone please
This is the reminder script that I'm using
function Reminder() {
var ss=SpreadsheetApp.getActiveSpreadsheet();
var s=ss.getActiveSheet();
var r1=s.getDataRange().getRow()+1;//Start past the header row!!! Doh!
var r2=s.getDataRange().getLastRow();
var mn,m,days,d=new Date(),coursedate=new Date(),dlen=8.64e7,i,course,r,year;//8.64e7
var subject="Just a gentle reminder that you or colleague(s) from your setting have a Paediatric First Aid course coming up in the next week or so. ";
var recipient, body, tail="Please be aware that Entrust (formerly Staffs Early Years) will make a charge for non attendance so";
tail+=" please make sure that you familiarise yourself with the times and dates of the course. ";
tail+="If you need help finding the venue then please follow the link below to find the venue and print off a map if required.";
tail+="\n\nhttp://www.blithfieldsafety.co.uk/venues/";
for (r=r1;r<=r2;r++) {
recipient=s.getRange(r,9).getValue();
course=s.getRange(r, 2).getValue();
body=subject+"\nCourse Details\n"+course+"\n\nDelegate Name: "+s.getRange(r,4).getValue()+"\n\n"+tail; //changed (r,2) to (r,4)
mn=course.match(/Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec/)[0];
m=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"].indexOf(mn);
days=course.match(/(\d{1,2})(st|nd|rd|th)/g);
year=d.getFullYear();
for (i in days) {
coursedate.setMonth(m);
coursedate.setDate(days[i].slice(0,-2));
if ((coursedate-d)/dlen<14 && s.getRange(r,16).getValue()!="mail sent") {
GmailApp.sendEmail(recipient, subject, body);
s.getRange(r,16).setValue("mail sent");//arbitrarily picked col 15
}
}
}
};
It looks like the time remaining until the course begins is checked with this line:
if ((coursedate-d)/dlen<14 && s.getRange(r,16).getValue()!="mail sent") {
That line is making a date calculation, and checking if the value of a cell had the text "mail sent" in it. If the cell didn't have mail sent AND the date calculation is true, then an email gets sent. Notice that the divisor dlen is a value that was hard coded.
var mn,m,days,d=new Date(),coursedate=new Date(),dlen=8.64e7,i,course,r,year;//8.64e7
The value of the variable dlen is set to a constant value of 8.64e7. But I'm guessing that the math no longer works right for some reason.
The value of dlen is 86400000.
There are 24 hours in a day, 60 minutes in an hour, and 60 seconds in a minute.
24 * 60 * 60 = 86,400 seconds in a day. So, obviously, the 86,400,000 number is a multiple of the number of seconds in a day.
I'm guessing that there is a new course every month?
You can add a Logger.log() statement to your code, and run it so see what the variable values are:
Logger.log('coursedate: ' + coursedate);
If you put that line in your code:
for (i in days) {
coursedate.setMonth(m);
Logger.log('coursedate: ' + coursedate);
coursedate.setDate(days[i].slice(0,-2));
Logger.log('coursedate: ' + coursedate);
Logger.log('d: ' + d);
if ((coursedate-d)/dlen<14 && s.getRange(r,16).getValue()!="mail sent") {
That would tell you what the values of the variables coursedate and d are right when the calculation is being made.
Then you could hopefully figure out why the math is the way it is. To view the Logger.log() output, click on the View menu, and choose the Logs menu item. A list of logged values will be in the window.

Episerver, getting a users current "work-item"

I want to make a gadget that lists all the users with their current workitems shown.
How do I get the current work item which is shown in the page-tree in editor-mode. For example, when user 1 works with page 1 you can see that there is a little person-icon next to the name and if you hoover over it, it will say user 1.
Although it is possible to loop all pages in the page-tree and get latest changes, but that would be tough on the server.
There is an API for the notifications. Try this:
using EPiServer.Editor.Notification;
InUseNotificationRepository pagesInUseRepo = new InUseNotificationRepository();
var notifications = pagesInUseRepo.GetAllInUseNotifications();
foreach (var notification in notifications)
{
// notification.PageGuid
}