On edit trigger for send email function - google-apps-script

I am trying to create a script and/or trigger that will send an email to a small group of users anytime a value is entered into cells within a specific column of a google sheet. I am able to get the send email function to work properly but all the triggers I have attached the current script that is functional as far as sending the email, I just need a way to trigger it via script or the actual triggers wizard.
I tried an on edit trigger but I do not think I was using it correctly OR it doesn't have the permissions needed to send an email.
function myFunction() {// Fetch the email address
var emailRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("EmailScript").getRange("B2");
var emailAddress = emailRange.getValues();
// Send Alert Email.
var message = 'L&F cash amount entered!'; // Second column
var subject = 'L&F Cash';
MailApp.sendEmail(emailAddress, subject, message);
}
I want for an email to be sent anytime a value is entered into any cell within column D.
Any help is greatly appreciated.

Related

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.

Sending email when cell reach certain value

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);
}
}

Create a new sheet in an existing spreadsheet for EACH RESPONSE from a Google Form

I have created a Google form, and I need to create a new sheet in an existing spreadsheet for each response I receive from this form - each respondent generates a new sheet within the spreadsheet. Is this possible with some kind of onSubmit command? I'm completely new to Javascript but willing to learn. Thanks so much for your help.
You can't intercept a Google Form submission before the data is written into the spreadsheet. All you can do is manipulate the data after it's already been inserted into the spreadsheet. So, your responses will get put into the spreadsheet, all in one sheet to start with. You can't change that.
Now the question is, do you want to manipulate the data from code bound to the form or bound to the sheet? You'll want to use a project bound to the sheet.
This is some sample code:
This code assumes that the value you want to name your sheet is in column A
function subTheForm() {
Logger.log('submit ran');
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
//Get last row of data
var lastRow = sheet.getLastRow();
var colA_Data = sheet.getRange(lastRow, 1).getValue();
//var thisUser = 'theUserName';
ss.insertSheet(colA_Data);
};
Old answer:
You'll need to generate some kind of unique string every time a new form is submitted. I have no idea what you want. You could get the user name, then add the date/time to it, then name each new sheet the user name with the time. The basic code will look like this:
function submit(){
Logger.log('submit ran');
var thisUser = 'theUserName';
var ss = SpreadsheetApp.getActive().insertSheet(thisUser);
};
Note the Logger.log(); statement. That prints something to the LOG. Inside the code editor, you can select the VIEW menu, and the LOGS menu item to show the LOG.
You can also run the code "manually" from the code editor by selecting the function name and clicking the run arrow icon. That way you can run the code without submitting a form every time. Get the code to work, then wire it up to the onsubmit trigger.
For this you can get the Spreadsheet using this command(getActiveSpreadsheet()) and then create a new sheet based on the parameters you require from this page. you can add this lines of code in your onSubmit trigger.
Hope that helps!

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.

Merge Form Submission to document - lost newbie

Seeking guidance on the following:
User submits Formstack form -> Form entry populates a row on Google Spreadsheet -> Trigger the execution of a document merge for that submission (now a ROW in the sheet) with the column header defining the variables -> Email merged document to User via submitted email address.
My document requires the ability to conditionally handle many of the variables (if/then conditional text based on form response). I've played with an App called Ultradoc which seems great for the variable handling in the Google Document, supports conditions, etc.
However, the problem is it doesn't know how to select one ROW of data, rather it's designed to run a merge for everything in each column.
One idea might be to run a script which takes that new ROW and somehow makes it look like a two row sheet (header+submitted row)?? Somehow hides the other rows? This seems terribly kludgy. What's the right way to approach something like this?
Thanks in advance
You actually don't need any third party apps for this.
Create the form as a Google Form, create the script and make it run on Form submit.
To get the values that were entered into the form, pass the form submission as a parameter to the function: function processForm(e){
To get the data in the form, access the e.values array. It's zero indexed, starting with the top item on the form.
Store the submitted data into variables
var name = e.values[0];
var email = e.values[1];
// and so on...
Perform any validation or document handling.
Create a copy of your template document
var copyId = DocsList.getFileById("templateDocID")
.makeCopy(docName+' from '+name) //or whatever you wanted to call the resulting document
.getId();
var copyDoc = DocumentApp.openById(copyId);
var copyBody = copyDoc.getActiveSection();
Replace the text in the template
copyBody.replaceText("NAME", name);
copyBody.replaceText("EMAIL", email);
// and so on...
Send the document to the user (for my application, I sent as pdf, but you can send it how ever you like)
copyDoc.saveAndClose();
var pdf = DocsList.getFileById(copyId).getAs("application/pdf");
MailApp.sendEmail(email, copyDoc.getName(), "Here's your document", {attachments:pdf});
DocsList.getFileById(copyId).setTrashed(true);