I have a Googlesheets Stock Price Alert Script Running for a single stock in a GoogleSheet. It checks the current price against a target price and sends an email alert if it is lower.
How would I expand my script to check a list of stocks in the spreadsheet? I think I need a loop or something to scroll down each row but I'm unsure of how to do this.
My working code for single row check:
// Fetch the stock price
var stockNameRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getRange("A2");
var currentPriceRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getRange("C2");
var targetPriceRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getRange("B2");
var stockName = stockNameRange.getValue();
var currentPrice = currentPriceRange.getValue();
var targetPrice = targetPriceRange.getValue();
// Check stock prices
if (currentPrice < targetPrice){
// Fetch the email address
var emailRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2").getRange("B2");
var emailAddress = emailRange.getValues();
// Send Alert Email.
var message = stockName +" "+ currentPrice +" is below your target price of "+ targetPrice;
var subject = 'Low Price Alert';
MailApp.sendEmail(emailAddress, subject, message);
}
}```
Try this:
function sdk(){
// Fetch the stock price
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("sheet1");
var data = ss.getRange("A13:C23").getValues(); // gets all the data from the three cols and puts it into a 2D array.
var emailRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2").getRange("B2");
var emailAddress = emailRange.getValues();
var message = "";
for (var i = 0; i < data.length; i++){ // will go over the rows that you stored in data with data[i][0] being the stock name, data[i][1] being the target and data[i][2] being the current value.
// Check stock prices
if (data[i][2] < data[i][1]){
// Send Alert Email.
message += data[i][0] +" "+ data[i][2] +" is below your target price of "+ data[i][1] + " \n";
}
}
if (message != "")
MailApp.sendEmail(emailAddress, 'Low Price Alert', message);
}
Keep in mind that I used the range A13:C23 because that's where I had my test data, you will have to use yours depending on how you have structured your sheet, but this code will loop and get you the information you want into the email. it basically keeps appending rows of "alerts" into a message and sends everything together at the end of the loop.
When working with Apps Scripts, try to limit the calls to the APIs to make the code more optimized, this is why I changed the way you stored the ranges into a single call when getting the sheet in var ss = ..., this is also why using getValues() is important, it's only one call to the API instead of getting individual cells' values.
Related
first of all I would like to say that I am really a rookie at Apps Script.
I have found Script Code for automated Email notification when certain date is expired. I tried to alter the code for my SpreadSheet, but unfortunately it does not work properly for me:
function offboardingReminder() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// set active sheet to first sheet
spreadsheet.setActiveSheet(spreadsheet.getSheets()[0]);
var sheet = spreadsheet.getActiveSheet();
// figure out what the last row is
var lastRow = sheet.getLastRow();
var startRow = 2;
// grab all data from user to days left
var range = sheet.getRange(startRow, 1, lastRow - startRow + 1, 45);
var values = range.getValues();
var users = [];
// loop all data per row
values.forEach(function(row) {
// if days left is 3
if(row[45] <= 30) {
// add user if 3 days left
users.push(row[0]);
}
});
// if users has elements
if(users) {
// Formatted the message as html to look nicer
var message = "<html><body><h2>Reminder</h2><p>The following device/s service is due in 30 days or less:</p>";
// created bulleted list for list of users
var emails = "<ul>";
users.forEach(function(user){
emails = emails + "<li>" + user + "</li>";
});
emails += "</ul>";
message = message + emails + "</body></html>";
MailApp.sendEmail("norbert.jedrzejczak#kbcpl.pl", "Reminder Date Dues Services", "", {htmlBody: message, noReply: true});
}
}
So what I would like to accomplish here is to send automated notification every week with the list of expired services.
I have a spreadsheet with 51 columns and I would like to:
Take the name of the customer (column 31)
Take the date of last service (column 41)
Take the number of days left to next service (column 44) - and take these values which are equal or less than 30
And send a message with these data.
Subject: "Reminder Date Dues Services" + Current Date (of sending each email)
Body:
"Reminder! The following device/s service is due in 30 days or less:"
And below - a list of devices to be serviced - e.g. "CUSTOMER 1 - DEVICE 1 - SERIAL NUMBER 1 - DATE OF LAST SERVICE - DATE TO NEXT SERVICE"
Could you please help me out with the code? I would be grateful for your tips and recommendations.
Just to get you started:
function lfunko() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet0");
const sr = 2;
const vs = sh.getRange(sr,sh.getLastRow() - sr + 1, sh.getLastColumn()).getValues();
vs.forEach((r,i) => {
let n = r[30];
let dt = r[40];
let ds = r[43];
if(ds < 30 ) {
//complete message and email in here
}
})
}
I want to write a script that will send an email based on the criteria of a single column.
This is for an inventory management system that will send emails to remind that certain items are low in count.
eg.
if row 5's column J is = "reminder", send values of row 5's column B and C to my email. (col B and C is item description and quantity count respectively)
I just started learning about google app script so I'm not sure how to write it myself, but from other forum posts, this is what I got.
var values = SpreadsheetApp.getActiveSheet().getDataRange().getValues();
values.forEach(function(row) {
var indent = row[10]; //column j
if (indent !== '') {
var EditedRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("store list").getRange(indent);
var Edited = EditedRange.getValue();
}
// Fetch the email address
var emailRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("mail").getRange("B2");
var emailAddress = emailRange.getValue();
// Send Alert Email.
var message = Edited;
var subject = 'For Action: Indent' ;
MailApp.sendEmail(emailAddress, subject, message);
});
}
I split the code up and tested emailing and apparently the email portion of the codes work, but it is the retrieving of data that is not working and I don't really know how to get it working.
To get started, have a look at the Apps Script reference
There you will see that to retrieve the value of a single cell it is bets to use the method getValue() instead of getValues()
You need to specify the range (cell) wrom ehre you want to get the value
The easiest way to do so is with the method getRange() specifying A1 notation
A simple sample would be:
var sheet = SpreadsheetApp.getActiveSheet();
var checkValue = sheet.getRange("J5").getValue();
if (checkValue == "reminder"){
var B5Value = sheet.getRange("B5").getValue();
var C5Value = sheet.getRange("C5").getValue();
var message = B5Value + " and " + C5Value;
var emailAddress = "you need to define the email address of the recipient either in the code or a cell of the sheet";
var subject = "Define here your subject";
MailApp.sendEmail(emailAddress, subject, message);
}
Please make sure to dedicate enough time to study the Apps Script documentation to understand this code and be able to troubleshoot and perform simple modifications.
I have a google sheets tool where I automatically get the number of products on our site every hour with the Shopify API.
https://docs.google.com/spreadsheets/d/1m1lF6jLWPIKhJDOut_G-2tX_zYW4fU9dHKwIs03rr1Y/edit?usp=sharing
I need to develop a code for this tool. This code will check this product number after each product number search and if this product number is below 1000, it should send me a mail informing the product number. How can I improve this?
The function that takes the number of products from the site
function _1() {
var spreadsheet = SpreadsheetApp.getActiveSheet();
var startCol = 1
var lastRow = spreadsheet.getLastRow();
var rawtext = UrlFetchApp.fetch("https://kolayoto.com/collections/lastikleri.json").getContentText()
var jsonObj = JSON.parse(rawtext);
var contentObj = jsonObj.collection
var columns = Object.keys(contentObj)
var colName = []
var result = []
for (var i = 0; i < columns.length; i++){
var key = columns[i]
var value = contentObj[key]
result.push(value)
}
var numRow = 1
var numCol = columns.length
if(lastRow+1 == 1){
spreadsheet.getRange(lastRow+1, startCol, numRow, numCol).setValues([columns]);
spreadsheet.getRange(lastRow+2, startCol, numRow, numCol).setValues([result]);
}else {
spreadsheet.getRange(lastRow+1, startCol, numRow, numCol).setValues([result]);
}
spreadsheet.getRange(lastRow+1, startCol).activate();
};
The function that should take the Products Count number of the last row and send mail if it is less than 1000. (It is not working and has not been completed yet.) https://gyazo.com/e2fd5cdc4043dec00da1fce0e3c6c0ca (6562 is products count)
function SendEmail() {
// Fetch the monthly sales
var spreadsheet = SpreadsheetApp.getActiveSheet();
// I need your help in here. How can I get the products count in the last row after each run?
// Check totals sales
if (productsCount < 1000){
// Send Alert Email.
var message = 'KolayOto Lastik Ürün Sayısı Uyarısı!'; // Second column
var subject = 'Ürün sayısı uyarısı!';
MailApp.sendEmail("bbelcioglu#sekizgen.com", subject, message);
MailApp.sendEmail("berk.belcioglu#gmail.com", subject, message);
}
}
I hope I could explain the problems enough. I would be glad if you help.
Thanks.
I believe your goal as follows.
You want to retrieve the Products Count number from the URL using Google Apps Script.
In this case, you want to return the value of 6562.
You want to return that value at the function of _1().
For this, how about this answer?
Modification points:
When the returned value from the URL is seen, the Products Count number can be retrieved with contentObj.products_count.
Modified script:
When your script of _1() is modified, it becomes as follows.
From:
spreadsheet.getRange(lastRow+1, startCol).activate();
};
To:
spreadsheet.getRange(lastRow+1, startCol).activate();
return contentObj.products_count; // <--- Added
};
And, by above modification, SendEmail() can be modified as follows.
function SendEmail() {
var productsCount = _1(); // <--- Added
// Fetch the monthly sales
var spreadsheet = SpreadsheetApp.getActiveSheet();
// I need your help in here. How can I get the products count in the last row after each run?
// Check totals sales
if (productsCount < 1000){
// Send Alert Email.
var message = 'KolayOto Lastik Ürün Sayısı Uyarısı!'; // Second column
var subject = 'Ürün sayısı uyarısı!';
MailApp.sendEmail("bbelcioglu#sekizgen.com", subject, message);
MailApp.sendEmail("berk.belcioglu#gmail.com", subject, message);
}
}
We are using Google Forms to collect data from our field reps while they are out at a job site. We use a script to fill drop down values for 4 different fields and that runs periodically. This saves them from having to type it out and possible make mistakes.
All of those fields are pre-determined, so if they select Project #1, we already know the values of address, manager, and client. The values are stored in a second tab of the results form and could theoretically be used as a lookup.
I question whether these fields need to be included at all, but when the user submits the form, the data is then emailed using an add-on and it uses some of those fields in the subject. I suppose the recipients want the info as well.
Can I make my own triggers? If I had a trigger for when the project ID changed, I would think I could update the others from a spreadsheet.
Or if there was a OnNextPage trigger that I could use to fill those values.
Is there anyway to add/change values when the form is submitted?
I think the following is what I want to do (thanks #OMilo), but I am struggling with the lookups:
function onFormSubmit(e) {
Logger.log("[METHOD] onFormSubmit");
sendEmail(e.range);
}
function sendEmail(range) {
// Here we get choice the users selected in the form:
var itemResponse = e.response.getItemResponses()[1557784536]; // Use whatever index is the item, in my case it's 0.
var kmbProjectNumber = itemResponse.getResponse();
//LOOKUP KMB PROJECT NUMBER IN SHEET: "New - KMB Design Visit Closeout (Responses)" TAB: "KMB Lookups"
var ss = SpreadsheetApp.OpenByID('REDACTED');
var lookups = ss.getSheetByName("KMB Lookups");
//In Column named'KMB Project ID' find record from bottom where value = kmbProjectNumber
//Get value for column named 'Site Address'
//Get value for column named 'KMB Project Manager'
//Get value for column named 'Client Assigning this Work'
// FETCH SPREADSHEET //
var values = range.getValues();
var row = values[0];
//WRITE FOUND VALUES TO SPREADSHEET
//Set row[3] to Site Address
//Set row[4] to Project Manger
//Set row[5] to Client
var svProjectManager = row[4]; //Update manually //E
var svClient = row[5]; //Update manually //F
// EXTRACT VALUES //
var svTimeStamp = row[0]; //A
var svInitials = row[1]; //B
var svProjectID = row[2]; //C
var svSiteAddress = row[3]; //Update manually //D
var svProjectManager = row[4]; //Update manually //E
var svClient = row[5]; //Update manually //F
var svNOCNeeded = row[6]; //G
// PREPARE EMAIL //
var emailRecipients = "REDACTED";
var emailSubject = "Field Visit Completed for "+svProjectManager+" "+svProjectID;
var emailBody = "" //Format using variables set
// SEND EMAIL //
}
You don't need to include these fields in the form itself. Instead, you can set different values depending on which option they choose in the function that is trigged by the onFormSubmit trigger.
I wrote a small sample to show how this can be done.
First, create the onFormSubmit trigger if you haven't done so:
function createTrigger() {
var form = FormApp.openById('your_form_id'); // Change accordingly
ScriptApp.newTrigger('getData')
.forForm(form)
.onFormSubmit()
.create();
}
Next, create the function that will be called by the trigger, when the user submits the form:
function getData(e) {
// Here we get choice the users selected in the form:
var itemResponse = e.response.getItemResponses()[0]; // Use whatever index is the item, in my case it's 0.
var response = itemResponse.getResponse();
var values = getDataFromSheet(); // Getting the values from the sheet
for(var i = 1; i < values.length; i++) { // Checking which row from the sheet corresponds to the choice selected in the form
var row = values[i];
if(row[2] == response) { // Checks if current sheet row is the one selected in the form submission
var emailData = { // Data for email to be sent is assigned depending on form choice and sheet data
project: row[2],
address: row[3],
manager: row[4],
client: row[5]
}
}
}
// Preparing email parameters
var emailBody = emailData["address"] + " - " + emailData["manager"] + " - " + emailData["client"];
var emailSubject = "Field Visit Completed for " + emailData["manager"] + " " + emailData["project"];
var emailRecipient = 'valid email'; // Change accordingly
// Sending email
MailApp.sendEmail(emailRecipient, emailSubject, emailBody);
}
In the above function, getDataFromSheet is called:
function getDataFromSheet() {
var ss = SpreadsheetApp.openById('your_spreadsheet_id'); // Change accordingly
var lookups = ss.getSheetByName("KMB Lookups");
var values = lookups.getDataRange().getValues();
return values;
}
I hope this is useful to you.
I'm setting up an email alert on my google sheet, in which if a value in one column goes below 2 I get an email alert on my mail.
I have mulitple domains and it is very tedious to check the domains expiry date every day. I created a sheet in which I put up domain name, registrar,hosted, todays date, expiry date, Expiry remaining days. Now I want to create an alert on "Expiry remaining days column", so that when the remaining days is below 2 days it send an alert email to my list of email addresses.
What I have already done is getting an email for one cell value but what I want to do is get it on whole column or number of column values.
function CheckSales() {
// Fetch the values
var domainexpireRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("domain list").getRange("F2");
var domainexpire = domainexpireRange.getValues();
// Check domain expiring
if ( domainexpire < 2){
var emailRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Company emails").getRange("B2:B4");
var emailAddress = emailRange.getValues();
// Send Alert Email.
var message = '2019 smtp Domain Expiring in two days. Please check the sheet domain sheet '; // Second column
var subject = '2019 smtp Domain Expiring';
MailApp.sendEmail(emailAddress, subject, message);
}
}
I have a sheet which has multiple rows and columns, what I want to do is check column F and if any of the value on column F is less than 2 then send an alert email to my email addresses.
My code is working fine if I copy paste the code to multiple times and change the "getRange("F2");" to F2,F3,....F100 .
But it is not good way to put up a code. Can anyone tell me if I can edit some code and get the result.
I tried using "getRange("F2:F");" & getRange("F2:F54");but it doesn't worked out.
Thanks for your help.
Try using a for statement to loop through the whole sheet, the one below should work:
function checkSales() {
// Fetch the values
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getSheetByName("domain list");
var dataRange = sheet.getDataRange();
var data = dataRange.getValues();
// loop through each row starting at row 2
for (var i = 1; i < data.length; i++) {
var domainExpire = data[i][5];
// Check domain expiring
if (domainExpire < 2) {
var emailRange = spreadsheet.getSheetByName("Company emails").getRange("B2:B4");
var emailAddress = emailRange.getValues();
// Send Alert Email.
var message = '2019 smtp Domain Expiring in two days. Please check the sheet domain sheet '; // Second column
var subject = '2019 smtp Domain Expiring';
MailApp.sendEmail(emailAddress, subject, message);
}
}
}
Try this:
function CheckSales() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('domain list');
var domainexpireRange=sh.getRange(1,6,sh.getLastRow()-1,1);
var domainexpire=domainexpireRange.getValues();
for(var i=0;i<domainexpire.length;i++) {
// Check domain expiring
if (domainexpire[i][5]<2){
var emailRange=ss.getSheetByName("Company emails").getRange("B2:B4");
var emailAddress=emailRange.getValues().map(function(r){return r[0];}).join(',');
// Send Alert Email.
var dateString=Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyy");
var message=Utilities.formatString('%s smtp Domain Expiring in two days. Please check the sheet domain sheet.',dateString);
var subject=Utilities.formatString('%s smtp Domain Expiring',dateString);
MailApp.sendEmail(emailAddress, subject, message);
}
}
}