How can I get and send to the last row submitted? - google-apps-script

I've built a script that will get the issue with a form submission (D2) then output the text with the information in an email. Right now the Email address location (B2) and issue (D2) are hard coded. How can I work the code to get the email and issue from only the last row submitted?
function SendNot() {
// Fetch the Issue
var reasonRange =
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("TriggerSettings").getRange("D2");
var reason = reasonRange.getValue();
// Check for Issue
if (reason==="nogps"){
// Fetch the email address
var emailRange =
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("PlayerInfo").getRange("B2");
var emailAddress = emailRange.getValues();
// Send Alert Email.
var message = 'No GPS...';
var subject = 'Latest VDGL Entry...';
GmailApp.sendEmail(emailAddress, subject, message);
}
else if (reason==="nobarcode"){
// Fetch the email address
var emailRange =
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("PlayerInfo").getRange("B2");
var emailAddress = emailRange.getValues();
// Send Alert Email.
var message = 'No Barcode...';
var subject = 'Latest VDGL Entry...';
GmailApp.sendEmail(emailAddress, subject, message);
}
}

You can calculate the last row with content using the following method:
sheet.getLastRow()
In your example you can calculate this as follows:
var d_size = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("TriggerSettings").getLastRow();
var b_size = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("PlayerInfo").getLastRow();
and then you can use d_size to grab the last row reason elements:
var reasonRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("TriggerSettings").getRange("D"+d_size);
and b_size to grab the last row email elements:
var emailRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("PlayerInfo").getRange("B"+b_size);
You can also use a different syntax to get the desired range:
Instead of getRange("D"+d_size) -> getRange(d_size,4)
Instead of getRange("B"+b_size) -> getRange(b_size,2)
References:
Sheet.getLastRow()

Related

Is there a way to pass information to a Google Form from a link sent in an email (parameters in the URL maybe)?

I want to send an email to folks using a script that will ask them to confirm an appointment. I'd like to make it easy for them to confirm. I was thinking I could have a link go to a Google Form, but I would like that form to contain information about the appointment; I thought about putting parameters in the form URL (e.g. https://docs.google.com/forms/d/e/[formID]/viewform?location=Office1&subject=management) but I don't see a way to grab that URL in the script attached to the form (only the normal URL of the form). Any way I can get the URL with the parameters? Or is there some other way to pass information to the form? (Or, failing that, to a Google Doc or something?)
I tried using getPublishedURL but that gets the standard URL, no parameters...
Question: Is a way to pass parameter information to a Google Form from a link sent in an email.
Answer: No.
But there is a way that you can use a Google Forms link, sent in an email, that would enable a person to confirm an appointment.
In brief:
create a Google Form with three questions
Question 1 = Title: "User Details", Type: "Paragraph Text"
Question 2 = Title: "My appoitment time is", Type: "Short-answer Text"
Question 3 = Title: "Acknowledgement", Type: "List Item", one options = "yes"
create a Google spreadsheet with two sheets
sheet 1 = user details = name, email, appointment time plus two checkboxes ("ResponseCreated" and "Email sent")
sheet 2 = Form Responses - linked from the Google Form
add one additional column: "EditResponse URL"
write/run a script to create form responses using the data on sheet1
this will populate questions 1 and 2
Sheet 2(Form Responses) is automatically updated.
write/run a script to create the EditResponseUrl for the data on sheet="Form Responses"
write/run a script to send emails to the user details on Sheet1
use the EditResponseUrl from sheet 2 to create an HTML link in the email
-when each user clicks the link in their email, they are directed to a form that contains their details, and the time of their appointment.
They select "Yes" (to acknowledge the appointyment) and then Submit.
Sheet 2 is automatically updated from the form - this is your evidence of their acknowledgement.
Create Form Responses
function createResponse() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sourceSheetName = "User details"
var source = ss.getSheetByName(sourceSheetName)
// get the number of entries
var aVals = source.getRange("A2:A").getValues()
var aLast = aVals.filter(String).length
// get the data; 3 columns plus a checkbox// one row = header
var sourceRange = source.getRange(2,1,aLast,4)
//Logger.log("DEBUG: source range = "+sourceRange.getA1Notation())
var sourceValues = sourceRange.getValues()
var formUrl = ss.getFormUrl();
var form = FormApp.openByUrl(formUrl); // grabs the connected form
var questions = form.getItems();
// Getting the fields of the form questions
var userInfo = questions[0].asParagraphTextItem();
var appntInfo = questions[1].asTextItem();
var updateArray = new Array
for(i = 0; i < sourceValues.length; i++) {
if (sourceValues[i][3] == false){
var formResponse = form.createResponse();
var d1 = "Name: "+sourceValues[i][0]+"\nEmail address: "+sourceValues[i][1]
var r1 = userInfo.createResponse(d1)
var d2 = sourceValues[i][2]
var r2 = appntInfo.createResponse(d2)
formResponse.withItemResponse(r1)
formResponse.withItemResponse(r2)
formResponse.submit()
updateArray.push([true])
}
else {
updateArray.push([true])
}
}
// Logger.log("DEBUG: checkbox range = "+source.getRange(2,4,sourceValues.length).getA1Notation())
// Logger.log(updateArray) // DEBUG
source.getRange(2,4,sourceValues.length).setValues(updateArray)
}
Get EditResponseUrl
function responseURL() {
var form = FormApp.openById('10cG91VSwmIvCS8PQbJwtrQk47uWVmcH6i5pX83KsuVE')
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sheet = ss.getSheetByName('Form Responses 1')
var formResponses = form.getResponses()
for (var i = 0; i < formResponses.length; i++) {
var formResponse = formResponses[i]
sheet.getRange(i+2, 5).setValue(formResponse.getEditResponseUrl());
}
}
Send email
function sendEmails(){
var ss = SpreadsheetApp.getActiveSpreadsheet()
var userSheetName = "User details"
var usersheet = ss.getSheetByName(userSheetName)
var formSheetName = "Form Responses 1"
var formsheet = ss.getSheetByName(formSheetName)
// get the number of entries
var aVals = usersheet.getRange("A2:A").getValues()
var aLast = aVals.filter(String).length
// get the data; 3 columns// one row = header
var userRange = usersheet.getRange(2,1,aLast,5)
// Logger.log("DEBUG: source range = "+userRange.getA1Notation())
var userValues = userRange.getValues()
var formRange = formsheet.getRange(2,1,aLast,5)
// Logger.log("DEBUG: form range = "+formRange.getA1Notation())
var formValues = formRange.getValues()
//Logger.log(formValues)
// return
var sentArray = new Array
var emailSubject = "Request for Confirmation of Appointment"
for (var i=0;i<userValues.length;i++){
if (userValues[i][4] == false){ // test if email has already been sent
var name = userValues[i][0]
var email = userValues[i][1]
var apptTime = userValues[i][2]
var respURL = formValues[i][4]
var html_link = "<a href='"+respURL+"'> our Appointment confirmation form</a>"
//Logger.log(html_link)
var html_body = "Hello, "+ name +",<br><br>"
+ "Your appointment is at "+apptTime+". Would you please confirm your appointment by going to " + html_link + ".<br><br>"
+ "Thank you, <br>"
+ "Signature"
MailApp.sendEmail({
to: email,
subject: emailSubject,
body: "Can add a Plain Text version of the email body here for email apps that dont do html",
htmlBody: html_body
})
sentArray.push([true])
Logger.log("mail sent to "+name)
}
else{
sentArray.push([true])
}
}
usersheet.getRange(2,5,userValues.length).setValues(sentArray)
}
User Details (sheet1)
Form Responses (sheet2)
Email
Form - Confirm appointment

Sending the same multiple emails instead of 1 email for loop bug

I have bug where when I run my send email function. its sending multiple emails instead of just one email notification here is my code what am I doing wrong??!?! I got 31 of the same emails. I believe the issue the for loop is sending an email each time the if statement is true instead of just one time if its true help.
here is my code:
function sendEmail(){
var ss = SpreadsheetApp.getActiveSpreadsheet(); //get active spreadsheet only! to get the url for the filter view
var SpreadsheetID = ss.getSheetId(); // get the sheet Id
var spreadsheetURL = ss.getUrl(); // get the current active sheet url
var SpreadsheetID = spreadsheetURL.split("/")[5]; // using the last / for getting the last parts of the email
var filterViewName = 'PO_Log Precentage'; // Name of the filter view you want to get the url from & MAKE SURE Title matches view name account for "spaces" too
var filterViewID = filterId(SpreadsheetID, filterViewName); // Getting filter view id
var url = createURL(spreadsheetURL, filterViewID); // creating the url to send the filter view id
Logger.log(url);// Testing to see the correct url is created
var po_numID = ss.getSheetByName("Purchase Orders List").getRange("A2").getDisplayValue().substr(0,3);// Gets the Purchase Order List Sheet and the PO# the first 3 Characters of the PO in A2
Logger.log(po_numID);
var email_va = ss.getSheetByName("Purchase Orders List");
//gonna build statuses to look for into array
var statusesToEmail = ['On-going', '']
//"Status" is in Column T (Col 2)
//"Precent" is in Column Q (Col 3)
var data = email_va.getDataRange().getValues()
// //var headerRowNumber = 1; // When checking for emails in the sheet you want to exclude the header/title row
var emailDataSheet = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/17G0QohHxjuAcZzwRtQ6AUW3aMTEvLnmTPs_USGcwvDA/edit#gid=1242890521").getSheetByName("TestA"); // Get The URL from another spreadsheet based on URL
Logger.log(emailDataSheet.getSheetName());
var emailData = emailDataSheet.getRange("A2:A").getDisplayValues().flat().map(po => po.substr(0,3));
Logger.log(emailData)///Working to get the first 3 charcters in column A
var subject = po_numID + " Po Log Daily Notification "; // Unique PoTitle of the email
var options = {} // Using the html body for the email
options.htmlBody = "Hi All, " + "The following" + '<a href=\"' +url+ '" > Purchase Orders </a>' + "are over 90% spent" + "";
for(var i = 0; i < data.length; i++){
let row = data[i];
if( statusesToEmail.includes(row[1]) & (row[2] >= .80)){
emailData.every((po, index) => {
if (po == po_numID){
const email = emailDataSheet.getRange(index + 2,7).getValue();//Getting the last colmun on the same row when the Po# are the same.
console.log(email);
MailApp.sendEmail(email, subject, '', options); // Sending the email which includes the url in options and sending it to the email address after making sure the first 3 Charcters Of the PO_log are the same as
return false;
} else {
return true;
}
});
}
}
}
here is the spreadsheet
https://docs.google.com/spreadsheets/d/1QW5PIGzy_NSh4MT3j_7PggxXq4XcW4dCKr4wKqIAp0E/edit#gid=611584429
you have to use the break function if u wish to stop the loop once the loop has been fulfiled, because if im not wrong , the email is sent if the IF condition is met , thus in the block that has mailapp.sendemail , you have to add in a break otherwise the loop will keep on happening. this is the basic of javascript and you should read up more about the FOR loop here
break as in just type "break" at the end of the code so the script will not continue to loop once the condition has been met.

Google Sheet - Send Email

I need my google sheet to send emails every time a condition becomes true.
In this case, every time value of C2 is lower than value of J2.
On the cell L2 there is the email address.
The code (found online and just edited)
function CheckPrice() {
var LastPriceRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Alerts").getRange("C2");
var LastPrice = LastPriceRange.getValue();
var EntryLimitRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Alerts").getRange("J2");
var EntryLimit = LastPriceRange.getValue();
var StockNameRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Alerts").getRange("B2");
var StockName = LastPriceRange.getValue();
// Check totals sales
if (LastPrice < EntryLimit){
// Fetch the email address
var emailRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Alerts").getRange("L2");
var emailAddress = emailRange.getValues();
// Send Alert Email.
var message = 'Ticker ' + StockName + ' has triggered the alert';
var subject = 'Stock Alert';
MailApp.sendEmail(emailAddress, subject, message);
}
}
With this code I don't receive any error, but I don't even receive the email.
I granted permissions as requested when I run the script for the first time.
On L2 I put the same email address I granted permission (I send email to myself).
I did a try even putting a secondary email address I have.
Can you please show me what's wrong ?
Issues:
See the first lines of your code where you define LastPrice,
EntryLimit and StockName. All of them are coming from the same
range: LastPriceRange.
I also removed all the unnecessary calls in your script. There is no
need to call
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Alerts") so
many times when you can just put it in a variable and use that
variable instead.
Also, you don't need to define unnecessary
variables. For example, you can get the value of a cell with one line:
sh.getRange("B2").getValue().
Solution:
function CheckPrice() {
const sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Alerts");
const LastPrice = sh.getRange("C2").getValue();
const EntryLimit = sh.getRange("J2").getValue();
const StockName = sh.getRange("B2").getValue();
// Check totals sales
if (LastPrice < EntryLimit){
// Fetch the email address
const emailAddress = sh.getRange("L2").getValue();
// Send Alert Email.
const message = 'Ticker ' + StockName + ' has triggered the alert';
const subject = 'Stock Alert';
MailApp.sendEmail(emailAddress, subject, message);
}
}
If you want an email to be sent when you edit a particular cell, then you need to transform the aforementioned solution to an onEdit(e) trigger. If you want a time basis trigger then you can just use the solution above directly.

google sheets script editor - send email if there is specific text in column E

if any row in column E has "get fish" then the email should send, - is this part
correct? : -
if (monthSales = "get fish"){
the full code is below: -
function CheckSales() {
// Fetch the monthly sales
var monthSalesRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("myfish").getRange("E1:E1000");
var monthSales = monthSalesRange.getValues();
// Check totals sales
if (monthSales = "get fish"){
// Fetch the email address
var emailRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getRange("B2");
var emailAddress = emailRange.getValue();
// Send Alert Email.
var message = 'Get Fish '
var subject = 'Get Fish';
MailApp.sendEmail(emailAddress, subject, message);
}
}
Try var emailAddress = emailRange.getValue(); getValues() returns a 2d Array even for one cell. getValue() returns one value. Look at what getValues returns.

Auto-direct emails to specific addresses on Google Form submit

This is my first post so apologies in advance if I am posting to the wrong place or asking a question that has been answered elsewhere - go easy on me!
In a nutshell, I have a Google Form and a connected Google Sheet. I need to automate it so that, when a new form is submitted, an email is sent to a specific colleague (the student's supervisor). I have had a good go myself but am now totally stuck!
I have created the form, linked it to a sheet, written the code, added the trigger and tested by submitting a form. Nothing happened! No error messages, just... nothing!
Any advice hugely appreciated. I am very new to this and still taking baby steps.
The code I have cobbled together (which is probably full of errors!) is as follows:
function wa132657(e) {
//setup the spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
//get the range from OnFormSubmit
var range = e.range;
Logger.log("DEBUG: the range is "+range.getA1Notation());//DEBUG
// get the data for the range
var response = row.getValues();
// get the supervisor name from the form submission
var supervisor = response[0][1];
Logger.log("DEBUG: Supervisor = "+supervisor);// DEBUG
// get the emails list
var emailSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SupEmails");
// get ALL the data from this sheet
var emaildata = emailSheet.getDataRange().getValues();
// check how many rows of data
var emailLastRow = emailSheet.getLastRow();
// start the loop through the emails data
for (var i=1; i<emailLastRow; i++){
// if the supervisor is equal to SupervisorEmail
if (supervisor == emaildata[i][0]){
// there is a match
//Next, get the email address
var emailSupervisor = emaildata[i][1];
Logger.log("DEBUG: supervisor = "+emaildata[i][0]+", email address: "+emailSupervisor);// DEBUG
// Finally, send the Email.
var theirName = e.values[2];
var theirProgramme = e.values[3];
var theAbsenceReason = e.values[8];
var theAbsenceStart = e.values[5];
var theAbsenceEnd = e.values[6];
var subject = "Student Absence Report";
var message = "New Absence Report: " + theirName + " \n Programme: " + theirProgramme; + " \n\n
Reason for Absence: \n" + theAbsenceReason + " \n Start of Absence" + theAbsenceStart + "\n End of Absence:" + theAbsenceEnd;
MailApp.sendEmail(emailSupervisor, subject, message);
}
}
}