AppScript is not sending Emails automatically - google-apps-script

Using below AppScript to sending an auto email based on Google Sheet values but its not working.
I have changed the Column reference according to the current columns but its not giving an error but also not sending the email.
can someone please look into this matter.
Your help will be greatly appreciated.
function Send_email() {
var INITIALline = 2;
var columnSEND = 5;
var STATUScolumn = 16;
var textCONDITION = "New Request";
var textSENT = "Mail_Sent"
var tab = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data");
var interval = tab.getRange(INITIALline,1,tab.getLastRow()-INITIALline+1,STATUScolumn);
var dice = interval.getValues();
var yousent = false;
var email,subject,message;
for (var i=0; i<dice.length; ++i) {
if((dice[i][columnSEND-1]==textCONDITION) && (dice[i][STATUScolumn-1]!=textSENT)){
var email = dice[i][9]
subject = dice[i][6]+" | YOUR CASE ID IS | "+dice[i][0];
var message = "<font size='3' face='Comfortaa'>Dear "+dice[i][6]+",<br/><br/>"+
"Thanks for connecting with us."+dice[i][0]+".<br/><br/>"+
"<i>Thanks & Regards</i><br/>"+
"<b>VNA SERVICE TEAM </b>";
MailApp.sendEmail(email, subject, message,{ htmlBody: message});
tab.getRange(INITIALline+i,STATUScolumn).setValue(textSENT);
yousent = true;
SpreadsheetApp.flush();
}
}
}

In your Spreadsheet, it seems that Your issue is the column "E". But columnSEND is 15 by var columnSEND = 15 of your script in your question. In this case, the if statement of if((dice[i][columnSEND-1]==textCONDITION) && (dice[i][STATUScolumn-1]!=textSENT)){ checks the column "O". I think that this is the reason of your issue.
So in order to check the column "E", as a simple modification, how about the following modification?
From:
var columnSEND = 15;
To:
var columnSEND = 5;

Related

Google App Script - automatically send out email when a new row

I'm trying to build a script that can automatically send email when a new row is updated. I only want to trigger the new updated rows and mark 'sent' after sending them out.
Here's the script that's currently working well. I can run it with a click:
function sendMail()
{
var name = 0;
var request = 1;
var id = 2;
var select = 3;
var time = 4;
var email = 5;
var status = 6;
var error = 7;
var emailTemp = HtmlService.createTemplateFromFile("email");
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Email list");
var data = ws.getRange("A2:I" + ws.getLastRow()).getValues();
data = data.filter(function(r){ return r[8] == true });
data.forEach(function(row)
{
emailTemp.fn = row[name];
emailTemp.req = row[request];
emailTemp.id = row[id];
emailTemp.erm = row[error];
emailTemp.ta = row[select];
emailTemp.time = row[time];
var htmlMessage = emailTemp.evaluate().getContent();
GmailApp.sendEmail(row[email],
"Failure message",
"Please submit again.",
{name: "My name", htmlBody: htmlMessage}
);
});
}
I have studied this query but I still have no idea how it works.
Please share some relevant source or some solution, thank you!
Although I'm not sure about mark 'sent' after sending them out., if "sent" is put to the column "J", from I assume it's filled in another column, like col8 or col 9. of your reply, I guessed that you wanted to put "sent" to the column "J" because the columns 8 and 9 (H and I) have already been used in your script. If my understanding is correct, how about the following modification?
Modified script:
Please copy and paste the following script to the script editor of Google Spreadsheet and save the script. And please install OnEdit trigger to the function sendMail. By this, when the cell is edited, the script is run.
function sendMail() {
var ws = SpreadsheetApp.getActiveSheet();
if (ws.getSheetName() != "Email list") return;
var name = 0;
var request = 1;
var id = 2;
var select = 3;
var time = 4;
var email = 5;
var status = 6;
var error = 7;
var emailTemp = {};
var emailTemp = HtmlService.createTemplateFromFile("email");
var data = ws.getRange("A2:J" + ws.getLastRow()).getValues();
var ranges = data.map(function (row, i) {
if (row[8] == true && row[9] != "sent") {
emailTemp.fn = row[name];
emailTemp.req = row[request];
emailTemp.id = row[id];
emailTemp.erm = row[error];
emailTemp.ta = row[select];
emailTemp.time = row[time];
var htmlMessage = emailTemp.evaluate().getContent();
GmailApp.sendEmail(row[email],
"Failure message",
"Please submit again.",
{ name: "My name", htmlBody: htmlMessage }
);
return "J" + (i + 2);
}
return "";
}).filter(String);
ws.getRangeList(ranges).setValue("sent");
}
In this case, when the active sheet is "Email list", the script is run. And, "sent" is put to the column "J".
Note:
I think that the event object of OnEdit can be used. But from your question, I thought that you might want to directly run the script with the script editor. So I didn't use the event object.
It seems that the columns 8 and 9 (H and I ) are used in your script like emailTemp.erm = row[error]; and data = data.filter(function(r){ return r[8] == true });. So I put "sent" to the column "J". Please be careful this.

How to add cc in Google Apps Script and onFormSubmit trigger

I am not sure how can I add a line for cc. Below is the script i have. Grateful if anyone can help. Thanks!
Meanwhile, I know there is a trigger called onFormSubmit trigger. May I know how can I send an email according to the specific answer coming in from a form?
For instance, in the Google form. I have question like Which colour do you like? Red or Yellow. If someone picked yellow, an email would be sent. However, I am not sure how to do that.
function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{
name : "Send Email",
functionName : "sendEmails"
}
];
sheet.addMenu("Let's do it", entries);
};
function hindex(header_row, value){
for (var j = 0; j < header_row.length; j++) {
if(value == header_row[j]) return j;
}
return 0;
}
function sendEmails() {
var htmlcode = String(SpreadsheetApp.getActiveSpreadsheet().getSheetByName("HTML").getRange(1, 1).getValue());
var replyTo = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sender").getRange(2, 2).getValue();
var name_shown = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sender").getRange(1, 2).getValue();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Receiver List");
var htmlsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Testhtml");
var startRow = 2; // First row of data to process
var LastRow = sheet.getLastRow(); // Number of rows to process
var dataRange = sheet.getRange(startRow, 1, LastRow-1, 50);
var data = dataRange.getValues();
for (var i = 1; i < data.length; i++) {
var row = data[i];
var name = row[0];
var emailAddress = row[1];
var subject = row[2];
var confirm = row[3];
var EmailSent = row[4];
var strings = data[0];
var obj = {};
var message = htmlcode;
for (var k = 0; k < strings.length; k++){
if(strings[k].length == 0)continue;
obj[strings[k]] = row[hindex(data[0],strings[k])];
var reg = new RegExp("\{\{"+strings[k]+"\}\}", "g");
//htmlsheet.getRange(k+1, 3).setValue(reg);
message = message.replace(reg,obj[strings[k]])
}
/*
var r1 = row[hindex(data[0],"r1")];
var r2 = row[hindex(data[0],"r2")];
var r3 = row[hindex(data[0],"r3")];
var r4 = row[hindex(data[0],"r4")];
var r5 = row[hindex(data[0],"r5")];
var r6 = row[hindex(data[0],"r6")];
var r7 = row[hindex(data[0],"r7")];
var r8 = row[hindex(data[0],"r8")];
var r9 = row[hindex(data[0],"r9")];
var r10 = row[hindex(data[0],"r10")];
var r11 = row[hindex(data[0],"r11")];
var r12 = row[hindex(data[0],"r12")];
var r13 = row[hindex(data[0],"r13")];
var q1 = row[hindex(data[0],"q1")];
var r14 = row[hindex(data[0],"r14")];
var q2 = row[hindex(data[0],"q2")];
var q3 = row[hindex(data[0],"q3")];
var q4 = row[hindex(data[0],"q4")];
var q5 = row[hindex(data[0],"q5")];
var r15 = row[hindex(data[0],"r15")];
var q6 = row[hindex(data[0],"q6")];
var r16 = row[hindex(data[0],"r16")];
var q7 = row[hindex(data[0],"q7")];
message = htmlcode.replace(/\{\{r1\}\}/,r1)
.replace(/\{\{r2\}\}/,r2)
.replace(/\{\{r3\}\}/,r3)
.replace(/\{\{r4\}\}/,r4)
.replace(/\{\{r5\}\}/,r5)
.replace(/\{\{r6\}\}/,r6)
.replace(/\{\{r7\}\}/,r7)
.replace(/\{\{r8\}\}/,r8)
.replace(/\{\{r9\}\}/,r9)
.replace(/\{\{r10\}\}/,r10)
.replace(/\{\{r11\}\}/,r11)
.replace(/\{\{r12\}\}/,r12)
.replace(/\{\{r13\}\}/,r13)
.replace(/\{\{r14\}\}/,r14)
.replace(/\{\{r15\}\}/,r15)
.replace(/\{\{r16\}\}/,r16)
.replace(/\{\{q1\}\}/,q1)
.replace(/\{\{q2\}\}/,q2)
.replace(/\{\{q3\}\}/,q3)
.replace(/\{\{q4\}\}/,q4)
.replace(/\{\{q5\}\}/,q5)
.replace(/\{\{q6\}\}/,q6)
.replace(/\{\{q7\}\}/,q7)
.replace(/\{\{name\}\}/,name);
*/
htmlsheet.getRange(1, 1).setValue(message);
htmlsheet.getRange(1, 2).setValue(JSON.stringify(obj));
if (confirm == "Yes" && EmailSent != "Email Sent") {
MailApp.sendEmail(emailAddress,subject, "", {
htmlBody: message,
replyTo: replyTo,
name: name_shown
});
sheet.getRange(startRow + i, 5).setValue("Email Sent");
}
}
}
Add cc:
The cc is an advanced parameter at sendEmail(recipient, subject, body, options), like htmlBody or replyTo. Therefore, when using sendEmail, you should add it this way:
MailApp.sendEmail(emailAddress,subject, "", {
htmlBody: message,
replyTo: replyTo,
name: name_shown,
cc: "YOUR_DESIRED_CC_EMAIL"
});
Use onFormSubmit:
There are two types of onFormSubmit triggers, one for the spreadsheet linked to the Form and the other for the Form itself. Depending on which one you install (see Installable Triggers for more information on how to install a trigger), you'd retrieve the value of a response in different ways, using the corresponding event object.
It's probably easier to get this information via the Sheets event object, so I'd suggest you to use the Sheets trigger. In this case, the event object has a field namedValues, which refers to an object containing the question names and values from the form submission. In the function triggered by the form submission, just find the key that corresponds to the item you want to fetch the response from, and retrieve its value. For example:
function triggeredByFormSubmit(e) {
const submittedColor = e.namedValues["Which colour do you like?"];
// ...
}
If you installed a Form's onFormSubmit instead, you should find the item response via the event property response, which corresponds to the FormResponse.
Note: Please note that this is supposed to run automatically when a user submits a form. If you try to execute it directly from the editor, or from the custom menu, it will fail because the event object (in the sample above, e) won't be defined.

"Email_Sent" message not updating to the spreadsheet as it should

I'm having trouble with the "Email _Sent" text. It is supposed to appear next to the recipient who received the email from my spreadsheet. However, when I select certain emails to send the message to, the text "Email _Sent" starts filling out the first empty rows in my spreadsheet. In this way, the text appears beside some recipients who didn't receive the message.
I'll post the script that I'm using:
function sendGeneralEmail() {
var Email = 4;
var Name = 3;
var emailSent = 6;
var subject = "Sample Analysis Service"
var html = HtmlService.createTemplateFromFile("SUM.1");
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Test");
var data = ws.getRange("A5:G" + ws.getLastRow()).getValues();
data = data.filter(function(r){ return r[5] == true});
var Email_Sent = 'Email_Sent';
var sheet = SpreadsheetApp.getActiveSheet();
var notBlank = sheet.getRange("D5:G5");
var lastRow = notBlank.getLastRow();
data.forEach(function(row){
html.en = row[Name];
var htmlMessage = html.evaluate().getContent();
if(emailSent !=Email_Sent) {
GmailApp.sendEmail(
row[Email],
subject, "Your Email doesn't support HTML", {
name: "MASAR Team",
htmlBody: htmlMessage},
);
sheet.getRange(lastRow, 7, data.length, 1).setValue(Email_Sent);
SpreadsheetApp.flush();
}
});
}
Can someone help me to fix that?
The second issue is that, if I run the script and then stopped and came back and run it again on the same day, the text "Email_sent" stops updating to the spreadsheet. It only appears the first I run the script during the day.
Screenshot
Hope to have a solution to this
I tried to replicate your code and found some issues:
using setValue on range with multiple cells will copy the value to all cells within the range. In your example, all cells in getRange(lastRow, 7, data.length, 1) will have the value "Email_Sent". This causes the unwanted write of "Email_Sent" in your spreadsheet.
if(emailSent !=Email_Sent) will always true because '6' is not always equal to 'Email_Sent'
Based on your example, your goal is to send an email and write "Email_Sent" to the Email Status column of the recipient.
Here, I fixed some part of your code and added features.
Code:
function sendGeneralEmail() {
var subject = "Sample Analysis Service"
// var html = HtmlService.createTemplateFromFile("SUM.1");
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Test");
var data = ws.getRange("A5:G" + ws.getLastRow()).getValues();
var sheet = SpreadsheetApp.getActiveSheet();
for(var i=0; i<data.length; i++){
var selected = data[i][5];
var emailStatus = data[i][6];
if(selected && emailStatus != "Email_Sent"){
var email = data[i][4];
// html.en = row[Name];
// var htmlMessage = html.evaluate().getContent();
GmailApp.sendEmail(
email,
subject, "Your Email doesn't support HTML", {
name: "MASAR Team",
message: "ABCD",
// htmlBody: htmlMessage},
}
);
sheet.getRange(i+5, 7, 1, 1).setValue("Email_Sent");
}
}
}
Note: I commented the html parsing since I don't have the sample html and replaced the email message with a string.
Before running the script:
After running the script:
Reference:
setValue()

Send mail based on Google Sheet Cell value

I am trying to send auto generated mail based on text value of Google sheet.
In My Sheet column, F is the row with the status " Approved' Or "Rejected"
If Status is " Approved' mail should generate
I have created the code, however, i think need small modifications
function myNotification() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var ss_sheet = ss.getSheetByName('Form Responses 1')
var ss_sheet_datarange = ss.getDataRange().getValues();
var ss_sheet_lastrow = ss_sheet.getLastRow()
for (var i = 5; i < ss_sheet_lastrow; i++)
var approvalstatus = ss_sheet_datarange[5][i] // column F is the row with the status in
var approval_status = 5;
if (approval_status == 'Approved') {
var email = Session.getUser().getEmail();
MailApp.sendEmail(email, "Test", "Test");
}
Change
if (approval_status == 'Approved') {
For
if (approvalstatus == 'Approved') {
You have two variables very similar, but in your code, approval_status will ALWAYS be 5

How can I keep the leading zero's in my pdf generated documents from google spreadsheet?

I have created a google test form and test form response. In the response spreadsheet, I have written below script to capture the inputted values from the from > generate a pdf/doc > email the pdf & > save a copy of the doc in a target folder. The issue I'm running into is that the section labeled as passcode could start with a "0" or multiple "0's", which I have formatted in the script for the spreadsheet. However when it generates the PDF/DOC, the zero's are removed. Is there any way to keep the leading 0's when converted in the PDF/DOC?
function formatNumber(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var cell = sheet.getRange("D2:D");
// Always show 4 digits
cell.setNumberFormat("0000");
}
var docTemplate = "11laarf0ThJ4mANX4KzHZCblVwRgphlf-bCblaUMl4oc";
var docName = "Test Form";
function onFormSubmit(e) {
var email_address = "jimmy111#gmail.com";
var Time_Stamp = e.namedValues["Timestamp"];
var full_name = e.namedValues["Name"];
var phone = e.namedValues["Phone Number"];
var passcode = e.namedValues["Passcode"];
var price = e.namedValues["Price"];
var copyId = DocsList.getFileById(docTemplate)
.makeCopy(full_name+' '+docName)
.getId();
var copyDoc = DocumentApp.openById(copyId);
var copyBody = copyDoc.getActiveSection();
copyBody.replaceText('keyDate', Time_Stamp);
copyBody.replaceText('keyName', full_name);
copyBody.replaceText('keyPhone', phone);
copyBody.replaceText('keyCode', passcode);
copyBody.replaceText('keyPrice', price);
copyDoc.saveAndClose();
var pdf = DocsList.getFileById(copyId).getAs("application/pdf");
var subject = "CIR Testform for "+ full_name + "";
var body = "Here is the registration form for "+ full_name +"";
MailApp.sendEmail(email_address, subject, body, {htmlBody: body, attachments: pdf});
var targetFolder = DocsList.getFolderById('0B-LfisIjjXtvLW82X3o1UzNyY1U');
var file = DocsList.getFileById(copyId);
file.addToFolder(targetFolder);
file.removeFromFolder(DocsList.getRootFolder());
}
function assignEditUrls() {
var form = FormApp.openById('16zVePLm61yRsSZMaoDI5MWIeB-vGHZGEoR9J7uJ0CP8');
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Form Responses 1');
var data = sheet.getDataRange().getValues();
var urlCol = 6; // column number where URL's should be populated; A = 1, B = 2 etc
var responses = form.getResponses();
var timestamps = [], urls = [], resultUrls = [];
for (var i = 0; i < responses.length; i++) {
timestamps.push(responses[i].getTimestamp().setMilliseconds(0));
urls.push(responses[i].getEditResponseUrl());
}
for (var j = 1; j < data.length; j++) {
resultUrls.push([data[j][0]?urls[timestamps.indexOf(data[j] [0].setMilliseconds(0))]:'']);
}
sheet.getRange(2, urlCol, resultUrls.length).setValues(resultUrls);
}
I've got a workaround to this issue, it's less than ideal but it's working.
Using the Pre-Filled form feature, enter a period in each response that requires the leading zero.
So if your user had entered "0123456", the recorded response will appear as "0.123456" you can then use substring to remove the first two charecters.
e.g.
var phone = e.namedValues["Phone Number"].substring(2);
This will then give you the leading zero. The only issue is accidental deletion of the period from the pre-filled form, although you can set a validation which checks for it, and then an error asking the user to enter it if they've removed it.
Not pretty, but we're up and running with that now at least.