Sending email when cell reach certain value - google-apps-script

I've created a spreadsheet that collects data from a Google Form.
When a certain cell's value reach above certain number, I'd like to the sheet to send an email to my account. However I can't seem to get my head around how to do this. I've realized that I can't use the conditional formatting option that I get by right clicking the cell. I can only alter the cell/text color by using that option. Do I have to use a script to be able to perform this task automatically?
(The sheet collects absence/attendance data in a class, and when the absence percentage reach a certain value (15%) I'd like the sheet to e-mail a notice about this.)
This might be a newbie question, but that's what I am; A newbie.

You can setup a onFormSubmit trigger on the Response Spreadsheet and after every submit, it can calculate the attendance percentage and send an email using the MailApp.sendMail() method.
function calculate(e)
{
var s = SpreadsheetApp.getActiveSheet();
var data = s.getDataRange.getValues();
for (var rows in data) {
// Calculate the attendance data
}
if (condition_met) {
MailApp.sendEmail(email, subject, message);
}
}

Related

tracking editing values from Google Form

I've a google form, and I split data based on sections. I've 3 sections for example and data is get separated into 3 different sheets when user submits the form, I've successfully done it using form events, but now I want to know how I can track changes if user edits the form and make those fields red.
Sorry I am not including the code, here just want to know about suggestion to do it?
Can you suggest methods I can use for this?
Get response id:
Assuming you are using an onFormSubmit trigger (for Forms, not for Sheets), you can use the corresponding event object to get information about the form response.
More specifically, you can retrieve the form response id, which will be the same every time the form response is edited, as well as the different form item ids. You can use these field to identify the response in your sheet and each of the corresponding items and update those. For example, if this was your trigger function:
function onFormSubmit(e) {
const responseId = e.response.getId();
const itemResponses = e.response.getItemResponses();
itemResponses.forEach(itemResponse => {
const response = itemResponse.getResponse();
const itemId = itemResponse.getItem().getId();
// Find cells with corresponding responseId and itemId
// Update cells if found, populate new ones if it's a new submission
});
}
Find cells in spreadsheet:
Then you should find the responseId in your spreadsheet. You can use Range.getValues to look for the sheet values or, if you feel so inclined, use TextFinder to find the corresponding cell.
Update cells:
Once you've identified the cells, you can update the corresponding values (Range.setValues) and/or update the background color (Range.setBackgrounds).
Note:
This solution requires you to add the different responseId and itemId for every form response in your sheets. Otherwise, there will be no way to identify these whenever a response is submitted or edited.
The exact workflow for this would depend on the data structure you have, the form items you want to track, etc. I hope there's enough indications here to help you though.

Send email to a specific recipient based on cell value

I'm not a technical person and need help on using apps script.
I have a sheet with 5 tabs (each sheet are exactly the same format of column headers)
Column B is a dropdown of 4 points of contact. E.g. John, Anna, Peter and Michelle
Goal: when a user selects a name from the dropdown, it will send an email to whoever was chosen.
subject and message can be a generic template for everyone
Can someone help me with a script I can copy and paste for this?
As it says in the comments, StackOverflow is not a coding writing service, but I will give you a couple of keys to achieve it by yourself.
What is the main point? We need to observe the changes on the sheet, and when it coincides with the cell that contains the email, we send the email to the one the value is in the cell.
We need to observe the changes on the sheet, how we achieve it? With an installable trigger we can capture edits events on the Sheet, as the change of the drop-down list.
Finally we need to filter the event and only attend to the ones that are in the cell or cells that contain the drop-down.
In this example I have the cell A1 with the drop-down of emails:
const sendEmailFromSheets = (e) => {
const range = e.range;
const email = e.value;
if( range.getA1Notation() === 'A1') {
MailApp.sendEmail(email,'Message from the Sheet', 'Body')
}
}
After this, we attach this function to an installable trigger with the source From spreadsheet and type On change.
With all of this, you should be able to change it to adapt it to your needs.
Documentation:
SpreadsheetApp
Event-driven Trigger

Insert new row and move data based on cell text

Trying to automate a Google sheet to save time for a team member. I have zero scripting experience. I am trying to insert a row based on a "Yes" result from column K in a Google form submission sheet and then move data in cells L:P to the new row, all without messing up the query functions that are pulling this data.
Is this possible?
Appending selected data from a form submission
function onFormSubmit(e) {
var ss=SpreadsheetApp.openById('SpreadsheetID');
var sh=ss.getSheetByName('Sheet Name')
if(e.values[11]=="Yes") {
var nV=e.values.slice(11,16);
ss.appendRow(nV);
}
}
Since you said that you have zero scripting experience, I should warn you that you cannot run this function without supplying the event object and personally I would never append new rows to a linked sheet. I would append the rows to another sheet instead. There have been problems with the onFormSubmit trigger lately which causes spurious additional triggers as described here.

Form Notification for Teachers when Students Fill out Google Form

I'm making a website for school to connect students and teachers. Teachers fill out a Google Form asking for service (grading papers...) and it is connected to Google Spreadsheets. Then a student can see that Spreadsheet and sign up on a different Google Form to help the teacher, and that response is recorded in the same Google Spreadsheet. When the student submits his/her Google Form, I want the teacher to be notified by email that a student signed up to help them. How can I send that notification? And I don't want the notification to come from my own school address. Is that possible?
Here is the Google website: https://sites.google.com/fcpsschools.net/jmhsservicesignup/subjects/math
This is the code I have so far:
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Tutors
Signed Up");
var startRow = sheet.getLastRow(); // First row of data to process
var dataRange = sheet.getRange(startRow, 1, 1, 5)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
var emailAddress = row[3]; // Second column
var tutor = row[0];
MailApp.sendEmail(emailAddress,"Tutor Request Filled",""+tutor+" has accepted your request to be tutored! Please notify"+tutor+" if anything changes.");
}
}
The getLastRow doesn't seem to work, and the email sends from my own address, not a Google forms notification if that is even possible.
If this is impossible I might just make the students send the email to the teacher, but I really want to automate the process. If you can think of a workaround, that would also be awesome.
Adding to what Sandy Good and Guilherme mentioned.
Here are a few more tips:
Not clear what data you're trying to get in your function. Are you trying to grab the data from the form submission? In that case you need to set up a trigger from the scripts menu, and connect it to the function (function needs to have an 'event' argument, usually called e).
function processFromSubmission(e) {//get data from e}
Apologies if you're not trying to do that. What happens when you Log sheet.getLastRow()?
Ask the school if they can get you another email address to use for this form, something like notifications#yourschool.edu. Follow the steps here to set up your alias. Do it for the gmail account that "owns" the spreadsheet these forms are sending data to.
Make sure your alias is set up properly. You should be able to see it in the "from" dropdown menu when you compose an email. Also try running the code Logger.log(GmailApp.getAliases()) and check the log to see that it's available.
Use GmailApp.sendEmail to send email, not MailApp.sendEmail. They're almost the same, but it looks like the MailApp version doesn't let you send from an alias. You can specify the 'replyTo' email as well if you want to set it to something else, like the student filling out the form or whatever (still not clear exactly what you're trying to set up!).
Send email like:
GmailApp.sendEmail(emailAddress, subject, body,
{replyTo: replyToEmailAddress_can_be_any_email,
from: 'notifications#yourschool.edu'
});
Note: your link didn't open.

Spreadsheet Email Trigger

I have Written Script on Google Spreadsheet to send Email when spreadsheet is modified or any Data is added. Email Trigger is working but whenever any data is entered in next Row it send Email to previous email address also.
Please suggest solution
The below is written script :
function onEdit(e) {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 1; // Number of rows to process
var dataRange = sheet.getRange(startRow, 1 , numRows,3) // Fetch the range of cells A2:B3
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
var emailAddress = row[2]; // First column
var message = row[0] + "requested" + row [1]; // Second column
var subject = "Sending emails from a Spreadsheet";
MailApp.sendEmail(emailAddress, subject, message);
}
}
Your question is unclear... nowhere in the script I see something that reads which cell is actually modified... your target range is hardcoded on row 2 so the only row that can be processed is row 2 (and the mail can only be sent once)...
So can you :
explain how it should work
explain how it works now , especially what do you mean by 'previous email'
remove typos in your code (row[2] is not First column)
explain how you trigger this function : the name onEdit(e) suggest an onEdit trigger but simple triggers cannot send mail so I suppose you have set some other trigger.
explain why (e) in your function parameter and not using it ?
EDIT : thanks for the complement of information.
The script you suggest is not sufficient to achieve what you want. The idea here is to check if something in the sheet has been modified either by adding (or inserting) a row of data or (if I understood well) by editing any row in the sheet with a new value.
This is not really as simple as it looks at the first glance ;-)
What I would do it to take a 'snapshot' of the sheet and -based on a timer or onEdit - compare that snapshot to the sheet's current state.
There is more than one way to get that result, you could have a second sheet in your spreadsheet that no one could modify and that is a copy of the main sheet that you update after each modification/mail send. So before updating the script should look for any difference between the sheets and send a report to the corresponding email when a difference is found.
Another way to do that is to store the sheet data converted to a string in the script properties, the principle is the same but it's more 'invisible' for normal users accessing the spreadsheet.
You could also use scriptDb or your userproperties but the script properties is probably better suited (simpler) for this use case.
Tell us what you think/prefer and I (or someone else) could probably give you some code to start with.
It appears that you're using a shared spreadsheet to collect the add-user-requests, and trusting the requesters to fill in the information. In the detail document you shared, it further appears that requests are ADDED, but not EDITED. (That's an important simplifying distinction.)
I suggest that what you really need is to use a form for receiving that input. Using a form will create a "data table" within your spreadsheet, a set of columns that you must not mess with. (You can edit the contents, add and delete rows, but must not add or remove columns.) However, you CAN add columns to the spreadsheet outside of this table, which gives you a handy place to store state information about the status of individual requests.
Further, you can trigger your processing to run on form submit, rather than a simple "onEdit" - this gets away from the problem that ScampMichael pointed out. Alternatively, you can use an installable edit trigger, as described in this answer.
Try this sheet, and this form. Save yourself a copy, go into the script and remove the comments that are stopping emails from being sent, and try it out. There's a menu item in the spreadsheet that can kick off processing; just clear the "Request State" column to re-run it. You can open the form (and find its URL), and add more entries to experiment.
It's the core of a similar system that I've written, and contains a discreet state machine for processing the requests. My system has large amounts of very complex data in multiple spreadsheets, so it often gets pre-empted, then needs to run again. (I use a timed trigger for that.) That's why requests are handled through states. If you find that too complex, pull out only the parts you need.