I was looking for a solution to send automated emails from a Google Sheet connected to a Google Form, so I found Google Scripts. I never worked with it (or other scripts) before, so it's all new to me. I did find a lot of information on the internet, but I still have some questions.
Let's explain the situation. So I'm selling two different products in a Google Form, they both have a different price, so I was looking for a solution to send mails to the customers with the total price and some extra information. I have a Google Sheet where all the answers are put in automatically.
So I have 12 columns, as you can see in a copy of my sheet. https://docs.google.com/spreadsheets/d/1CrA9cNAwsUdLyaxzFiJrtXxu-0eiIMiA3IEaEaIYlZo/edit?usp=sharing
The script I use is added as a picture.
The problems:
The script should prevent Google from sending duplicates, but that doesn't work
I used a formula to fill the total amount in the sheet (column L) but I can't add it in the text of the script to send it in the mail
What I want:
Automated mails, can I add the script as a add-on or how do I automate it in the sheet? Now I need to press the "play script" button every time
I want the duplicate tracker to work, so no-one gets 2 mails
I want the script to scan enough rows, so everyone gets a mail
I want the total amount in the text of the mail
That's it I guess, thanks for helping!
// This constant is written in column C for rows for which an email
// has been sent successfully.
let EMAIL_SENT = 'EMAIL_SENT';
/**
* Sends non-duplicate emails with data from the current spreadsheet.
*/
function sendNonDuplicateEmails() {
try{
// Get the active sheet in spreadsheet
const sheet = SpreadsheetApp.getActiveSheet();
let startRow = 3; // First row of data to process
let numRows = 3; // Number of rows to process
// Fetch the range of cells A2:B3
const dataRange = sheet.getRange(startRow, 1, numRows, 300);
// Fetch values for each row in the Range.
const data = dataRange.getValues();
for (let i = 0; i < data.length; ++i) {
const row = data[i];
const emailAddress = row[1]; // Second column
const message = 'Beste ' + row[4] + '\n\nBedankt voor uw bestelling, we hebben deze succesvol ontvangen!' + '\n\nU bestelde ' + row[2] + ' pakjes droge worsten en ' + row[3] + ' pakjes pannenkoeken.' + '\nDit vormt dus ' + row[2] + ' x €6 en ' + row[3] + ' x €6,5.' + '\nIn totaal komt dit op ' + ' euro.' + '\n\nDe bestelling is pas officieel na overschrijving van bovenstaand bedrag op het rekeningnummer BE04 7755 8091 4631 met als mededeling: ' + row[2] + ' DW en ' + row[3] + ' PK.' + '\n\nBij vragen of opmerkingen kunt u ons altijd een mailtje sturen via info#chirozedelgemdorp.be.' + '\n\nChiro Zedelgem Dorp dankt u, laat het u smaken!';
const emailSent = row[11]; // Elfde kolom
if (emailSent !== EMAIL_SENT) { // Prevents sending duplicates
let subject = 'Worst- en pannenkoekenverkoop | Chiro Zedelgem Dorp';
// Send emails to emailAddresses which are presents in First column
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(startRow + i, 11).setValue(EMAIL_SENT);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}
catch(err){
Logger.log(err)
}
}
Related
I would like an email sent when a cell value is above a certain amount
I would like an email sent when cell c6 value is >=4.Heres the script I'm currently using that does not send me an email
function sheetTracker(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var cell = ss.getActiveCell().getA1Notation();
if(Session.getActiveUser()!='trdforlife#gmail.com' &&
Number(ss.getActiveCell().getValue())>=4 && cell=='c6'){
MailApp.sendEmail('yourmail#gmail.com', 'Modification in the spreadsheet',
'Cell ' + cell + ' has been modified by '+ Session.getActiveUser() +
' - new value = ' + ss.getActiveCell().getValue().toString());
}
}`your text`
I was wondering if you could please help. I am trying to use the MailApp.sendEmail method to send emails when a date is entered into column M. I currently use a button on the spreadsheet to trigger the sending of emails and this works fine: emails are sent.
I naturally wish for duplicate emails not to be sent and as such I wish for the "EMAIL_SENT" value to entered into Column N at the moment I trigger the sending of emails, but this does not work. This is despite my code pretty much replicating what is shown on google's own page (https://developers.google.com/apps-script/articles/sending_emails) et al.
I also wish it to generate a timestamp into Column O when emails are sent. Again, this does not work, but I can believe my approach is not correct. I'll be honest and say I am new to this!
Please advise me on where the errors are in my code.
var EMAIL_SENT = "EMAIL_SENT";
function SEWEmailReminder() {
var sheet = SpreadsheetApp.getActiveSheet();
var numRows = sheet.getLastRow(); // nothing to change
var startRow = "9"; // put the row number where the formula should start
var range = sheet.getRange(startRow, 1, numRows, 22) // Fetch the range of cells A9:Vx
var data = range.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var programmeid = row[0]; // 1st column A
var programmename = row[1]; // 2nd column B
var author = row[2]; // 3rd column C
var authoremail = row[3]; // 4th column D
var comments = row[4]; // 5th column E
var programmestatus = row[5]; // 6th column F
var datadate = row[6]; // 7th column G
var plannedcompletiondate = row[7]; // 8th column H
var completiondate = row[8]; // 9th column I
var presubjointreviewdate = row[9]; // 10th column J
var plannedsubdate = row[10]; // 11th column K
var jvissuedate = row[11]; // 12th column L
var sewresponsedate = row[12]; // 13th column M
var emailsent = row[13]; // 14th column N
var emailtimestamp = row[14]; // 15th column O
var sewreviewdate = row[15]; // 16th column P
var jvreceiveddate = row[16]; // 17th column Q
var difference = row[17]; // 18th column R
var rejectedaccepted = row[18]; // 19th column S
var recipients = row[19]; // 20th column T
var forclientacceptance = row[20]; // 21st column U
var jvreceiveddate = row[21]; // 22nd column V
var subject = "SEW Notification Email";
var message = "Dear " + author + ",\nYou have received this email to notify you that the SEW Response Date is " + sewresponsedate + " for Programme ID " + programmeid + ", titled " + programmename + ".\nKind Regards,\nAdmin"
if (row[12] != "") {
if (emailsent != EMAIL_SENT) { // Prevents sending duplicates
MailApp.sendEmail(authoremail, subject, message);
sheet.getRange(startRow + i, 14).setValue(EMAIL_SENT);
sheet.getRange(startRow + i, 15).setValue(new Date()); // set date & time stamp
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}
}
I have looked at this code and they just seem to simply update theirs every day with the HTML, but I know there's a way to make a custom date by altering Monday to be Morndas, Sunday to be Sundas, January as Morning Star, etc. How would I go about coding this for my own website, as it's a cool little feature to have on an Elder Scrolls website, and I am not always available to update it every night at midnight.
Thanks
I think this is best done using server side scripting, like PHP. But below I've given a Javascript implementation which you can easily embed. Once you learn about server side scripting, it should be trivial to translate this code to another language.
window.addEventListener('DOMContentLoaded', function() {
// Function to determine the postfix of the month number
function numberPostFix(nr) {
nr = nr % 100;
if (nr >= 10 && nr < 20) return 'th';
nr = nr % 10;
if (nr == 1) return 'st';
if (nr == 2) return 'nd';
if (nr == 3) return 'rd';
return 'th';
}
// Arrays of custom month names.
var monthNames = [
"Morning Star",
"Sun's Dawn",
"First Seed",
"Rain's Hand",
"Second Seed",
"Mid Year",
"Sun's Height",
"Last Seed",
"Hearthfire",
"Frostfall",
"Sun's Dusk",
"Evening Star"
];
// Array of custom weekday names.
var dayNames = [
"Sundas",
"Morndas",
"Tirdas",
"Middas",
"Turdas",
"Fredas",
"Loredas"
];
// Get all relevant parts.
var date = new Date();
var month = date.getMonth();
var monthday = date.getDate();
var weekday = date.getDay();
// Construct the day text.
var dateHtml = "Today is " + dayNames[weekday] + ", " + monthday + "<sup>" + numberPostFix(monthday) + "</sup> of " + monthNames[month];
// Write to document.
document.getElementById('date').innerHTML = dateHtml;
});
<header>
<h2>Welcome, this is your page header.</h2>
<span id="date"></span>
</header>
I've been trying for days to create charts with an intelligent range, that differs when the data in the google spreadsheet is updated. However i succeeded doing so, i can't get the .setOption aspect to work. I want for example, a title, description etc with the chart. But this is not the main issue since i can insert there by hand.
More important however is the range name, because there isn't when i use the script. So, within the chart it is not possible to see what each column represents, and i really want to fix that. I tried to use the .setNamedRange() aspects, but that is not working.
Someone who can help me with that?
function check() {
var sheet = SpreadsheetApp.getActiveSheet();
var end = sheet.getLastRow();
var start = (end - 5);
var endnew = (end - 4);
var startnew = (end - 6);
if(sheet.getCharts().length == 0){
Logger.log("Er is geen grafiek");
var chartBuilder = sheet.newChart()
.asColumnChart().setStacked()
.addRange(sheet.getRange("A" + startnew + ":" + "A" + endnew)) // should have a name
.addRange(sheet.getRange("B" + startnew + ":" + "B" + endnew)) // should have a name
.addRange(sheet.getRange("E" + startnew + ":" + "E" + endnew)) //should have a name
.setOption('title', 'Effectief gebruik kantoorruimte') //not working
.setPosition(10, 10, 0, 0)
var chart = chartBuilder.build();
sheet.insertChart(chart);
}
else{
Logger.log("Er is wel een grafiek");
var charts = sheet.getCharts();
for (var i in charts) {
var chart = charts[i];
var ranges = chart.getRanges();
var builder = chart.modify();
for (var j in ranges) {
var range = ranges[j];
builder.removeRange(range);
builder
.addRange(sheet.getRange("A" + (start) + ":" + "A" + end)) //should have a name
.addRange(sheet.getRange("B" + (start) + ":" + "B" + end)) //should have a name
.addRange(sheet.getRange("E" + (start) + ":" + "E" + end)) // should have a name
.setOption('title', 'Effectief gebruik kantoorruimte')
.build();
sheet.updateChart(builder.build());
}
}
}
}
I'm assuming that this code is the issue?
builder
.addRange(sheet.getRange("A" + (start) + ":" + "A" + end))
Maybe try using the JavaScript toString() method to make sure that your text formula is working.
.addRange(sheet.getRange("A" + start.toString() + ":" + "A" + end.toString()))
There is a different format that you can use:
getRange(row, column, numRows, numColumns)
So, it would be:
getRange(start, 1, 1, numColumns)
That starts on row "start" in column A. It gets one row of data, and how ever many number of columns.
I've made the following script with a google form:
function myfunction (e){
var Naam = e.values[1] //column b - works fine
var Adres = e.values[2] //column c - works fine
var Postcode = e.values[3] //column d - works fine
var Woonplaats = e.values[4] //column e - works fine
var Email = e.values[5] //column f - works fine
var Aantal = e.values[6] //column g - works fine
var Totaal = e.values[9] //column j - doesn't work
var Verzendmethode = e.values[11] //column l - doesn't work
var subject = "Bestelling kaarten Getup Standup"
var message = "Beste " + Naam + ",\n\nBedankt voor uw bestelling de "
+ Aantal + " kaarten " + Verzendmethode + " wanneer u "
+ Totaal + " EURO over maakt op rekeningnr.
nl1ABNA1234567890\n\nHartelijk dank voor uw bestelling en
wij wensen u vast een prettige avond"
MailApp.sendEmail(Email, subject, message);
}
Where the value of column j[9] is the outcome of multiplying the value of column g[6] times 5 and adding up the value of column i[8] (which is either 0 or 2,5) depending on the choice in a multiple choice question.
The value of column l[11] is a predefined text, also depending on the choice in a multiple choice question.
Within the spreadsheet everything works correct. I just want to use the values of column j and l within the confirmation mail that goes out to the visitor. Instead it now states undefined.
Any ideas would be very welcome.