how to getRange of more than one cell in same row in a script - javascript

Im trying to make a script that sends email alert when specific fields reaches certain values. It works fine for one field, but how Do I do it so it sends alert when any of the fields in specific row range reaches that value.
Im using this code:
function CheckSales() {
// Tikrinam laukelio value
var monthSalesRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("reportai").getRange("A15");
var monthSales = monthSalesRange.getValue();
// tikrinam value
if (monthSales < 200){
// pasiimam email adresa
var emailRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getRange("B2");
var emailAddress = emailRange.getValue();
// Siuncima email.
var message = 'Mazas likutis: ' + monthSales; // Second column
var subject = 'Mazas Likutis';
MailApp.sendEmail(emailAddress, subject, message);
}
}
I tried using .getRange("A15:E15") but still it send alert only when A15 reaches value less than 200, its not reacting to B15, C15 ect.

You need to iterate the values in A15:E15 with a loop. Try this:
function checkSales() {
const monthSalesRange = SpreadsheetApp.getActive().getRange('reportai!A15:E15');
const emailAddress = SpreadsheetApp.getActive().getRange('Sheet1!B2').getValue();
const subject = 'Mazas Likutis';
let message = 'Mazas likutis: ';
const alerts = [];
monthSalesRange.getValues().flat()
.forEach(sales => {
if (Number(sales) && sales < 200) {
alerts.push(sales);
}
});
if (alerts.length) {
MailApp.sendEmail(emailAddress, subject, message + alerts.join(', '));
}
}
Some of the best resources for learning Google Apps Script include the Beginner's Guide, the New Apps Script Editor guide, the Fundamentals of Apps Script with Google Sheets codelab, the Extending Google Sheets page, javascript.info, Mozilla Developer Network and Apps Script at Stack Overflow.

Related

Google Sheets Form Response Conditional Responses

I'm relatively new to coding, especially in Javascript. I'm working on a google form that links to a google sheet and I want a conditional notification that when they answer a certain response it will notify that departments manager via email.
Essentially, I need my script to search for the value of a cell that contains the email to send.
I'm using a VLOOKUP chart to automatically input the email of that department based on the the department question they answer.
Additionally I need a way to trigger this function to run when a new response is entered. Making sure that only an email is sent for the new response and not any of the older ones.
enter image description here
My email will have the message line and subject using this code below:
var recipient = emailAddress
var message = ''
var subject = 'Department Alert';
MailApp.sendEmail(emailAddress, subject, message);
Any thoughts on how to achieve this?
This code will do the work for you.
Install the trigger onFOrmSubmit. Then it should be good to go.
function onFormSubmit(e) {
const form = FormApp.getActiveForm();
const items = form.getItems();
const formResponses = e.response;
const arr = [];
let receiptant_name;
for (i in items) {
let each_response = formResponses.getResponseForItem(items[i]).getResponse();
// this column has the supervisor name, you can change column title into yours.
if (items[i].getTitle() == 'Supervisor Name') {
// return a list of name
receiptant_name = each_response;
}
if (typeof(each_response) == "object") {
each_response ='<div>' + each_response.map(r => { return '<div>'+r+'</div>';}).join('') + '</div>';
}
const title = items[i].getTitle();
arr.push([title, each_response]);
}
const emailbody = return_emailbody(arr);
const receiptant_email = return_supv_email(receiptant_name);
sendEmail(receiptant_email, emailbody);
}
//this function to map form responses into html table.
function return_emailbody(responsearray) {
let mail_array = [];
responsearray.forEach(r => {
if (r[1] === null || r[1] === '') {
r[1] = 'N/A';
}
mail_array.push('<tr><td>' + r[1] + '</td></tr>')
});
const competed_template = htmltemplate(mail_array.join(''));
return competed_template;
}
//sheet id contains the supervisor email.Default Sheet1, you can change to your sheet name.
function return_supv_email(sheetid,supv_name) {
//receive name list
const values = sheet_data_return(sheetid, 'Sheet1');
let email_list = [];
for(i in supv_name){
values.filter(record => {
if (record[1].replace(/\s/g, '').includes(supv_name[i].replace(/\s/g, ''))) {
email_list.push (record[2]);
}
});
}
return email_list.toString();
}
function sheet_data_return(id, sheet_Name) {
return SpreadsheetApp.openById(id).getSheetByName(sheet_Name).getDataRange().getDisplayValues();
}
function sendEmail(recipient, emailbody) {
GmailApp.sendEmail(
recipient,
'FORM GOT A NEW RESPONSE',
emailbody,
{
htmlBody: emailbody,
name: 'GOOGLE FORM RESPONSE',
});
}
//you can edit your this HTML template to make your email look better.
function htmltemplate(emailbody) {
let template = '<!DOCTYPE html> <html> <head> <base target="_top"> </head><body><table>{body}</table> </body> </html>';
template = template.replace('{body}', emailbody);
return template;
}

update spreadsheet in serverside code run from client html javascript not working

I have an html where user requests add and enters data. The javascript in the body of the html calls the server side. I am unable to connect with the sheet either with saved ID or URL in order to add the row.
I cannot update of my spreadsheet despite #Serge insas comment that openById "it means "open for read and write". Am I making a simple mistake or is this impossible. The code initiated from the client side is running in the server.
const ssId = PropertiesService.getScriptProperties().getProperty('ssId');
var sheet = SpreadsheetApp.openById("[ssId]").getSheetByName('Sheet1');
const ssId = PropertiesService.getScriptProperties().getProperty('ssId');
var sheet = SpreadsheetApp.openById("ssId").getSheetByName('Sheet1');
Both get Error: Exception: Unexpected error while getting the method or property openById on object SpreadsheetApp.
const ssUrl = PropertiesService.getScriptProperties().getProperty('ssUrl');
var sheet = SpreadsheetApp.openByUrl("ssUrl").getSheetByName('Sheet1');
Gets error: Exception: Invalid argument: url
ABOVE IS THE IMPORTANT PART
/**
* this code is run from the javascript in the html dialog
*/
function addMbrCode(myAddForm) {
// removed logging
console.log("Beginning addMbrCode" );
paragraph = body.appendParagraph('Beginning addMbrCode.');
// Exception: Unexpected error while getting the method or property openById on object SpreadsheetApp.
// const ssId = PropertiesService.getScriptProperties().getProperty('ssId');
// var sheet = SpreadsheetApp.openById("[ssId]").getSheetByName('Sheet1');
// var sheet = SpreadsheetApp.openById("ssId").getSheetByName('Sheet1');
// Exception: Invalid argument: url
const ssUrl = PropertiesService.getScriptProperties().getProperty('ssUrl');
var sheet = SpreadsheetApp.openByUrl("ssUrl").getSheetByName('Sheet1');
myAddForm = [ fName, lName, inEmail, fallNum, winNum, sprNum];
var fName = myAddForm[0];
var lName = myAddForm[1];
var inEmail = myAddForm[2];
var fallNum = myAddForm[3];
var winNum = myAddForm[4];
var sprNum = myAddForm[5];
var retCd = '';
/**
* 10 - successful add
* 20 - duplicate - not added
*/
var combNameRng = sheet.getRange(2, 4, numRows).getValues();
var inCName = (fName + '.' + lName).toString().toLowerCase();
if (combNameRng.indexOf(inCName) > 0 ) {
console.log("Alert: Not adding duplicate "
+ fName + ' ' + lName + " retCd: " + 20 );
paragraph = body.appendParagraph("Not adding duplicate "
+ fName + ' ' + lName + " retCd: " + 20);
retCd = 20;
return retCd;
}
sheet.appendRow([fName.toString().toLowerCase()
, lName.toString().toLowerCase()
,
, inEmail.toString().toLowerCase()
]);
const currRow = sheet.getLastRow().toString();
);
retCd = 10;
return retCd;
}
If this makes a difference, here is the javascript from the body of my html in the dialog window.
<script>
document.querySelector("#myAddForm").addEventListener("submit",
function(e)
{
alert('begin addEventListener');
e.preventDefault(); //stop form from submitting
var retCd = google.script.run.addMbrCode(this); // client side validation
document.getElementById('errMsg').textContent = 'Successful member
return false; // do not submit - redisplay html
}
);
</script>
Removed unneeded coding detail
Per #iansedano I created an object/array to use instead of this and added the successhandler and failurehandler. In either case I want to see the html again with my message. This is the current script. Response is so doggy I am not seeing alerts, Logger.log, or console.log. Crazy shoppers using my internet!
<script>
document.querySelector("#myRmvForm").addEventListener("submit",
function(e)
// removed alerts and logging
// removed client side validation for simplicity
cSideValidate();
// Then we prevent the form from being submitted by canceling the event
event.preventDefault();
});
function cSideValidate() {
dataObj = [
document.getElementById('fName').value,
document.getElementById('lName').value,
document.getElementById('email').value
];
var retCd = google.script.run.withSuccessHandler(serverReply)
.withFailureHandler(serverReply)
.rmvMbrCode(dataObj); // server side validation
}
function serverReply {
// logic to set the correct message - this is an example
document.getElementById('errMsg').textContent
= 'Successful delete using email.';
}
</script>
Nothing is being added to my spreadsheet so the server side code is not working. I see my loggin so I know it is getting there.
You're getting ssId from the script properties and assigning it to the ssId variable, but then you pass a string ("ssId") to the openById() function, not the value of the variable.
Try the following please:
const ssId = PropertiesService.getScriptProperties().getProperty('ssId');
var sheet = SpreadsheetApp.openById(ssId).getSheetByName('Sheet1');

getChild of body of gmail email using Goole Apps Scripts (GAS)

Problem
I have automated emails coming to me with particular client details in them. I have the repetitive task of repling to each email with a template. I am wanting to automate the process utilising Google Apps Scripts.
Where I'm up to
I have worked out how to collect the body of the email I am replying to. I'm trying to get the third paragraph info and store this in a variable.
Here is my code:
function autoReply() {
//Capturing the automated email
var queryInbox = "is:unread from:(example#gmail.com)";
var locatedEmail = GmailApp.search(queryInbox);
for (var i in locatedEmail){
var thread = locatedEmail[i];
var messages = thread.getMessages();
var msgBody = messages[i].getBody();
var clientsEmail = msgBody.getChild('p')[3]; //Attempting to obtain the third paragraph of the body.
if(messages.length === 1) {
var body = "<p> The clients email is: " + clientsEmail + "</p>";
};
var options = { name: "Temp Name",htmlBody: body };
thread.reply(body, options);
thread.markRead();
thread.moveToArchive();
}
};
Note: Img attached for context.
I believe your goal as follows.
When the thread has one message, you want to retrieve the body of email.
You want to retrieve the 3rd paragraph from the message of email.
You want to reply the message including the retrieved 3rd paragraph.
Modification points:
At for (var i in unread){, I thought that you might use locatedEmail.
When you want to reply the message with messages.length === 1, var msgBody = messages[i].getBody(); is required to be modified. Because in your for loop, the index i is used for var thread = locatedEmail[i]; and var msgBody = messages[i].getBody();.
In your case, I think that getPlainBody() instead of getBody() might be suitable.
When above points are reflected to your script, it becomes as follows.
Modified script:
function autoReply() {
var queryInbox = "is:unread from:(example#gmail.com)";
var locatedEmail = GmailApp.search(queryInbox);
locatedEmail.forEach(thread => {
var messages = thread.getMessages();
if (messages.length === 1) {
var msgBody = messages[0].getPlainBody();
var clientsEmail = msgBody.split("\n")[2]; // Here, the 3rd paragraph is retrieved.
var body = "<p> The clients email is: " + clientsEmail + "</p>";
var options = { name: "Temp Name",htmlBody: body };
thread.reply(body, options);
thread.markRead();
thread.moveToArchive();
}
});
}
Reference:
getPlainBody()

Getting all the Google Ads Labels from MCC. Also the onces created by other users within a client account

Google Ad Scripts makes it possible to get the labels of child/client accounts. But not the onces, who are created by a client itself. Is there a way to get ALL the labelnames?
I tried serveral script, but all are returning the MCC labels
function getAllAccountLabels() {
var labelIterator = AdsManagerApp.accountLabels().get();
while (labelIterator.hasNext()) {
var label = labelIterator.next();
Logger.log('Label with id = %s and text = %s was found.', label.getId().toFixed(0), label.getName());
}
}
There is a difference in handling the MCC labels.
AdsManagerApp.accounts().withCondition( 'LabelNames CONTAINS "test"' ).get();
And
var accountIterator = AdsManagerApp.accounts().get();
while (accountIterator.hasNext()) {
var account = accountIterator.next();
var accountName = account.getName();
var labelIterator = account.labels().get();
while (labelIterator.hasNext()) {
var label = labelIterator.next();
var labelName = label.getName();
if( labelName.match(/test/i) ) {
Logger.log( accountName+" "+labelName );
}
}
}
WithCondition is not returning the user-level label names!

Trying to understand getThreads in GAS

I am new to app script and I am trying to read an email from my inbox. I thought that getThreads would do the job but I still don't fully understand how to use it. When I try to execute the code I wrote below it comes up with a null error.
Looking at the documentation of getThreads(), they use the example:
// Log the subject lines of the threads labeled with MyLabel
var label = GmailApp.getUserLabelByName("MyLabel");
var threads = label.getThreads();
for (var i = 0; i < threads.length; i++) {
Logger.log(threads[i].getFirstMessageSubject());
}
what does "MyLabel" stand for?
This is the code i tried that failed
function myFunction() {
var label = GmailApp.getUserLabelByName('bobtheman#gmail.com');
var threads = label.getThreads();
for (var t in threads) {
var thread = threads[t];
// Gets the message body
var message = thread.getMessages()[0].getPlainBody();
}
GmailApp.sendEmail('barbrabat#gmail.com', 'hola', message)
}
MyLabel is the label of the email. It depends whether you added a label to a specific email or not. You can use the search method instead.
function myFunction(){
var label = 'yourLabel'; // if no label, remove the label in search
// it would be better if you add a label to a specific email for fast and more precise searching
var searchEmail = GmailApp.search('from:me subject:"' + subject + '" label:' + label + '');
var threadId = searchEmail[0].getId(); // get the id of the search email
var thread = GmailApp.getThreadById(threadId); // get email thread using the threadId
var emailMsg = thread.getMessages()[0]; // get the content of the email
var emailContent = emailMsg.getPlainBody(); // get the body of the email
// check using log
Logger.log(emailContent);
// how to open log
// Ctrl + Enter
// Run this function before checking the log
}
Thanks

Categories