Is there a way to make the output of 'message' in the email neater?
Right now, it's just 1 line of long data sent to the user. I tried using <br> but it didnt seem to work.
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getDataRange();
var data = range.getValues();
setUpCalendar_(data, range);
var message = "";
for (i in data) {
var row = data[i];
var subject = "Compiled List for " + row[0];
message += row[0] + row[1] + row[2] + row[3];
}
MailApp.sendEmail("emailgoeshere", subject, message);
}
As mentioned in the comment above, this has already been explained a few times...
below is an example that sends data in text format AND in html format so that recipients that reject html content will still see something readable ;-)
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getDataRange();
var data = range.getValues();
setUpCalendar_(data, range);
var txt = "";
var html = '<table style="background-color:lightblue;border-collapse:collapse;" border = 1 cellpadding = 5><tr>'
for (i in data) {
var row = data[i];
var subject = "Compiled List for " + row[0];
txt += row[0] +' - '+ row[1] +' - '+ row[2] +' - '+ row[3]+'\n';
html+= '<td>'+row[0] +'</td><td>'+ row[1] +'</td><td>'+ row[2] +'</td><td>'+ row[3] +'</td></tr><tr>';
}
html += '</tr></table>';
MailApp.sendEmail('an email adress', subject, txt,{'htmlBody':html});
}
Change the background color to your taste
Try using \n to start a new line
Related
I have a form that contains 84 questions, not all of them are mandatory.
This is the script I manage to write so far:
function SendEmail() {
var ActiveSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var StartRow = 2;
var RowRange = ActiveSheet.getLastRow() - StartRow + 1;
var WholeRange = ActiveSheet.getRange(StartRow,1,RowRange,84);
var AllValues = WholeRange.getValues();
var message = "";
for (i in AllValues) {
var CurrentRow = AllValues[i];
var EmailSent = CurrentRow[85];
if (EmailSent == "Sent")
continue;
# I know this part takes only the first 5 column, I wrote them only as an example. In bold the headers of each column.
message =
"<p><b>Kind of content: </b>" + CurrentRow[2] + "</p>" +
"<p><b>Project Name: </b>" + CurrentRow[3] + "</p>" +
"<p><b>Project Description: </b>" + CurrentRow[4] + "</p>" +
"<p><b>Name of your team: </b>" + CurrentRow[5] + "</p>" +
"<p><b>Scope of work: </b>" + CurrentRow[6] + "</p>";
var setRow = parseInt(i) + StartRow;
ActiveSheet.getRange(setRow, 85).setValue("sent");
}
var SendTo = "email#gmail.com";
var Subject = "New"+" " + CurrentRow[2] +" "+"project request";
MailApp.sendEmail({
to: SendTo,
cc: "",
subject: Subject,
htmlBody: message,
});
}
What I want is to send an email every time somebody fills the form and the content of the email should include only the last row and only the columns with data with their header.
The way this script is written will generate an email with 84 rows, most of them empty and not relevant. Can somebody give me a hand with it?
Thank you so much for your help!!
You can use sheet.getLastRow() to get the index of the last row in the sheet that has data.
For finding columns that have data, you can iterate through the row data and look for cell values that are not blank.
var header = sheet
.getRange(1,1,1,sheet.getLastColumn())
.getDisplayValues()[0];
var data = sheet
.getRange(sheet.getLastRow(),1,1,sheet.getLastColumn())
.getDisplayValues()[0];
var output = [];
for (var d=0; d<data.length; d++) {
if (data[d] !== "") {
output.push(header[d] + " = " + data[d]);
}
}
return data.join("\n");
I know you are too naive to coding and Amit is a busy person, so just to help you, I am plugging in the code he has provided to your code with a small correction, so you can just copy the entire code :)
function SendEmail() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var lRow = sheet.getLastRow();
var emailSent = sheet.getRange(lRow, 86).getValue();
var header = sheet
.getRange(1,1,1,sheet.getLastColumn())
.getDisplayValues()[0];
if (emailSent != "Sent"){
var data = sheet
.getRange(lRow,1,1,sheet.getLastColumn())
.getDisplayValues()[0];
var output = [];
for (var d=0; d<data.length; d++) {
if (data[d] !== "") {
output.push(header[d] + " = " + data[d]);
}
}
var message = output.join("\n");
var SendTo = "email#gmail.com";
var Subject = "New"+" " + sheet.getRange(lRow, 3).getValue() +" "+"project request";
MailApp.sendEmail({
to: SendTo,
cc: "",
subject: Subject,
htmlBody: message,
});
sheet.getRange(lRow, 86).setValue("sent");
}
}
You can use filter, for example
var AllValues = WholeRange.getValues().filter( row => row[5] != '');
will reduce AllValues to only those there column 6 isn't empty
can you please tell me, how to change code to run script only on specified sheet? I want to send e-mails if some value in 2nd column of specified sheet will change. Currently it is sending e-mails if I change 2nd column in any sheet.
I have tried code below, but didn't work:
var sheet = SpreadsheetApp.getActiveSpreadsheet();
SpreadsheetApp.setActiveSheet(sheet.getSheetByName('sheetname'))
This is code I have:
function sendNotification() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var mycell = ss.getActiveSelection();
var cellcol = mycell.getColumn();
var row = sheet.getActiveRange().getRow();
var cellvalue = mycell.getValue().toString();
var recipients = "email#email.com";
if (cellcol == 2)
{
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 + '»';
MailApp.sendEmail(recipients, subject, body);
}
}
Thank you.
So I have this google script function that reads information from a google spreadsheet and sends an email with the data. I set up a time-based trigger that activates every day at a certain hour but the problem is that every time it triggers the script ask for authorization so basically what I'm receiving is the email with this "time-based" error that asks for authorization.
The function self-works perfectly when I manually execute it and confirm the authorization myself.
I set up the time-based trigger via code and the trigger option of the scripts but none of them seems to work.
Do you guys know a way to always keep the authorization on so the trigger can work and send the email with the data?
so to add some additional information here, this is the code I'm using right now:
The spreadsheet is shared between two people, me and a co-worker.
If I manually execute this script, it will ask for authorization and then send to my email the data I need. My problem comes when I tried to set up a trigger to automatically execute this script. Every time the trigger execute the script I get an email saying that it needs authorization.
Function: emailCarts
Error Message: Authorization is required to perform this action. Activation: Time-Based
function emailCharts(sheet,emails,emailSubject){
var ss = SpreadsheetApp.openById("SPREADSHEET_ID");
var sheet = SpreadsheetApp.openById("SPREADSHEET_ID").getSheetByName("Graficos");
var emailSubject = 'Reporte Automático Reclamos y Sugerencias ' + Utilities.formatDate(sheet.getRange("B2").getValue(),ss.getSpreadsheetTimeZone(),"dd/MM/yy");
var emails = 'MY_EMAIL'; // your email ID
var charts = sheet.getCharts();
var sheet2 = SpreadsheetApp.openById("SPREADSHEET_ID").getSheetByName("Tabla");
var schedRange = sheet2.getDataRange();
var body = '<div style="text-align:left;display: inline-block;font-family:
arial,sans,sans-serif">'
body += '<H1>'+ 'Reclamos Abiertos ' +'</H1>';
body += getHtmlTable(schedRange);
body += '</div><br>';
debugger;
if(charts.length==0){
MailApp.sendEmail({to: emails,subject: "ERROR:"+emailSubject,htmlBody: "No hay
gráficos en el spreadsheet"});
return;
}
var chartBlobs = new Array(charts.length);
var emailBody = "Estimados,<br><br> Junto con saludar, se hace envío del reporte
automático de los Reclamos/Sugerencias/Felicitaciones Abiertos y Cerrados,
correspondiente a la fecha: "
+ Utilities.formatDate(sheet.getRange("B2").getValue(),ss.getSpreadsheetTimeZone(),"dd/MM/yy");
var emailImages = {};
for(var i=0;i<charts.length;i++){
var builder = charts[i].modify();
builder.setOption('vAxis.format', '#');
var newchart = builder.build();
chartBlobs[i] = newchart.getAs('image/png');
emailBody = emailBody + "<p align='center'><img src='cid:chart"+i+"'></p>";
emailImages["chart"+i]= chartBlobs[i];
}
for (var i = 0; i < emails.length; i++){
MailApp.sendEmail({to: emails[i], subject: emailSubject, htmlBody: emailBody+body, inlineImages: emailImages});
}
}
function getHtmlTable(range){
var ss = range.getSheet().getParent();
var sheet = range.getSheet();
startRow = range.getRow();
startCol = range.getColumn();
lastRow = range.getLastRow();
lastCol = range.getLastColumn();
// Read table contents
var data = range.getValues();
// Get css style attributes from range
var fontColors = range.getFontColors();
var backgrounds = range.getBackgrounds();
var fontFamilies = range.getFontFamilies();
var fontSizes = range.getFontSizes();
var fontLines = range.getFontLines();
var fontWeights = range.getFontWeights();
var horizontalAlignments = range.getHorizontalAlignments();
var verticalAlignments = range.getVerticalAlignments();
// Get column widths in pixels
var colWidths = [];
for (var col=startCol; col<=lastCol; col++) {
colWidths.push(sheet.getColumnWidth(col));
}
// Get Row heights in pixels
var rowHeights = [];
for (var row=startRow; row<=lastRow; row++) {
rowHeights.push(sheet.getRowHeight(row));
}
// Future consideration...
var numberFormats = range.getNumberFormats();
// Build HTML Table, with inline styling for each cell
var tableFormat = 'style="border:1.5px solid black;border-collapse:collapse;text- align:center" border = 1.5 cellpadding = 5';
var html = ['<table '+tableFormat+'>'];
// Column widths appear outside of table rows
for (col=0;col<colWidths.length;col++) {
html.push('<col width="'+colWidths[col]+'">')
}
// Populate rows
for (row=0;row<data.length;row++) {
html.push('<tr height="'+rowHeights[row]+'">');
for (col=0;col<data[row].length;col++) {
// Get formatted data
var cellText = data[row][col];
if (cellText instanceof Date) {
cellText = Utilities.formatDate(
cellText,
ss.getSpreadsheetTimeZone(),
"dd/MM/yy");
}
var style = 'style="'
+ 'color: ' + fontColors[row][col]+'; '
+ 'font-family: ' + fontFamilies[row][col]+'; '
+ 'font-size: ' + fontSizes[row][col]+'; '
+ 'font-weight: ' + fontWeights[row][col]+'; '
+ 'background-color: ' + backgrounds[row][col]+'; '
+ 'text-align: ' + horizontalAlignments[row][col]+'; '
+ 'vertical-align: ' + verticalAlignments[row][col]+'; '
+'"';
html.push('<td ' + style + '>'
+cellText
+'</td>');
}
html.push('</tr>');
}
html.push('</table>');
return html.join('');
}
I made a small script to send text via email from a spreadsheet.
I got the text of the cells using .getValue() but when my cells have two or more lines (Ctrl+enter) it just put them on the same line in the table I'm sending in the email.
I'd like to know if there is a way to keep the GoogheSheet formatting when extracting it with .getValue() or if I need to reprocess the string, and if so, how do I make any RE detect the new line...?
Here is the coding I used to extract the cells:
function readInList(debR, col){
/* Documentation
La routine lit chaque cellule d'un range de 1 col par 5 row et stock les valeurs dans une liste au format texte.
retourne cette liste
*/
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var stopRow = debR + 5;
var opCol = col;
var rangeList = [];
var i;
for (i=debR; i < stopRow; i++){
var cell = sheet.getRange(i, col);
rangeList.push(cell.getValue());
}
return (rangeList);
}
So the Mail sends a reconstructed table with the text, and all of this is inseted inside a html Mail:
function weeklyReport() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var rowMonth = [31,28,31,30,31,30,31,30,31,30,31,30];
var today = new Date();
var todayYear = today.getYear();
var todayMonth = today.getMonth();
var todayDate = today.getDate();
// Calc the number of rows depending of months that have passed
var rowCell=0;
var i = 0;
do {
rowCell+=rowMonth[i];
i++;
} while (i < todayMonth);
rowCell+=3 + todayDate
var range1 = readInListD(rowCell-4, 1);
var range2 = readInList(rowCell-4, 4);
var subject = 'Weekly report Clem Michard';
var greetings = 'Hi, ';
var sentence = 'please find my weekly report below:';
var table = textToTable(range1, range2);
var signature = 'Clem';
var tables = today;
var cmEmail= '***';
var owaEmail = '***';
var headEmail = '***';
var htmlBodyA =
"<html>"+
"<head>"+
"<style>"+
"table, th, td {"+
"border: 1px solid black;"+
"border-collapse: collapse;"+
"}"+
"</style>" +
"</head>"+
"<body>"+
"<p>" + greetings + "</p>"+
"<p>" + sentence + "</p>"+
"<pre>" + table + "</pre>"+
"<p>" + signature + "</p>"+
"</body>"+
"</html>";
/*- Message envoyé aux particpants avec un e-mail valide -*/
MailApp.sendEmail({
to: headEmail,
bcc: cmEmail,
subject: subject,
name: "Clément Michard",
replyTo: cmEmail,
htmlBody: htmlBodyA})
}
And use this to compose the table:
function textToTable(col1, col2){
/*
This method converts a list of str into an HTML table
takes 2 lists to build a table.
*/
var listC1, listC2, text, lLen, i, j;
listC1 = col1;
listC2 = col2;
lLen = listC1.length;
text = "<table><tr><th>" + "Date" + "</th><th>" + "Report" + "</th></tr>";
for (i = 0; i < lLen; i++){
text += "<tr><td>" + listC1[i] + "</td><td>" + listC2[i] + "</td></tr>";
}
text += "</table>";
return(text);
}
I wrote this JS to send email automatically using Google Script into a spreadsheet.
Unfortunately, the duplicate check is not working, and the bcc line trigger an error.
Actually I want to send an email only for the LAST answer into the spreadsheet everytime.
Could you help me?
var EMAIL_SENT = "EMAIL_SENT";
function sendEmails2() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2;
var numRows = active;
var dataRange = sheet.getRange(startRow, 1, numRows, 14)
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var name = row[2];
var surname = row[3];
var salesRepEmail = row[4];
var qualityAnalystEmail = "john#doe.com"
var customerEmail = row[5];
var websiteURL = row[6];
var solution1 = row[7];
var solution2 = row[8];
var solution3 = row[9];
var toResolve1 = row[10];
var toResolve2 = row[11];
var toResolve3 = row[12];
var checkDate = row[13];
var message = 'Bonjour '+ name + ' ' + surname + ', ' + 'blablabla';
var emailSent = row[14]; // Third column
if (emailSent != EMAIL_SENT) { // Prevents sending duplicates
var subject = "Votre Optimisation De Site Mobile pour " +websiteURL;
MailApp.sendEmail(customerEmail, subject, message, {
cc: "",
bcc: qualityAnalystEmail,+ " " + salesRepEmail,
});
sheet.getRange(startRow + i, 15).setValue(EMAIL_SENT);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}
Your code is triggering on bcc line cause you put a extra comma. As seen on the documentation, the bcc parameters should be a string with
a comma-separated list of email addresses to BCC
In your cas, you should'nt have:
bcc: qualityAnalystEmail,+ " " + salesRepEmail
but:
bcc: qualityAnalystEmail + ", " + salesRepEmail
which gives:
MailApp.sendEmail(customerEmail, subject, message, {
cc: "",
bcc: qualityAnalystEmail+ ", " + salesRepEmail
});
(You also put a extra comma after your bcc parameters which is not good)
Thank you so much , Please find below the datas and the script.
I will try to call the variables into the HTML afterwards using Google Scriptlet. For the moment, the simple text is sufficient. It seems to be working like that, but the code is not clean.
Image Du Tableau
// This constant is written in column O for rows for which an email
// has been sent successfully.
var EMAIL_SENT = "EMAIL_SENT";
function testSchemas() { {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = sheet.getLastRow();
var numRows = 1; // Number of rows to process
var dataRange = sheet.getRange(startRow, 1, numRows, 15)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var name = row[2];
var surname = row[3];
var salesRepEmail = row[4];
var qualityAnalystEmail = "xxx#yyy.com"
var customerEmail = row[5];
var websiteURL = row[6];
var solution1 = row[7];
var solution2 = row[8];
var solution3 = row[9];
var toResolve1 = row[10];
var toResolve2 = row[11];
var toResolve3 = row[12];
var checkDate = row[13];
function doGet() {
return HtmlService
.createTemplateFromFile('Index')
.evaluate();
}
Logger.log(doGet);
var htmlBody = HtmlService.createHtmlOutputFromFile('Index').getContent();
var message = 'Bonjour '+ name + ' ' + surname + ', ' + 'c\'est avec grand plaisir que je vous écris pour résumer ... - '+solution1+' \n\n- '+solution2+' \n\n- '+solution3+' \n\nMalgré...';
var emailSent = row[14]; // Third column
if (emailSent != "EMAIL_SENT") { // Prevents sending duplicates
/*MailApp.sendEmail(customerEmail, subject, message, {
cc: "",
bcc: qualityAnalystEmail + ", " + salesRepEmail
}); */
MailApp.sendEmail({
to: customerEmail,
bcc: qualityAnalystEmail + ", " + salesRepEmail,
subject: 'Résumé De Notre Consultation Du Site Mobile ' + websiteURL,
htmlBody: htmlBody,
});
}
Logger.log(name);
sheet.getRange(startRow + i, 15).setValue(EMAIL_SENT);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}