Trigger an Email when text changes in formatted cell? - triggers

I've been tasked with setting up a GoogleSheet that contains information about my team's software and the expiry date of their licenses. I have set up the Sheet so when it reaches an expiry date it changes a column to read "Expired".
What I'd like to happen is that when the cell text changes to "Expired" it send me an email to alert me.
I found some tips online and tried a script but can't seem to get it to function as expected.
Here's what my Google Sheet looks like:
Here's the code i've been trying to adapt:
function sendMailEdit(e){
if (e.range.columnStart != 6 || e.value != "Expired") return;
const rData = e.source.getActiveSheet().getRange(e.range.rowStart,1,1,5).getValues();
let lictyp = rData[0][2];
let swpi = rData[0][1];
let name = rData[0][0];
let msg = "The " + lictyp + "license for " + swpi + "will expire in 10 days time for " + name + "." + "Contact IT to renew licence asap. Kind Regards, LICENSE NINJA!";
Logger.log(msg);
GmailApp.sendEmail("myemail#address.com", "License Expiry Alert", msg)
}

Related

Send automated email based on cell value changes in a range

I'm working on a scoreboard automation process using Google Sheets, but I've come up with a little problem.
I want an automatic e-mail to be sent to a list of emails when a cell value in a range is met.
For example, when an user takes a test, if his/her scores is below 50%, it will instantly send an email to the teacher and the students.
The contents of the email should be able to edit easily based on different scores. For example, if the score is below 30% > send an warning email, if the score is above 60%, send a congratulations email
Other needs:
The script should be able to send notification instantly right after the user complete the test
The script should work when other users use the file, not just the owner of the file
I've used similar Appscripts, however if I use onEdit or onChange trigger, everytime any cell change, it send an email, which is way to many, I only want the email to be sent when the test taker complete a whole test.
The Link of a demo file is below, please take a look. Many thanks https://docs.google.com/spreadsheets/d/1s0IApxtJuUNbHhKRxEpFnJg_rd2_JAk-GjnSUP9VdJs/edit#gid=0
I don't know how to code so I cannot include a script here, I just think that it might be possible to use Google Appscript or some extensions.
Try (set a trigger on the onSpeEdit function when the edit happens)
function onSpeEdit(event) {
var sh = event.source.getActiveSheet();
var rng = event.source.getActiveRange();
if (rng.getColumn() >= 3 && rng.getColumn() <= 11) {
if (sh.getRange(rng.getRow(), 12).getValue() == 'Completed') {
var d = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "MMM dd yyyy hh:mm a");
if (sh.getRange(rng.getRow(), 13).getValue() > 0.5) {
MailApp.sendEmail({
to: sh.getRange(rng.getRow(), 2).getValue(),
cc: sh.getRange('B2').getValue(),
subject: "Congratulations",
body: sh.getRange(rng.getRow(), 14).getValue(),
});
sh.getRange(rng.getRow(), 15).setValue('sent # ' + d)
}
else if (sh.getRange(rng.getRow(), 13).getValue() < 0.3) {
MailApp.sendEmail({
to: sh.getRange(rng.getRow(), 2).getValue(),
cc: sh.getRange('B2').getValue(),
subject: "Warning",
body: sh.getRange(rng.getRow(), 14).getValue(),
});
sh.getRange(rng.getRow(), 15).setValue('sent # ' + d)
}
}
}
}

Custom Email script

I am trying to form a simple order system, which responds to the user with a estimated delivery date once it is inserted into google sheet.
Basically someone completes a google form, which populates the sheet and then I require the sheet to send an email confirmation once a delivery date is manually inserted into the "delivery date" column on the sheet.
Currently the script is:
function CustomEmail() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("B2:L1000");
var UserData = range.getValues();
for (i in UserData) {
var row = UserData[i];
var name = row[5];
var email = row[0];
var score = row[9];
MailApp.sendEmail (row[1], "ORDER CONFIRMATION", "Order Confirmation of: " + name + ". The estimated delivery date is " + score);
}
}
It seems to work but it emails all of the rows of data, so I receive multiple emails each time and it will duplicate. I need it to just send an email to the row which has had the date manually inserted in the sheet. The script is designed to email an email address which is captured through the form.
I would like it to email that line only, I have read that it would be best to use an "on edit" trigger. This works but it still sends an email to the whole sheet each time not just the particular line that is edited.
The email response arrives like this:
"Order Confirmation of: 300mm screws. The estimated delivery date is Thu Jan 17 2019 00:00:00 GMT-0000 (GMT)"
Apologies, this is my first attempt at any sort of script so very novice.
Cheers
Joe

What is the procedure to email the test score of a test conducted on google forms?

I have created a test through google form, and I want to send the score result to the participants. I have created a copy of the response and put scoring through if functions. And then in the next worksheet, I have summed the score. Now I want to send that calculated score to the participants. I have entered the script in the script editor and set trigger on form submit but I am getting errors.
Would the error be because the script takes the default sheet and not the one where I have created score function? If so, how do I change that?
Here is the code that I used:
function myFunction(e)
{
var userName = e.values[1];
var userEmail = e.values[2];
var score = e.values[3];
var subject = "Thank you for your participation: Find your Score";
var message = "Thank you, " + userName + " for choosing to participate in this test. Your score is " + score;
MailApp.sendEmail(userEmail, subject, message);
}
There are two ways. Send an e-mail from the form or send a notification from the result collection spreadsheet (limited to spreadsheet collaborators).
For the first, you have to use the script editor found under tools. There are several examples to get you started. I'd recommend you take a look at: http://www.labnol.org/internet/auto-confirmation-emails/28386/
For the second, you use the notifications option, see: https://www.maketecheasier.com/send-email-notifications-google-forms/
Here is the code that I used
function myFunction(e){
var userName = e.values[1];
var userEmail = e.values[2];
var score = e.values[3];
var subject = "Thank you for your participation: Find your Score";
var message = "Thank you, " + userName + " for choosing to participate in this test. Your score is " +score;
MailApp.sendEmail (userEmail, subject, message);}

google form script not triggering

I am trying to create a workflow in google forms. Its a simple leave application form that employees submit to get approval from their managers, HR, and finally management.
The form results feed into the google sheets as intended. i have written the following script in the form and later also in the sheet and set a trigger "on form submit". It worked fine last night and was able to sent the email confirmation i programmed into the script. For whatever reason it decided not to work today. Can someone tell me what they think went wrong? also is it best to create the script in the form or in the spreadsheet. My feeling is that in the spreadsheet might be better but i could be wrong. When the script did run last night, i am not sure which one worked (the one in the sheet or the one in the form). i only got one email for each test submission i made. here is the code:
function leaveProcessInput(e) {
var username = e.values [1];
var name = e.values [2];
var department = e.values [3];
var leaveType = e.values [4];
var fromDate = e.values [5];
var toDate = e.values [6];
var reason = e.values [7];
var releiver = e.values [8];
var contactAway = e.values [9];
var subject = "Your " + leaveType + "Application Form has been submitted";
var message = "Dear " + name + ", your " + leaveType + "from " + fromDate + "to " + toDate + "Application Form has been submitted at " + timestamp + ". You will be notified of its status once we have processed it. Regards, Finance & Admin team.";
MailApp.sendEmail(username, subject, message);
}
I would really appreciate help on the above.
this script (triggered on form submission) should be bound to the spreadsheet, not in the form.
I hope that solves it.
Try removing the spacing between 'e.values' and the [].
e.g. e.values [1] should be e.values[1]
The script should not be attached to the form, but only to the spreadsheet.

Getting a Google Form Script generated email to pipe data into Reponse Sheet

I am currently trying to setup an approval workflow. I'm fairly junior when it comes to some of this stuff. But so far have it working at respectable level to fit our needs with the assistance of an example.
I was using the template/example from Email Approval using Google Script and a Form.
The issue I am running into, with a lack of functionality is that at the time of Accept or Deny via the Email that is generated for approval I would like it to then record that data back into the Google Form row in the last column that the email was generated from.
I may end up adding 2nd timestamp, reply email etc later.
So then that row would show the initial form filled out and then either blank/accepted/deny as the status.
Thank you for any time or assistance.
The approval workflow that James Ferreira originally wrote was intentionally very basic. Enhancing it to provide correlation between approvals and the original requests is simple in concept, yet complicates the code because of details and limitations.
Things that need to considered:
Form responses include a timestamp, which we can use as a sort of "serial number" for responses, since it has a very high probability of being unique in an application like this.
We can pass this identifier along with the rest of the URL embedded in the approval email, which will give it back as a parameter to the webapp, in turn.
Passing an object like a timestamp between applications can be troublesome. To ensure that the URL embedded in the approval email works, we need to encode the string representation of the timestamp using encodeURIComponent(), then decode it when the webapp consumes it.
Searching for matches is simplified by use of ArrayLib.indexOf() from Romain Vaillard's 2D Array library. This function converts all array data to strings for comparisons, so it fits nicely with our timestamp.
Alternatively, we could put effort into creating some other identifier that would be "guaranteed" to be unique.
The approval-response web app (doGet()) does not understand what "activeSpreadsheet" means, even though it is a script contained within a spreadsheet. This means that we need a way to open the spreadsheet and record the approval result. To keep this example simple, I've assumed that we'll use a constant, and update the code for every deployment. (Ick!).
So here's the Better Expense Approval Workflow script.
// Utilizes 2D Array Library, https://sites.google.com/site/scriptsexamples/custom-methods/2d-arrays-library
// MOHgh9lncF2UxY-NXF58v3eVJ5jnXUK_T
function sendEmail(e) {
// Response columns: Timestamp Requester Email Item Cost
var email = e.namedValues["Requester Email"];
var item = e.namedValues["Item"];
var cost = e.namedValues["Cost"];
var timestamp = e.namedValues["Timestamp"];
var url = ScriptApp.getService().getUrl();
// Enhancement: include timestamp to coordinate response
var options = '?approval=%APPROVE%&timestamp=%TIMESTAMP%&reply=%EMAIL%'
.replace("%TIMESTAMP%",encodeURIComponent(e.namedValues["Timestamp"]))
.replace("%EMAIL%",e.namedValues["Requester Email"])
var approve = url+options.replace("%APPROVE%","Approved");
var reject = url+options.replace("%APPROVE%","Rejected");
var html = "<body>"+
"<h2>Please review</h2><br />"+
"Request from: " + email + "<br />"+
"For: "+item +", at a cost of: $" + cost + "<br /><br />"+
"Approve<br />"+
"Reject<br />"+
"</body>";
MailApp.sendEmail(Session.getEffectiveUser().getEmail(),
"Approval Request",
"Requires html",
{htmlBody: html});
}
function doGet(e){
var answer = (e.parameter.approval === 'Approved') ? 'Buy it!' : 'Not this time, Keep saving';
var timestamp = e.parameter.timestamp;
MailApp.sendEmail(e.parameter.reply, "Purchase Request",
"Your manager said: "+ answer);
// Enhancement: store approval with request
var sheet = SpreadsheetApp.openById(###Sheet-Id###).getSheetByName("Form Responses");
var data = sheet.getDataRange().getValues();
var headers = data[0];
var approvalCol = headers.indexOf("Approval") + 1;
if (0 === approvalCol) throw new Error ("Must add Approval column.");
// Record approval or rejection in spreadsheet
var row = ArrayLib.indexOf(data, 0, timestamp);
if (row < 0) throw new Error ("Request not available."); // Throw error if request was not found
sheet.getRange(row+1, approvalCol).setValue(e.parameter.approval);
// Display response to approver
var app = UiApp.createApplication();
app.add(app.createHTML('<h2>An email was sent to '+ e.parameter.reply + ' saying: '+ answer + '</h2>'))
return app
}
So, I tried this, but there an issue with the formatting for date when it's in the data array. In order to get this to work, you have to reformat the time stamp in the doGet using formatDate.
I used the following to get it to match the formatting that appears in the array.
var newDate = Utilities.formatDate(new Date(timestamp) , "PST", "EEE MMM d yyyy HH:mm:ss 'GMT'Z '(PST)'");
Lastly, of course update the indexof parameter that is passed to newDate.