Google Forms Email Notifications based on response - google-apps-script

I am designing a questionnaire that requires respondents to input their name and a company code that is specific to their employer. I would like to have a script so that a different company will get an email notification depending on which company code is specified. I created a Google Sheet in the Form that lists company codes, corresponding emails, and messages.
I have found a script that does this but I have to tailor it to my own form. Can anyone do this or has a better code?
Link to Demo Form: Here
Link to demo spreadsheet: Here
//using the obtained settings to set up email info
function onOpen(e) {
FormApp.getUi().createMenu('Authorizer').addItem('Authorize', 'authorize').addToUi();
}
//Easily authorize script to run from Form Editor interface
function authorize(){
var respEmail = Session.getActiveUser().getEmail();
MailApp.sendEmail(respEmail,"Form Authorizer", "Your form has now been authorized to send you emails");
}
function setSettings(e){
var response = e.response;
var settings = getSettings();
var emailSubject = settings[1][2];
var emailMsg = settings[1][3];
var formCompany = getResponse(response,"Company Code");
var formName = getResponse(response,"Name");
var emailAddr;
var companycode;
//loop through and grab the selected school from the Settings spreadsheet.
for (i in settings){
if (settings[i][0] === formcompanycode){
school = settings[i][0];
emailAddr = settings[i][1];
}
}
//build email and send to email send function
emailMsg = emailMsg + '\n' + 'Company Code: ' + formSchool + '\n' + 'Name: ' + formName;
mailSendSimple(emailAddr,emailSubject,emailMsg);
}
//function to find the selected company code.
function getResponse(response,formItem){
var selected;
//loop through the form response to find the company code
for (var i = 0; i < response.getItemResponses().length; i++){
if (formItem == response.getItemResponses()[i].getItem().getTitle()){
selected = response.getItemResponses()[i].getResponse();
}
}
return selected;
}
//grabbing general settings from spreadsheet sheet Settings
function getSettings() {
var form = FormApp.getActiveForm();
var ssID = form.getDestinationId();
var ss = SpreadsheetApp.openById(ssID);
var sheet = ss.getSheetByName("Settings");
var lastRow = sheet.getLastRow();
var lastColumn = sheet.getLastColumn();
var range = sheet.getRange(1,1,lastRow,lastColumn);
var values = range.getValues();
return values;
}
//function to send out mail
function mailSendSimple(emailAddr,emailSub, emailMsg){
MailApp.sendEmail(emailAddr,emailSub, emailMsg); //{cc: ccUser}
}

Partial answer
In formcompanycode used in the line
if (settings[i][0] === formcompanycode){
is not defined.
Remarks
See How can I test a trigger function in GAS?. The technique described there will help you to debug your code and find other errors.

Related

Sending automatic emails to specific email addresses once rows are edited in google sheet

I'm new to g-scripts and facing some issues in coming up with the code for the below. My goal is:
Want to send an automatic email to specific people once the information in any of the rows in the google sheet are edited.(note: the range is the whole sheet)
For each row in the google sheet, there's an email address next to it (under a new column) which specifies the person this automatic email should be sent to.
Can the changes be compiled once per day and sent via 1 email per email address?
Thank you in advance for your help.
Currently, this is my code:
function onEdit(e){
var rows = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("sheet1").getRange(30000,30).getValue();
var headerRow = rows.shift();
var editedRow = e.range.getRow();
var template = HtmlService.createTemplateFromFile("Template1.html");
template.headerRow = headerRow;
template.editedRow = editedRow;
template.rows = rangeValues;
var html = template.evaluate().getContent();
function sendEmails(){
var ss=SpreadsheetApp.getActiveSpreadsheet().getSheetByName("sheet1").activate();
var ss=SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var lr=ss.getLastRow();
//getting email body:
var sheet2Text = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("sheet2").getRange(1,1).getValue();
// Logger.log(emailText);
var quotaLeft = MailApp.getRemainingDailyQuota();
Logger.log(quotaLeft);
if((lr-1)>quotaleft){
Browser.msgBox("You have"+quotaLeft+"left & you're trying to send"+(lr-1)+"emails. Emails not sent");
} else{
for(var i=2; i<lr; i++){
var currentEmail = ss.getRange(i,26).getValue();
var currentClientName = ss.getRange(i,1).getValue();
var currentTeamName = ss.getRange(i,27).getValue();
var messageBody = sheet2Text.replace("{name}",currentTeamName);
var subjectLine = "notification on" + currentClientName + "process list", html;
MailApp.sendEmail(currentEmail, subjectLine, messageBody);
//26 is the column number that contains the emails in the google sheet
} //closing the for loop
} // closing the else loop
} // closing the function sendEmails
} // closing the onEdit function

Showing exception error while trying to send emails with a sheet as an excel attachment

I am trying to send emails with a specific tab of a Google Spreadsheet as an Excel attachment to 40-50 students using installable edit trigger. It is showing
Exception: You do not have permission to call UrlFetchApp.fetch. Required permissions: googleapis.com/auth/script.external_request.
I reviewed several related posts and answer at Stackoverflow and Google but can't find anyway to do it manually.
My codes are:
function classAttendance(e){
var spreadsheet = SpreadsheetApp.getActive();
var dashboard = spreadsheet.getSheetByName("Dashboard");
var sheetName = dashboard.getRange("A4").getValue();
var sheetw = dashboard.getRange("A8");
var sheetw2 = dashboard.getRange("G8");
if (sheetName == 'All'){
if (e.range.getA1Notation() === 'C6' && e.range.getValue() === "Send Emails") {
sheetw.setValue('Sending emails to all students. Please Wait!').setFontColor('Red');
//refreshSheet();
sendEmails();
sheetw.setValue('You may take class attendance now. Thank You!').setFontColor('Green');
sheetw2.setValue('You may do manual entry now. Thank You!').setFontColor('Green');
}
if ((e.range.getA1Notation() === 'C6') && (e.range.getValue() === "Start 1-Period" || e.range.getValue() === "Start 2-Period" || e.range.getValue() === "Error Correction")) {
dashboard.getRange("C6").setValue('Please Select');
}
}
}
function sendEmails(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ssID = ss.getId();
var sheetName = ss.getName();
var sh = SpreadsheetApp.getActive();
var sheet1 = sh.getSheetByName("TempDataSet");
var shID = sheet1.getSheetId().toString();
var subject = 'Your Attendance Record at BDU';
var body = 'Dear Student,'+ '\n\n' + 'Greetings! Please find the attendance record attached for your reference.' + '\n\n' + 'Thank you.';
var requestData = {"method": "GET", "headers":{"Authorization":"Bearer "+ScriptApp.getOAuthToken()}};
var url = "https://docs.google.com/spreadsheets/d/"+ ssID + "/export?format=xlsx&id="+ssID+"&gid="+shID;
var result = UrlFetchApp.fetch(url , requestData);
var contents = result.getContent();
var column = 3;
contents.sort({column: column, ascending:true});
var sheet2 = sh.getSheetByName('StudentList');
var data = sheet2.getLastRow();
var students = [];
var students = sheet2.getRange(2, 6, data).getValues();
for (var i=0; i<students.length; i++){ // you are looping through rows and selecting the 1st and only column index
if (students[i][0] !== ''){
MailApp.sendEmail(students[i][0].toString(), subject ,body, {attachments:[{fileName:sheetName+".xls", content:contents, mimeType:"application//xls"}]});
}
}
}
I created a standalone scripts where there are many functions including sendEmails() at my Google drive, then invoked the scripts as a library to my Google spreadsheet. Then I called the library in the script editor of my Google Sheet and also created an onEdit trigger for sendEmails(). All other functions in the library called are working fine.
The library seems to be added after adding the trigger. Hence authorization scopes are missing from previous authorization. The following should trigger re-authorization:
Remove the installed edit trigger and re-add it.
Click Run button after selecting classAttendance2 manually from script editor>

MailApp.SendEmail script for multiple tabs

I have been looking how to write the script to check and run on multiple tabs. What I have now, I would need to copy/paste and set execution triggers one by one.
Script I have:
function SendEmail() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("1");
var value = sheet.getRange("F3").getValue();
var subject = "subject";
var message = "message";
if (value >0){
MailApp.sendEmail("email", subject, message);
}
}
I have this running every 8 hours (trigger run).
I am looking to add more tabs so that for each tab the script can check and send an email if the value of individual tabs is more than 0.
Any ideas on how to do this?
The value in every tab is under F3. Tab names, for example, 1,2,3,4...
Thank you!!!
This should do what you looking for if I understood the issue correctly.
function SendEmail() {
//Get the Spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
//Get all Sheets in the Spreadsheet
var sheets = ss.getSheets();
//Create a variable for the email address, subject and message
var email = "";
var subject = "";
var message = "";
//Can change the starting sheet by changing the value of "i" - 0 will be the first sheet.
for (var i = 0; i < sheets.length; i++){
var sheet = sheets[i];
var value = sheet.getRange("F3").getValue();
switch(sheet.getSheetName) {
case "Sheet1":
email = "email1#domain.com";
break;
case "Sheet2":
email = "email2#domain.com";
break;
default:
value = 1
email = "yourEmailAddress#domain.com";
subject = "Message Failed to Send";
message = "There was an error sending email, please investigate";
}
if (value >0){
MailApp.sendEmail(email, subject, message);
}//END OF IF STATEMENT
}//END OF FOR LOOP
}//END OF FUNCTION

How to have simple google apps script send mails from Sheets from owner account regardless of who's accessing file

I've clicked around for the past few days trying to find an answer but can't seem to find one that makes sense to me (forgive me, I'm fairly new to GAS). I am trying to set up a Fantasy Golf Draft sheet to be used by about 12 users, but over half of which don't have/aren't willing to use a Gmail address. Getting access to the file is no problem, where I am running into an issue is trying to run a script, where when a Button/Shape is clicked, it sends an automated email to the next person who's turn it is to pick. The functionality of the script is working, when it comes from myself or someone with a Google account who can authorize the script etc. I run into troubles when it's someone without a Google account.
My question - how can I set the script to ONLY send from my email, or the Sheet/Script Owner's email - regardless of who is modifying/clicking the button? I see links about creating the script as a webapp to do this, but I get lost quickly.
Here's a link to my sheet:
[https://docs.google.com/spreadsheets/d/16AppcmrcuhatnzcEs7eIQyD_p1swbRimRZZ4FdbhBKI/edit?usp=sharing][1]
And here is my send mail code:
function sendAlertEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("Send Mails"));
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getRange("A2:f2");
var data = dataRange.getValues();
for (i in data) {
var rowData = data[i];
var emailAddress = rowData[1];
var recipient = rowData[0];
var message1 = rowData[2];
var message2 = rowData[3];
var message3 = rowData[4];
var message4 = rowData[5];
var message = 'Hey ' + recipient + ',\n\n' + message1 + '\n\n' + ' The last player picked was ' + message2 + '\n\n' + message3 +'\n\n' + message4;
var subject = '*GOLF DRAFT 2018* - YOU ARE ON THE CLOCK';
MailApp.sendEmail(emailAddress, subject, message);
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("DRAFT"));
}
}
Any help would be greatly appreciated!
I felt interested in this issue and worked a bit more on it. I changed from it being a get request to being a post request.
Here is what I have in the Google sheet.
function sendAlertEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("Send Mails"));
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getRange("A2:f2");
var data = dataRange.getValues();
for (i in data) {
var rowData = data[i];
var emailAddress = rowData[1];
var recipient = rowData[0];
var message1 = rowData[2];
var message2 = rowData[3];
var message3 = rowData[4];
var message4 = rowData[5];
var message = 'Hey ' + recipient + ',\n\n' + message1 + '\n\n' + ' The last player picked was ' + message2 + '\n\n' + message3 +'\n\n' + message4;
var subject = '*GOLF DRAFT 2018* - YOU ARE ON THE CLOCK';
var data = {
'name': 'Bob Smith',
'email': 'a#b.com',
'message': message,
'subject': subject,
};
var options = {
'method' : 'post',
'contentType': 'application/json',
'payload' : data
};
var secondScriptID = 'STANDALONE_SCRIPT_ID'
var response = UrlFetchApp.fetch("https://script.google.com/macros/s/" + secondScriptID + "/exec", options);
Logger.log(response) // Expected to see sent data sent back
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("DRAFT"));
// Browser.msgbox("Your Pick Has Been Made");
}
}
Below is what I have in the standalone script. There are some provisos on the standalone script working:
It needs to be published under "Deploy as a webapp"
Access should be set to 'Anyone, even anonymous'
Every time you make a change to the standalone script publish again and
change the Project version to new. This is so the call from the first sheet calls to the latest code.
Standalone Script
function convertURItoObject(url){
url = url.replace(/\+/g,' ')
url = decodeURIComponent(url)
var parts = url.split("&");
var paramsObj = {};
parts.forEach(function(item){
var keyAndValue = item.split("=");
paramsObj[keyAndValue[0]] = keyAndValue[1]
})
return paramsObj; // here's your object
}
function doPost(e) {
var data = e.postData.contents;
data = convertURItoObject(data)
var recipient = data.email;
var body = data.message;
var subject = data.subject;
try {
MailApp.sendEmail(recipient, subject, body)
}
catch(e){
Logger.log(e)
}
return ContentService.createTextOutput(JSON.stringify(e));
}
No, you can't do that, because a script can be shared with a multiple users and it is always executed from their own account not from the script owners account and script uses the 'from email address' of the executing user, it is not allowed by Google to send email from another users account as a security policy.
You could use a second script that belongs to you. From your first script send a fetch request to the second script, the second script can send an email from your account to anyone. The second script would look like this:
function doGet(e) {
var recipient = e.parameter.email;
var body = e.parmeter.message
var subject = "My golf thing"
try {
MailApp.sendEmail(recipient, subject, body)
}
catch(e){
Logger.log(e)
}
}
The first script would need a fetch request something like this.
var response = UrlFetchApp.fetch("https://script.google.com/macros/s/SECOND_SCRIPT_ID/exec?email=b#b.com&message=somthing");
return response;

How to add unique code to each response in responses spreadsheet in Google Forms?

I used Google's Quickstart: Add-on for Google Forms to enable e-mail notifications for respondents of my form. I also added a few lines to send unique code to each respondent and I would like to have these codes stored in responses sheet.
The code below sends the message with code, but it doesn't store code in responses sheet.
function sendRespondentNotification(response) {
var form = FormApp.getActiveForm();
var settings = PropertiesService.getDocumentProperties();
var emailId = settings.getProperty('respondentEmailItemId');
var emailItem = form.getItemById(parseInt(emailId));
var respondentEmail = response.getResponseForItem(emailItem)
.getResponse();
if (respondentEmail) {
var template =
HtmlService.createTemplateFromFile('RespondentNotification');
template.paragraphs = settings.getProperty('responseText').split('\n');
template.kod = (new Date).getTime().toString(16).substring(5);
template.notice = NOTICE;
var message = template.evaluate();
MailApp.sendEmail(respondentEmail,
settings.getProperty('responseSubject'),
message.getContent(), {
name: form.getTitle(),
htmlBody: message.getContent()
});
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var LastRow = sheet.getLastRow();
var cell = sheet.getRange(LastRow, 5);
cell.setValue(template.kod);
}
}
you could use onFormSubmit to generate the unique id and include it in the email for a webapp to use. that id could be something simple like the row number of the response (not in e.values thou) or generate on the fly and write to the responses spreadsheet as a new column. adding columns does not break the form.