I have created a table in Google Sheets and I want to send automatically that table (25 rows, 2 columns) every 5 days to a specific email.
I already know how to send email via script, basically you use MailApp.sendEmail.
function sendFuelcount() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
sheet.setActiveSheet(sheet.getSheets()[0]);
var column1 = sheet.getRange("D2:D25").getValue();
var column2 = sheet.getRange("A2:A25").getValue();
var data = Utilities.formatDate(new Date(), "GMT", "dd-MMM-yyyy")
var msg = ""+nome+" "+fuel+"\n"
MailApp.sendEmail("abcd#gmail.com", ""+data+"", msg, {
name: 'Auto Message'});
This is the code so far, but unfortunately, it only writes the first row of the two columns instead of the 25 x 2 values.
In email I get:
Column11 Column12
What I want in email body is:
Column11 Column12
Column21 Column22
Column31 Column32
Column41 Column42
Column51 Column52
Until Column 25,1 and Column 25,2 or copy of the Google Sheet table.
Hope I have made myself clear.
Thank you.
EDIT: The answer below does the trick for export all values but not in a organized way.
What I get in the email is this:
A,B,C,D,...,i
1,2,3,4,...,j
What I want is this:
A - 1
B - 2
C - 3
D - 4
i - j
Is there a way to do this? Meaning how to organize and show that in the email. Like a table.
I manage to do this:
function sendFuelcount() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
sheet.setActiveSheet(sheet.getSheets()[0]);
var nom0 = sheet.getRange("A1").getValue();
var fue0 = sheet.getRange("D1").getValue();
var line0 = nome0 + "......" + fuel0;
var nom1 = sheet.getRange("A2").getValue();
var fue1 = sheet.getRange("D2").getValue();
var line1 = nome1 + "......" + fuel1;
var nome2 = sheet.getRange("A3").getValue();
var fuel2 = sheet.getRange("D3").getValue();
var line2 = nome2 + "......" + fuel2;
var nom3 = sheet.getRange("A4").getValue();
var fue3 = sheet.getRange("D4").getValue();
var line3 = nome3 + "......" + fuel3;
var nom4 = sheet.getRange("A5").getValue();
var fue4 = sheet.getRange("D5").getValue();
var line4 = nome4 + "......" + fuel4;
var nom5 = sheet.getRange("A6").getValue();
var fue5 = sheet.getRange("D6").getValue();
var line5 = nome5 + "......" + fuel5;
var data = Utilities.formatDate(new Date(), "GMT", "dd-MMM-yyyy") //define a data
var msg = ""+line0+"\n"+line1+"\n"+line2+"\n"+line3+"\n"+line4+"\n"+line5+" \n EMAIL GERADO AUTOMATICAMENTE"
MailApp.sendEmail("abcd#abcd.com", ""+data+"", msg, {
name: 'Auto Message'});
}
I manage to get this results:
Ba......(L)
eda......21
Alf......601
Arcs......95
Aamar......16
Canco......45
EMAIL GERADO AUTOMATICAMENTE
It's better but not what I want. What I want (or to create a table):
Ba.......(L)
eda......21
Alf......601
Arcs.....95
Aamar....16
Canco....45
EMAIL GERADO AUTOMATICAMENTE
This is what I want but the code I think is overly complicated, and I have to repeat that 25 times. I don't know how to properly use the For. But I think it can be useful here.
Thank you.
You will have to use getValues() instead of getValue()
Related
My fellow teachers and I like to send students little google drawings to let them know they've been doing well lately. We have a spreadsheet that we use and I am trying to automate the process of sending them an email when their drawing is ready to be viewed. I keep getting the 'Cannot read property 'getRange' of null error' even though I am 100% sure that a sheet exists with the name PR and that it is spelled right. I am new to Google Script so I lack the skills to troubleshoot any more than the googling I've done already, which basically just says to make sure you've named the sheet correctly. Any help would be very appreciated!
var studentFirstNameRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('PR').getRange("A2:A");
var studentFirstname = studentFirstNameRange.getValues();
var studentEmailRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('PR').getRange("D2:D");
var studentEmail = studentEmailRange.getValues();
var emailSendRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('PR').getRange("L2:L");
var emailSend = emailSendRange.getValues();
if (emailSend){
// Send Alert Email.
var message = 'Hi ' + studentFirstname + '! Your teachers noticed you have been doing a great job this year, so we made this for you! Keep up the great work!' ; // Second column
var subject = 'Positive Recognition';
MailApp.sendEmail(studentEmail, subject, message);
}
}```
According to the title and the error you related, I did'nt get any error.
However, I don't understand your condiiton if (emailSend) neither the way you send emails. If you send emails to all the population at once, you can try
function myFunction() {
var lastRow = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('PR').getLastRow()
var studentFirstNameRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('PR').getRange("A2:A"+lastRow);
var studentFirstname = studentFirstNameRange.getValues();
var studentEmailRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('PR').getRange("D2:D"+lastRow);
var studentEmail = studentEmailRange.getValues();
var emailSendRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('PR').getRange("L2:L"+lastRow);
var emailSend = emailSendRange.getValues();
if (emailSend){
// Send Alert Email.
var message = 'Hi ' + studentFirstname + '! Your teachers noticed you have been doing a great job this year, so we made this for you! Keep up the great work!' ; // Second column
var subject = 'Positive Recognition';
Logger.log(studentEmail.join())
MailApp.sendEmail(studentEmail.join(), subject, message);
}
console.log('there is no errors!')
}
if you want to send individually
function myFunction() {
var lastRow = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('PR').getLastRow()
var studentFirstNameRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('PR').getRange("A2:A" + lastRow);
var studentFirstname = studentFirstNameRange.getValues();
var studentEmailRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('PR').getRange("D2:D" + lastRow);
var studentEmail = studentEmailRange.getValues();
var emailSendRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('PR').getRange("L2:L" + lastRow);
var emailSend = emailSendRange.getValues();
for (var i = 0; i < studentFirstname.length; i++) {
if (emailSend[i][0]) {
// Send Alert Email.
var message = 'Hi ' + studentFirstname[i][0] + '! Your teachers noticed you have been doing a great job this year, so we made this for you! Keep up the great work!'; // Second column
var subject = 'Positive Recognition';
MailApp.sendEmail(studentEmail[i][0], subject, message);
}
}
}
I'm new to Google Apps script and am trying to add an image inline to an automated response email.
The auto reply works perfectly, the main text of the email formats well in plain text and html.
the problem i'm facing is that the image does not appear.
my code:
// This constant is written in column Y for rows for which an email
// has been sent successfully.
var EMAIL_SENT = 'EMAIL_SENT';
/**
* Sends non-duplicate emails with data from the current spreadsheet.
*/
function sendEmails2() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
SpreadsheetApp.setActiveSheet(sheet.getSheetByName('Data'))
var startRow = 2; // First row of data to process
// Fetch the range
var dataRange = sheet.getRange("L2:L1000")
var dataRange2 = sheet.getRange("K2:K1000")
var dataRange3 = sheet.getRange("O2:O1000")
var dataRange4 = sheet.getRange("Y2:Y1000")
var dataRange5 = sheet.getRange("B2:B1000")
// Fetch values for each row in the Range.
var data = dataRange.getValues();
var data2 = dataRange2.getValues();
var data3 = dataRange3.getValues();
var data4 = dataRange4.getValues();
var data5 = dataRange5.getValues();
for (var i = 0; i < data.length; ++i) {
var yesno = data2[i]
if(yesno == "Yes"){
var TFlogoUrl = "https://drive.google.com/openid=1nzmvP_zzOms1HiBoFCsVLFjDM6ZzM287";
var TFlogoBlob = UrlFetchApp
.fetch(TFlogoUrl)
.getBlob()
.setName("TFlogoBlob");
var emailAddress = data[i];
var ShipID = data3[i];
var cmdrID = data5[i];
var TFmsg = "Hi " + cmdrID + ",/n /nThank you for signing up to The Fatherhoods Lost Souls Expedition./n /nYour unique Ship ID is: " + ShipID + "/n /nWe look forward to seeing you on the expedition CMDR!/n /nFly Safe,/nThe Lost Souls Expedition team.";
var htmlTFmsg = "Hi " + cmdrID + ",<br> <br>Thank you for signing up to The Fatherhoods Lost Souls Expedition.<br> <br>Your unique Ship ID is: " + ShipID + "<br> <br>We look forward to seeing you on the expedition CMDR!<br> <br>Fly Safe,<br>The Lost Souls Expedition team.<br><img src='cid:TFlogo'>";
emailSent = data4[i]; // email sent (column Y)
if (emailSent != EMAIL_SENT) { // Prevents sending duplicates
var subject = "Lost Souls Expedition Sign up confirmation";
MailApp.sendEmail(emailAddress,subject,TFmsg,{
htmlBody: htmlTFmsg,
inlineImage:
{
TFlogo:TFlogoBlob
}
});
sheet.getRange("Y" + (startRow + i)).setValue(EMAIL_SENT);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}
}
How about this modification?
Modification points:
You cannot retrieve the file blob from this URL var TFlogoUrl = "https://drive.google.com/openid=1nzmvP_zzOms1HiBoFCsVLFjDM6ZzM287";. If you want to retrieve the file blob from URL, please use var TFlogoUrl = "http://drive.google.com/uc?export=view&id=1nzmvP_zzOms1HiBoFCsVLFjDM6ZzM287";. 1nzmvP_zzOms1HiBoFCsVLFjDM6ZzM287 is the file ID.
As an another method, from the file ID, it is found that the values of getSharingAccess() and getSharingPermission() are ANYONE_WITH_LINK and VIEW, respectively. So you can also retrieve the blob using var TFlogoBlob = DriveApp.getFileById("1nzmvP_zzOms1HiBoFCsVLFjDM6ZzM287").getBlob().setName("TFlogoBlob");. I recommend this.
When you want to use the inline image to email, please modify from inlineImage to inlineImages.
The script which reflected above points is as follows.
Modified script:
Please modify your script as follows.
From:
var TFlogoUrl = "https://drive.google.com/openid=1nzmvP_zzOms1HiBoFCsVLFjDM6ZzM287";
var TFlogoBlob = UrlFetchApp.fetch(TFlogoUrl).getBlob().setName("TFlogoBlob");
To:
var id = "1nzmvP_zzOms1HiBoFCsVLFjDM6ZzM287";
var TFlogoBlob = DriveApp.getFileById(id).getBlob().setName("TFlogoBlob");
And
From:
inlineImage: {TFlogo:TFlogoBlob}
To:
inlineImages: {TFlogo:TFlogoBlob}
References:
sendEmail(recipient, subject, body, options)
If I misunderstand your question, please tell me. I would like to modify it.
I'm looking for help to send an email whenever a new row is added by a google form entry if said entry contains an email in the Email column. I'm new to Javascript, but I've pieced together some code which I plan to run off an onEdit trigger in GSheets.
My problem is that if there is no email address, the code will fail. I need to know how to wrap this in an "if/else" or maybe just a simple error handling bit would be fine, not sure.
If I go with an "if/else", I'll need to check if the email column contains a value. I don't need to check if it is a valid email; the google form already does this on submission.
Here is the code I have right now:
function MessageNotification() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("Message Board"));
//
//extracts the values in last row and stores them into a two-dimensional
array called data
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow();
var dataRange = sheet.getRange(lastRow,3,1,8);
var data = dataRange.getValues();
//
//pull column elements into a one-dimensional array called rowData
for (i in data) {
var rowData = data[i];
var emailAddress = rowData[2];
var poster = rowData[7];
var subject = rowData[3];
var recipName = rowData[6];
var comment = rowData[4];
var replyLink = rowData[5];
//
//
var message = 'Dear ' + recipName + ',\n\n'+poster+' has posted the
following comment directed to you: '+'\n'+comment+'\n\n'+'To reply to this
comment click: '+replyLink;
var subject = subject;
MailApp.sendEmail(emailAddress, subject, message);
}
}
thanks in advance for any help you can give me.
Thank you tehhowch for the help. I'm new at this so I'll have to continue researching the link you referred to regarding iteration best practice. However I was able to get this working with a simple 'if' wrapper, which turned out to be simpler than I thought.
I did find out that form submission does not recognize an active sheet, so manually testing my code worked, while form submission did not trigger it.
After some looking, I replaced:
var ss = SpreadsheetApp.getActiveSpreadsheet();
with this:
var ssID = '//insert spreadsheet id here';
var ss = SpreadsheetApp.openById(ssID);
This still did not work, so I had to kickstart it by deleting the trigger and putting it back in (found this info: On form submit trigger not working)
This may not be the most efficient code, but here is what I have now, and it does work:
function MessageNotification() {
var ssID = '//insert spreadsheet id here';
var ss = SpreadsheetApp.openById(ssID);
ss.setActiveSheet(ss.getSheetByName("Message Board"));
//extracts the values in last row and stores them into a two-dimensional
array called data
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow();
var dataRange = sheet.getRange(lastRow,3,1,8);
var data = dataRange.getValues();
//
//pull column elements into a one-dimensional array called rowData
for (i in data) {
var rowData = data[i];
var emailAddress = rowData[2];
var poster = rowData[7];
var subject = rowData[3];
var recipName = rowData[6];
var comment = rowData[4];
var replyLink = rowData[5];
//
//
var message = 'Dear ' + recipName + ',\n\n'+poster+' has posted the
following comment directed to you: '+'\n'+comment+'\n\n'+'To reply to this
comment click: '+replyLink;
var subject = subject;
if(emailAddress)
{
MailApp.sendEmail(emailAddress, subject, message);}
}
}
As mentioned in the question comments, you want to use the event object available to the on form submit trigger. This can be accessed from a container-bound script on either the form or its responses spreadsheet, simply by adding a parameter to the function that receives the trigger.
This object is of the form:
e: {
authMode: <enum>,
namedValues: {
'q1title': [ <q1string> ],
'q2title': [ <q2string> ],
...
},
range: <Range>,
triggerUid: <string>,
values: [<q1string>, <q2string>, ...]
}
Using this object means that accessing of the Spreadsheet, for the purposes of emailing someone based on contents of the form, is unnecessary.
function MessageNotification(e) {
if(!e) return; // No form event object was provided.
var responses = e.namedValues;
var emailQTitle = /* the title of the question that asks for the email */;
// Check that 1) this question exists in the response object, and also
// 2) it has an answer with a value that 3) is "truthy".
// https://developer.mozilla.org/en-US/docs/Glossary/Truthy
if(responses[emailQTitle] // 1
&& responses[emailQTitle].length // 2
&& responses[emailQTitle][0]) // 3
{
var emailAddress = responses[emailQTitle][0];
/* access the responses variable in a similar manner
for the other variables needed to construct the email */
MailApp.sendEmail(emailAddress, ... );
} else {
/* There was no response to the email question. */
// You can use View->Stackdriver Logging to inspect the form response, for
// example, to make sure that it had the format or values you expected.
console.log({form_object: e, responses: responses, emailTitle: emailQTitle});
}
}
I feel like this should be so easy and obvious, but I cannot figure it out...
I am working with 2 forms and 2 spreadsheets. Form 1 submits to Sheet 1. On Sheet 1, for each record, there is a link that takes the user to Form 2, which is half pre-populated with data from Sheet 1. When the user submits Form 2, it populates Sheet 2.
I have a couple of scripts that are supposed to be triggered when Form 1 is submitted. I am using the "From Spreadsheet" "OnFormSubmit" trigger. The scripts, however, are also triggering when Form 2 is submitted.
How can I make it so the scripts only execute when Form 1 is submitted? Also, is there a way to ensure that scripts trigger in a specific order?
If it helps, the scripts are below. They all work properly as is, except for the triggering issue. I know that I can merge the 2nd and 3rd script, and I will, but I'd like to fix this triggering issue first, as I'm getting double the emails every time I test.
1st script:
function onFormSubmit(e) {
//Uses time in milleseconds to create unique ID #
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("ComplaintLog");
var d = new Date();
var n = d.getTime();
var lastRow = sheet.getLastRow();
var cell = sheet.getRange("BA" + lastRow);
cell.setValue(n);
var cell = sheet.getRange("BB" + lastRow);
cell.setFormula("=right(BA"+lastRow+",6)");
sheet.getRange("BB"+lastRow).copyTo(sheet.getRange("BC"+lastRow), +
{contentsOnly:true});
}
2nd script:
function formSubmitReply(e) {
//Sends email to certain users when a new complaint has been entered
var emailAddresses = 'person#organzation.com';
MailApp.sendEmail(emailAddresses,
"person#organzation.com",
"New Guest Complaint",
"A new guest complaint has been entered into the database."
+ "\n\n To vew the database, click here: http://goo.gl/DI33EC");
}
3rd script:
function createResolutionForm() {
var ss = SpreadsheetApp.getActive()
var sheet = ss.getSheetByName("ComplaintLog")
var lastRow = sheet.getLastRow();
var data = ss.getSheetByName("ComplaintLog") +
.getRange("A"+lastRow+":Z"+lastRow).getValues();
var form = FormApp.openById('The form's ID goes here. that part works.');
var items = form.getItems();
for (var i = 0; i < data.length; i++) {
var formResponse = form.createResponse();
//ID
var formItem = items[1].asTextItem();
var response = formItem.createResponse(data[i][0]);
formResponse.withItemResponse(response);
//Guest Name
var formItem = items[2].asTextItem();
var response = formItem.createResponse(data[i][3]);
formResponse.withItemResponse(response);
//email
var formItem = items[3].asTextItem();
var response = formItem.createResponse(data[i][4]);
formResponse.withItemResponse(response);
// The pre-populated form is being created here. I didn't include every
// form item for brevity's sake.
}
//Create Link
var formUrl = formResponse.toPrefilledUrl();
//Enable Clickable ID
var idNum = sheet.getRange("BC"+lastRow).getValues();
sheet.getRange("A"+lastRow).setFormula +
('=HYPERLINK("' + formUrl + '","' + idNum + '")');
var sheetUrl = "The URL to the spreadsheet goes here - that part works.";
//Send Email to assigned managers
var j,tempname=[],name, subject, managername, message;
managername = sheet.getRange("P"+lastRow).getValue();
tempname=managername.split(" ");
Logger.log(managername)
if (tempname.length==2) {
name=tempname[0].slice(0,1) + tempname[1] + '#organization.com';
subject = 'Action Required';
var message = "<html><body>"
+ "<p> You have been assigned to follow-up on a complaint,"
+ "or your contact information has been given to a customer in"
+ "regards to a complaint."
+ "<p><p>The complaint ID number is " + idNum +"."
+ "<p>To go directly to this complaint,"
+ "<b>click here</b>."
+ "<p>To vew the database so that you can take action,"
+click here."
+ "</body></html>";
MailApp.sendEmail(name, subject,"",{htmlBody : message});
}
}
Setting up the triggers from within the script might be what you're looking for. You can create triggers that respond to form submission events on a per-form basis like so:
function setup () {
ScriptApp.newTrigger('onForm1ResponseHandler').forForm(form1).onFormSubmit().create();
ScriptApp.newTrigger('onForm2ResponseHandler').forForm(form2).onFormSubmit().create();
}
where form1 and form2 are Form objects and 'onForm1ResponseHandler' is the name of the handler function.
With a handler function set up like this:
function onForm1ResponseHandler (e) {
...
}
e will be an object with properties documented here (for the Form Submit event).
I've created a form using google drive.
In order to provide to answerers a summary of what they wrote I would like to send an email to each of them, using the email they insert in the form.
I think it is possible to do this installing a script in the spreadsheet of the form result that send an email every time a new row is recorded.
I've found (on this forum) the following script that is, unfortunately, an email alert with a modify in a certain spreadsheet.
function sendNotification() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var cell = ss.getActiveCell().getA1Notation();
var row = sheet.getActiveRange().getRow();
var cellvalue = ss.getActiveCell().getValue().toString();
var recipients = "me#gmail.com";
var message = '';
if(cell.indexOf('G')!=-1){
message = sheet.getRange('D'+ sheet.getActiveCell().getRowIndex()).getValue()
}
var subject = 'Update to '+sheet.getName();
var body = sheet.getName() + ' has been updated. Visit ' + ss.getUrl() + ' to view the changes on row: «' + row + '». New comment: «' + cellvalue + '». For message: «' + message + '»';
MailApp.sendEmail(recipients, subject, body);
};
And here is the help I need. The script sends an email to a single predefined address. Is it possible to let the script take the recipient email from a certain cell in the relevant row (for example the email is recorded in the col C of the spreadsheet) and send him a message that contains some text taken by other cells of the same row ( for example col D and E)?
Using the variables you defined in your code (sheet, row):
//returns email address in column C
var recipient = sheet.getRange(row, 3).getValue();
//returns values in column D and E
var info1 = sheet.getRange(row, 4).getValue();
var info2 = sheet.getRange(row, 5).getValue();
Please be aware that this is an 'expensive' way to get the values and you would better served getting all values as an array in one call and then referencing them by index, as below.
//get all required values in one call
var values = sheet.getRange(row, 3, 1, 3).getValues();
//define variables using array index
var recipients = values[0];
var info1 = values[1];
var info2 = values[2];