Google app script - how to count number of google form response - google-apps-script

It is my first time writing google app script and I am desperately need help.
The purpose is to set up a workshop sign up form. Based on how many people already signed up, an email is sent out to inform if sign up was successful, or was put in the wait list.
I copied code from a tutorial. But need help to get the count of form responses. Here is how it looks like now:
function onFormSubmit(e) {
var timestamp = e.values[0];
var yourName = e.values[1];
var toAddress = e.values[2];
var subject = "Workshop Confirmation";
var emailBody = "Thank you for your submitted on " + timestamp
var num_response = COUNT_NUMBER_OF_RESPONSE // <-- need help here
var LIMIT = 15
if (num_response <= LIMIT) {
emailBody = emailBody + "\n\nYou are enrolled in the workshop";
}
else {
var wait = num_response - LIMIT
emailBody = emailBody + "\n\nThe workshop is full. You are #" + wait + " in the waiting list"
}
emailBody = emailBody + "\n\nThe details you entered were as follows: " +
"\nYour Name: " + yourName +
"\nYour Email: " + toAddress ;
MailApp.sendEmail(toAddress, subject,
emailBody, optAdvancedArgs);
}
I have no clue how to find right answer in the google app document. Any help would be greatly appreciated!

How about the composite function
FormApp.getActiveForm().getResponses().length
no need to go around looking for the spreadsheet (since in my experience, the spreadsheet is not always up to date, whereas the form is)

From what I see in the tutorial, this script is embedded in a spreadsheet so the easiest would be to count the number of rows and substract 1 because of the headers...
There is a method for that : getLastRow(), the doc refered in this link should give you enough information to write the few lines of code you need...
test :
function xx(){
var lr = SpreadsheetApp.getActiveSheet().getLastRow()-1;
Logger.log(lr);
}

Script on form (not spreadsheet)
function onFormSubmit(e) {
var num_response = FormApp.getActiveForm().getResponses().length
var LIMIT = 20 //or whatever
if (num_response < LIMIT) {
}
else {
var form = FormApp.getActiveForm();
form.setAcceptingResponses(false);
}
}

Related

Fixing a trigger

I need a trigger (or two) and I'm doing something wrong. Or maybe I need to tweak my code.
I want an email to send automatically when I update a line in my spreadsheet. The three columns that update are notes, status, and resolution. Right now, in my test version, it sends an email as soon as I change any one of those columns. Which is fine, if I'm only updating one thing. But if I want to add a note, change the status, and enter a resolution all at once, it sends three separate emails. My first trigger for sending an email upon form submission works great.
Here is my code. Any help would be appreciated
PS: I'm sure there are cleaner ways to do this, but I'm familiar with this from the past. It's just been long enough that I don't remember all of it.
function formSubmitReply(e) {
var userEmail = e.values[3];
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow();
// Set the status of the new ticket to 'New'.
// Column F is the Status column
sheet.getRange("F" + lastRow).setValue("New");
// Calculate how many other 'New' tickets are ahead of this one
var numNew = 0;
for (var i = 2; i < lastRow; i++) {
if (sheet.getRange("F" + i).getValue() == "New") {
numNew++;
}
}
MailApp.sendEmail(userEmail,
"Helpdesk Ticket #" + lastRow,
"Thanks for submitting your issue. \n\nWe'll start " +
"working on it as soon as possible. You are currently " +
"number " +
(numNew + 1) + " in the queue. \n\nHelp Desk.",
{name:"Help Desk"});
}​
function emailStatusUpdates() {
var sheet = SpreadsheetApp.getActiveSheet();
var row = sheet.getActiveRange().getRowIndex();
var userEmail = sheet.getRange("D" + row).getValue();
var subject = "Helpdesk Ticket #" + row;
var body = "We've updated the status of your ticket.\n\nStatus: " + sheet.getRange("F" +
row).getValue();
body += "\n\nNotes: " + sheet.getRange("E" + row).getValue();
body += "\n\nResolution: " + sheet.getRange("G" + row).getValue();
MailApp.sendEmail(userEmail, subject, body, {name:"Help Desk"});
}
function onOpen() {
var subMenus = [{name:"Send Status Email", functionName: "emailStatusUpdates"},
{name:"Schedule Appointment", functionName: "scheduleAppointment"},
{name:"Push to KB", functionName: "pushToKb"}];
SpreadsheetApp.getActiveSpreadsheet().addMenu("Help Desk Menu", subMenus);
}​
It looks that you are using an on edit trigger to send and email that works OK when you only need to edit one cell but when you need to edit two or more the email should be sent until you ended to edit all the related cells.
One way to achieve the desired behaviour is to add one or more conditions to send the email.
One way to implement the above is to add an auxiliary column to set if the email should be sent inmediately or not. What about calling this "Hold" and add a checkbox?
This is just is a brief example of how to implement the above as an installe on edit trigger
/**
* Columns C,D,E are notes, status and resolution respectively
* Column F is Hold
*/
function sendUpdate(e){
if(e.range.columnStart > 2 && e.range.columnStart < 6 || e.range.columnStart === 6){
var hold = e.range.getSheet().getRange(e.range.rowStart, 6).getValue();
if( hold !== 'TRUE'){
// Call here your send email function
} else {
// Ask if the email should be sent now
}
}
}

Google Apps Script to send email notification, if the email from an expected sender is not received every 1 hour

I have managed to get email notification alert if I have not received an expected email in past XX day.
By following the guidelines given in - http://baumbach.com/google-script/
It is working as expected.
Here is the javascript code-
function SearchEmail() {
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
for (var i = 1; i < data.length; i++) {
// "in:all " searches trash and spam email folders. Remove "in:all " + to only search all mail and inbox
var gsearch = "in:all " + "from:(" + data[i][1] + ") to:(" + data[i][2] + ") subject:(" + data[i][3] + ") newer_than:" + data[i][4] + "d";
var threads = GmailApp.search(gsearch, 0, 1);
if (threads.length == 0) {
var emailSubject = "No email in " + data[i][4] + " days: - " + data[i][5];
var emailText = "Note: " + data[i][5] + "\r\n\r\nSearch was: " + gsearch;
var emailTo = data[i][0];
MailApp.sendEmail(emailTo, emailSubject, emailText);
}
}
}
But, What I want is, to get email notification alert if I have not received an expected email in past 1 Hour and not days.
Can anyone tell me how to do this and where should I change the code??
Thanks a lot in advance.
EDIT
In the guide from the link you provided and in your code, the date used to query the messages from Gmail comes from the linked spreadsheet you have, so this part would be set by you.
To query the message the code uses the gsearch variable which is formatted by the q parameter guidelines using the Gmail search operators and inserting data in the query from the data variable which is obtained from using the getDataRange and getValues methods to your sheets. For what I see in the search operators, there's no option to query the messages by time, the minimum is 1 day.
Also, they explain they set up a time driven trigger to execute the SearchEmail function once a day. For this part you can use the everyHours method to create a trigger to execute the function once every hour. Run the below function once in order to create the trigger:
function createTimeTriger1hour() {
ScriptApp.newTrigger("SearchEmail")
.timeBased()
.everyHours(1)
.create();
}

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

GScript: Track number of emails sent using mass email Gscript code

I am trying to modify this GScript to count the number of emails sent. I would like to track the total number of emails sent using this function. Would it be easier to do it within this code or to use a code to search the sent box of the user? I believe I know how to make a count value get stored temporarily, but I am unsure how to store it for a greater period of time.
function WhiteTicket() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Email Outline');
var lastRow = sheet.getRange("J1").getValue();
var range = sheet.getRange("A3:"+ lastRow);
var UserData = range.getValues();
for (i in UserData) {
var row = UserData[i];
var firstname = row[1];
var lastname = row[2];
var email = row[3];
var whiteticket = row[6];
if (whiteticket != '0') {
var esubject = "New Tickets";
MailApp.sendEmail({
to: row[3],
subject: esubject,
htmlBody:"Hello " + firstname + "," + '<br />'+'<br />' +
"Please note that you have " + whiteticket + " ticket(s)."});
}
}
if (ok) {
EmailComplete();;
}
}
Requirement:
Record amount of emails sent by this script.
Solution:
Use GmailApp.search() and pass to length to count the amount of emails sent.
Example:
var total = GmailApp.search('in:sent subject:"'+esubject+'"').length;
Logger.log(total);
This is pretty self explanatory, it'll search all of the emails in your sent folder with subject matching the subject string you're assigning with var esubject. The script above just writes it to the log using Logger.log().

Retuning a GMail script to prevent "Exceeded maximum execution time"

I use a gmail account to receive status updates from devices which I have listed in a Google spreadsheet by its user and serial number. The status update email will have the serial number of the device in it's email subject and will usually be sent about once a week per device. Due to the number of devices (600+), I get a pretty constant influx of status updates from various devices every day. What I'm trying to do is setup a script that will search my Inbox and create a list of devices that I haven't received a status update email from which would prompt me to figure out why that device isn't reporting in.
I've modified a script I found online at: http://forums.mozillazine.org/viewtopic.php?f=46&t=2740775. It works by obtaining a device serial number listed in a spreadsheet and searching the Inbox for an email subject with that serial number sent within the past 15 days. The script works fine when the spreadsheet has about 200 items, but beyond that I start getting an "Exceeded maximum execution time" error and I need it to do 600+ items now and more as time goes on. I also had to add the Utilities.sleep(1000) line to avoid a "Service invoked too many times in a short time: gmail rateMax" error. Is there a better way to write this script to avoid these errors?
function SearchEmail() {
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
var waittime = 15;
var emailTo = "temp#email.com";
var emailSubject = "NO EMAIL IN " + waittime + " DAYS FROM FOLLOWING DEVICES";
var emailText = "";
for (var i = 1; i < data.length; i++) {
Utilities.sleep(1000);
var j = i + 1;
var gsearch = "in:inbox subject:(" + data[i][1] + ") newer_than:" + waittime + "d";
var threads = GmailApp.search(gsearch, 0, 1);
if (threads.length == 0) {
var emailText = emailText + j + " Device: " + data[i][1] + " User: " + data[i][0] + "\n";
}
}
MailApp.sendEmail(emailTo, emailSubject, emailText);
}
I'd suggest you see the problem from another point of view.
Could you find a common string to all the emails that your report is sending ? Something like "device status" in the subject or in the body...
This way you could search your inbox for that string, put a label on it so that you avoid rechecking them and use a simple function to check in your spreadsheet if that number is in the list.
function checkList(device){
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
for(var n=0;n<data.length;n++){
if(data[n][0]==device){ return true};// assuming number are in column A
}
return false;
}
then send a mail only if(checkList(device)!=true){
This would be far more efficient I think.