Google Sheets connecting with Gmail or Slack - google-sheets

I'm looking for a code I can use in google sheets.
I need to get a notification when a cell changes in a specific column and get it through email or Slack.
Can someone please help me?
I'm currently using
function onSpeEdit(e) {
var sh = e.source.getActiveSheet();
var rng = e.source.getActiveRange();
var col = 1
if (sh.getName() == 'mySheet' && rng.getColumn() == col) {
MailApp.sendEmail(
'yourEmail#gmail.com',
`Change Notification`,
`Change in ${rng.getA1Notation()} old value "${e.oldValue}" new value "${e.value}" `);
}
}

Try
function onSpeEdit(e) {
var sh = e.source.getActiveSheet();
var rng = e.source.getActiveRange();
var col = 1
if (rng.getColumn() == col) {
MailApp.sendEmail(
'yourEmail#gmail.com',
`Change Notification`,
`Change in ${rng.getA1Notation()} of ${sh.getName()} old value "${e.oldValue}" new value "${e.value}" `);
}
}
change name of sheet, column and email address
you will need to define an installable trigger in order to use services that requires authorization.
Installable Triggers
edit : il you want to add another information, i.e. from column B, try to replace the sentence by
`Hey, the title ${sh.getRange('B'+rng.getRow()).getValue()} from sheet ${sh.getName()} changed. Before it has the number ${e.oldValue} now is ${e.value}.`

Related

How to apply formatting to a code-generated gmail

I am following these tutorials on how to create an email and populate it with values from a Google Sheet.
https://developers.google.com/apps-script/articles/sending_emails
https://katydecorah.com/code/google-sheets-to-gmail/
It all works as expected, however I cannot apply any formatting to the email such as underline, bold or even tables. Any formatting I apply in the original Google Doc is removed when the email is generated.
EDIT:
Here is the Google-Doc used as the template
Dear {caregiver}
Herewith please find the Weekly Engagement Summary for {fname} {sname}
Week 1: {week_1_score}
Week 2: {week_2_score}
Thank You
And here is the Google-Sheet used with the values
fname|sname|caregiver|email|week_1_score|week_2_score|date drafted
bob|smith|parent1|user1#gmail.com|4|3
john|jones|parent2|user2#gmail.com|2|4
rob|brown|parent3|user3#live.com|3|5
And here is the code-behind script that glue them together and creates the email
// What is the Google Document ID for your email template?
var googleDocId = "<my id>";
// Which column has the email address? Enter the column row header exactly.
var emailField = 'email';
// What is the subject line?
var emailSubject = 'Weekly Engagement Indicator';
// Which column is the indicator for email drafted? Enter the column row header exactly.
var emailStatus = 'date drafted';
/* ----------------------------------- */
// Be careful editing beyond this line //
/* ----------------------------------- */
var sheet = SpreadsheetApp.getActiveSheet(); // Use data from the active sheet
function draftMyEmails() {
var emailTemplate = DocumentApp.openById(googleDocId).getText(); // Get your email template from Google Docs
var data = getCols(2, sheet.getLastRow() - 1);
var myVars = getCols(1, 1)[0];
var draftedRow = myVars.indexOf(emailStatus) + 1;
// Work through each data row in the spreadsheet
data.forEach(function(row, index){
// Build a configuration for each row
var config = createConfig(myVars, row);
// Prevent from drafing duplicates and from drafting emails without a recipient
if (config[emailStatus] === '' || config[emailStatus] !== '' && config[emailField]) {
// Replace template variables with the receipient's data
var emailBody = replaceTemplateVars(emailTemplate, config);
// Replace template variables in subject line
var emailSubjectUpdated = replaceTemplateVars(emailSubject, config);
// Create the email draft
GmailApp.createDraft(
config[emailField], // Recipient
emailSubjectUpdated, // Subject
emailBody // Body
);
sheet.getRange(2 + index, draftedRow).setValue(new Date()); // Update the last column
SpreadsheetApp.flush(); // Make sure the last cell is updated right away
}
});
}
function replaceTemplateVars(string, config) {
return string.replace(/{[^{}]+}/g, function(key){
return config[key.replace(/[{}]+/g, "")] || "";
});
}
function createConfig(myVars, row) {
return myVars.reduce(function(obj, myVar, index) {
obj[myVar] = row[index];
return obj;
}, {});
}
function getCols(startRow, numRows) {
var lastColumn = sheet.getLastColumn(); // Last column
var dataRange = sheet.getRange(startRow, 1, numRows, lastColumn) // Fetch the data range of the active sheet
return dataRange.getValues(); // Fetch values for each row in the range
}
Any help appreciated.
Thanks

How to run a Dynamic Script in Google Sheets (live edit)

I am trying to run a script that will execute when the checkbox is marked "TRUE" and send an email to a client. I can not get the triggers to work and I can seem to make my own work either. I am putting the code below. Please help.
'''code'''
***Email Function
function SendEmail(i) {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
//var lr= ss.getLastRow();
//for (var i = 2; i<=lr;i++){
var currentEmail= ss.getRange(i, 1).getValue();
//logger.log(currentEmail);
var currentADID= ss.getRange(i, 3).getValue();
MailApp.sendEmail(currentEmail,"Customer Ready"+ currentADID,"This customer should be ready to schedule and installtion date and time" );
}
Trigger Function
function CheckCD() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var lr= ss.getLastRow();
for (var i = 2; i<=lr;i++){
var currentDCheck= ss.getRange(i, 4).getValue();
var x= onEdit():
if (currentDCheck == true)
SendEmail(i)
}
}***
You actually misunderstood how to use onEdit trigger, although you need to install the trigger in this case due to permission needed by MailApp.sendEmail
Anyways, you need to make use of the event object (e) as it holds the details about the edited cell's properties. See code below:
Code:
// Trigger function, install it under "Triggers" tab as you need permission for MailApp
function CheckCD(e) {
// get the row and column of the edited cell
var row = e.range.getRow();
var column = e.range.getColumn();
// proceed only if edited cell's range is D2:D and value is "TRUE"
if (row > 1 && column == 4 && e.value == "TRUE") {
// get the sheet where the cell was edited
var ss = e.source.getActiveSheet();
// get Email and ADID of the same row where checkbox was ticked
var currentEmail = ss.getRange(row, 1).getValue();
var currentADID = ss.getRange(row, 3).getValue();
MailApp.sendEmail(currentEmail, "Customer Ready" + currentADID, "This customer should be ready to schedule and installtion date and time");
}
}
Install trigger:
Make sure to choose On edit event type and choose the function you want to run. (in this case, CheckCD)
Sample data:
Output:
Note:
The behavior of this script is that every time someone checks a checkbox on range D2:D and the resulting value is TRUE, then it sends an email. (as it seems you have different email per row, but if not, send them all in one email)
References:
Installable Triggers

Google Sheets - making script run on iOS sheets app

I am running the following script as its own .gs file
/**
* TITLE:
*     Hide a row if a value is inputted.
*/
//**GLOBALS**
// Sheet the data is on.
var SHEET = "Norm Adam";
// The value that will cause the row to hide.
var VALUE = "Yes";
// The column we will be using
var COLUMN_NUMBER = 11
function onEdit(e) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var activeSheet = ss.getActiveSheet();
  
  //Ensure on correct sheet.
  if(SHEET == activeSheet.getName()){
    var cell = ss.getActiveCell()
    var cellValue = cell.getValue();
    
    //Ensure we are looking at the correct column.
    if(cell.getColumn() == COLUMN_NUMBER){
      //If the cell matched the value we require,hide the row.
      if(cellValue == VALUE){
        activeSheet.hideRow(cell);
      };
    };
  };
}
It works fine on a computer browser but on iOS device it doesn't work through the google sheets app and I actually can't even get the editable through safari. I read that only the onEdit function will work on a mobile device so I figured this should work. Is there another piece to this puzzle?
Thanks
Mike
(credit for script creation goes to: https://yagisanatode.com/2018/05/26/how-to-hide-a-row-based-on-a-cell-value-in-google-sheets-with-filter-or-google-apps-script/ )
Script V2:
I commented below on this still not working in iOS. I figured the simpler it was the more likely to work?
function onEdit(e) {
if (e.range.getColumn() == 11 && e.value == 'Yes') {
e.range.getSheet().hideRows(e.range.getRow());
}
}
getActive calls, especially ss.getActiveCell() should be avoided on mobile apps. Consider alternatives like e.range to get the edited range from event objects.

Google Sheets Script permissions for everyone allowed access to a sheet

I know there are a lot of questions out there related to Google Scripts and some of them touch on my issue but I can't seem to figure out the full answer.
I only want to be able to run 1 or 2 scripts in the same project file for 1 spreadsheet. How do I allow permission for everyone with whom the sheet is shared WITHOUT forcing each user to go through the process of allowing Authorization? Is this possible?
Maybe there is an alternative script? Here is my script (in case this helps):
function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{name:"Go to active row", functionName:"Go to active
row"}];
sheet.addMenu("Scripts", entries);
myFunction();
};
function gotoend() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var lastRow = sheet.getDataRange().getValues();
lastRow.forEach(function (row,index) {
if (row[3] == "") { // row[0] is the same as Column A. row[1] = B
lastRow.length = index;
}
});
var newRange = sheet.getRange(lastRow.length,1);
sheet.setActiveRange(newRange);
}
/**
* #OnlyCurrentDoc
*/

Google Script - Auto Fill Current Date-Time when select specific text in the drop down list

I wonder if anyone can help me with the following google script? I just begin to work on some google script and help my colleagues to track the production of his work.
Here is the field is explained below.
Column 9 = Status (Dropdown list: Pending, In-progress, Done)
Column 11 = Send Date
Column 13 = Start Date
Column 14 = End Date
How I want the script work
Example:
When Column 9 (dropdown list) value = "Pending" then auto fill the current
date to Column 11.
When Column 9 (dropdown list) value = "In-progress" then auto fill
the current date to Column 13.
When Column 9 (dropdown list) value = "End Date" then auto fill the current
date to Column 14.
The code I am working on to get when the status is "In-Progress".
I know I am wrong about this part. -> [s.getValue() !== 'In-progress']
But I am not sure where or how to put the certain text that I am looking for in here.
function onEdit(e) {
var s = e.source.getActiveSheet(),
cols = [9],
colStamp = 13,
ind = cols.indexOf(e.range.columnStart)
if (s.getName() !== 'Lab Cases Tracker' || s.getValue() !== 'In-progress' || ind == -1) return;
e.range.offset(0, parseInt(colStamp - cols[ind]))
.setValue(e.value ? new Date() : null);
}
Thank you so much!
This should do it:
function onEdit(e) {
var ss=SpreadsheetApp.getActiveSpreadsheet()
var s1=ss.getActiveSheet()
var s = e.source.getSheetName()
var col=e.range.getColumn()
var r=e.range.getRow()
var val=e.value
var curDate = Utilities.formatDate(new Date(), "GMT+1", "MM/dd/yyyy")
if(s=="Lab Cases Tracker" && col==9){
if(val=="Pending"){
s1.getRange(r,11,1,1).setValue(curDate);
}
else if(val=="In-progress"){
s1.getRange(r,13,1,1).setValue(curDate);
}
else if(val=="End Date"){
s1.getRange(r,14,1,1).setValue(curDate);
}
else{return}
}}

Resources