I created a form using google docs spreadsheet, and created a script that sends an email when the user fills the form:
function sendFormByEmail(e){
var email = "AAA";
var subject = "XXX";
var message = "";
for(var field in e.namedValues)
message += field + ' = '+ e.namedValues[field].toString() + "\n\n";
var advancedArgs = {replyTo:e.namedValues['E-mail'].toString()};
MailApp.sendEmail(email, subject, message, advancedArgs);
}
the script works,
but when it sends the email, data is not sorted as the fields of the form.
how can I modify my script to sort the values as they are in the Spreadsheet (form)?
You could get the columns order from the spreadsheet. Something like this:
function sendFormByEmail(e){
var email = "AAA";
var subject = "XXX";
var message = "";
var s = SpreadsheetApp.getActive().getSheetByName("Sheet1");
var headers = s.getRange(1,1,1,s.getLastColumn()).getValues()[0];
for(var i in headers)
message += headers[i] + ' = '+ e.namedValues[headers[i]].toString() + "\n\n";
var advancedArgs = {replyTo:e.namedValues['E-mail'].toString()};
MailApp.sendEmail(email, subject, message, advancedArgs);
}
Naturally, you have to change the sheet name Sheet1 to your actual sheet name.
By the way, I have written a script that does this a lot more, maybe you want to check it out (if this is not only a programming exercise). It's called FormEmailer and you can find it in the Script Gallery and in its site.
Related
I have this code to send Google Form responses to email.
function sendFormByEmail(e) {
Logger.log("e: " + e);
var email = "email#gmail.com";
var s = SpreadsheetApp.getActiveSheet();
var headers = s.getRange(1,1,1,s.getLastColumn()).getValues()[0];
var message = "";
var subject = "New Hire Form Submission: ";
for(var i in headers)
message += headers[i] + ': '+ e.namedValues[headers[i]].toString() + "\n\n";
// Insert variables from the spreadsheet into the subject.
// This creates an email subject like "New Hire: Jane Doe - starts 4/23/2013"
subject += e.namedValues[headers[2]].toString() + " - starts " + e.namedValues[headers[15]].toString();
// Send the email
MailApp.sendEmail(email, subject, message);
}
This is tied to the spreadsheet not the form and e is returning undefined. I saw someone else have this issue and disabling the new Chrome V8 worked for them but is not working for me.
trigger settings
By the time the function is called, the data is already in the spreadsheet, so you could just read the last now
var row = SpreadsheetApp.getActiveSheet().getLastRow();
var columns = s.getLastColumn()
var range = s.getRange(row, 1, 1, columns).getValues();
I am trying to send an automatic email to my students with feedback on the coursework. I have developed a google form with the marking scheme where I enter the student number, but the script doesn't read the named values method.
I have tried to do one by one student numbers and the rest of the code it works.
The code is as follows:
function sendNotification(e){
var s = SpreadsheetApp.getActiveSheet();
var message = "";
var headers =s.getRange(1,1,1,s.getLastColumn()).getValues()[0];
message += "This automated email includes the marks and feedback for
your Main report Assignment.\n\n";
var studentNumber = e.namedValues[headers[3]].toString();
Logger.log("column 3: " + studentNumber);
message += "Student Number: " + studentNumber + "\n\n";
var recipients = studentNumber + "#email.com";
var subject = "Test Email";
MailApp.sendEmail(recipients, subject, message);
}
I want to be able to gather the student email from the google form, that is already saved in column 3 of the spreadsheet that is attached to the form.
Sorry my answer is a little rushed as I am literally leaving. (As is my code.) Normally don't do this, but since you are a teacher willing to make an exception.
Hope the below code helps. (This is how I would accomplish the task you are trying to do.)
function helpingTheTeacher() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("YOUR_SHEET_NAME_HERE");
var values = sheet.getRange(2, 1, sheet.getLastRow(), sheet.getLastColumn()).getValues();
for (var i = 0; i < values.length; i++){
var timeStamp = values[i][0];
var studentName = values[i][1];
var studentNumber = values[i][2];
var studentGrade = values[i][3];
var message = "Hi " +studentName + " your grade is " +studentGrade + "."
var email = studentNumber + "#email.com";
var subject = "ALERT: MESSAGE FROM TEACHER!!!";
MailApp.sendEmail(email, subject, message)
}//END OF FOR LOOP
}//END OF FUNCTION
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;
My code sends email notifications every time a Google Form is submitted. It works, but I want the collected form data as bold in the email.
for(var i in headers)
message += headers[i] + ': '+ e.namedValues[headers[i]].toString() + "\n\n";
function sendFormByEmail(e)
{
var s = SpreadsheetApp.getActiveSheet();
var headers = s.getRange(1, 1, 1, s.getLastColumn()).getValues()[0];
var message = "";
var data = s.getRange(1, 1, 1, s.getLastColumn()).getValues()[0];
var subject = "";
//Get active Spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
//Get Sheet called 'Form responses 1'
var fr1 = ss.getSheetByName("Form responses 1");
//Get all emails from 'Emails' tab
var emails = ss.getSheetByName("Emails");
var numRows = emails.getLastRow();
var emailTo = emails.getRange(2, 2, numRows, 1).getValues();
// The variable e holds all the form values in an array.
// Loop through the array and append values to the body.
for(var i in headers)
message += headers[i] + ': '+ e.namedValues[headers[i]].toString() + "\n\n";
// Insert variables from the spreadsheet into the subject.
// In this case, I wanted the part number as part of the
// email subject. These are the 3rd and 16th columns in my form.
// This creates an email subject like "Parts Inquiry Submission: 729302"
subject += e.namedValues[headers[1]].toString();
// Send the email
MailApp.sendEmail(emailTo, subject, message);
// Based off of a script originally posted by Amit Agarwal - www.labnol.org
// Credit to Henrique Abreu for fixing the sort order
}
First of all, you must use the advanced parameter htmlBody in the 4th parameter of sendEmail() and you need to make the body parameter and empty string.
sendEmail(recipient, subject, body, options)
Code:
message = "<strong>" + message + "</strong>";//Wrap message in bold tags
var options = {
"htmlBody":message
}
// Send the email
MailApp.sendEmail(emailTo, subject, "",options);//Make email body empty string
Thank you all for your help. I ended up changing it up a bit. Here is what I ended up using.
function sendFormByEmail(e)
{
var message = "";
var subject = "";
var emailTo = "";
//Gets the active Spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
//Get Sheet called 'Form responses 1'
var fr1 = ss.getSheetByName("Form responses 1");
var headers = fr1.getRange(1,1,1,fr1.getLastColumn()).getValues()[0];
//Get all emails from 'Emails' tab
var emails = ss.getSheetByName("Emails");
var emailTo = emails.getRange(2, 2, emails.getLastRow()-1, 1).getValues().toString();
// For each column in the spreadsheet, add the column name and it's new entry as a line in the email
message = "<html>";
for(var i in headers)
message += headers[i] + ': <b>'+ e.namedValues[headers[i]].toString() + "</b><br><br>";
message += "</html>";
// Set the subject as the Item Number
subject = e.namedValues[headers[1]].toString();
// Send the email
MailApp.sendEmail({
to: emailTo,
subject: subject,
htmlBody: message
});
}
I'm trying to make a script to send an email every day , after checking in a spreadsheet, two conditions. If the first condition for True , the data to e- mail will be " subject1 ", otherwise, will be " subject2 ".
The script works correctly when I run manually , however, through the trigger, the value I would like to send via email, simply does not appear in the body.
I can not understand what could be wrong if manually , works perfectly .
The trigger is "time-driven/hour time/every 12 hours".
Can anyone help me?
This is the code:
function sendNotificationD() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var cell = ss.getActiveCell().getA1Notation();
var cellvalue = ss.getActiveCell().getValue().toString();
var column = ss.getRange('o13');
var cell = sheet.getRange('o13');
var value = column.getValue();
var emailSheet = ss.getSheetByName("totais");
var emails = emailSheet.getRange("q1:s1").getValues();
var range_bill_com = sheet.getRange('o13');
if (range_bill_com.getValue() !='CONGRATS'){
var recipients = emails;
var message = '';
var subject = 'subject1 here';
var body = 'IMPORTANT: ' + '\n\n' + 'your goal is' + ' ' + value;
MailApp.sendEmail(recipients, subject, body);
}
if (range_bill_com.getValue() =='CONGRATS'){
var recipients = emails;
var message = '';
var subject = 'subject2 here';
var body = 'you have reached your goal';
MailApp.sendEmail(recipients, subject, body);
}
};
At this line:
var sheet = ss.getActiveSheet();
The method getActiveSheet() gets the the active sheet that is being displayed in the spreadsheet UI when a user opens it, but when it runs from a time-driven trigger there is no active sheet, so you need to indicate the sheet, you can use getSheetByName() or getSheets() the line should look like this:
var sheet = ss.getSheetByName("Sheet1");
or
var sheet = ss.getSheets()[0]; // Index of the tab, 0 will return the first one
The function will still work if you fire it manually or from a trigger.