I am trying to send an email using Google scripts to multiple emails listed in the cells. I would like to send one email and the other emails would be cc. Emails are listed in cells D10:D12, M5:M6, and AL10:AL12
Sheet Link = https://docs.google.com/spreadsheets/d/1xVjEQv6FOnKk-qZgcPV4b7vdeEP3h53on2CA-jJa7iU/edit?usp=sharing
The current script is working great to send an email to me. Just can't figure out how to do the multiple emails and CC's.
function sendEmail() {
var email = sheet.getRange(D10:D12).getValues();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var actualSheet=SpreadsheetApp.getActiveSheet()
var sheet = ss.getActiveSheet() // Enter the name of the sheet here
var subject = "PDF from Water Polo Scoresheet - " + actualSheet.getName();
var body = "\n Attached is a PDF copy of the sheet " + sheet.getName() + " in the " + ss.getName() + " spreadsheet. For the most up to date scoresheet make sure and check www.waterpolodrills.com";
// Base URL
var url = "https://docs.google.com/spreadsheets/d/SS_ID/export?".replace("SS_ID", ss.getId());
/* Specify PDF export parameters
From: https://code.google.com/p/google-apps-script-issues/issues/detail?id=3579
*/
var url_ext = 'exportFormat=pdf&format=pdf' // export as pdf / csv / xls / xlsx
+ '&size=letter' // paper size legal / letter / A4
+ '&portrait=false' // orientation, false for landscape
+ '&fitw=true&source=labnol' // fit to page width, false for actual size
+ '&sheetnames=false&printtitle=false' // hide optional headers and footers
+ '&pagenumbers=false&gridlines=false' // hide page numbers and gridlines
+ '&fzr=false' // do not repeat row headers (frozen rows) on each page
+ '&gid='; // the sheet's Id
var token = ScriptApp.getOAuthToken();
var response = UrlFetchApp.fetch(url + url_ext + sheet.getSheetId(), {
headers : {
'Authorization' : 'Bearer ' + token
}
}).getBlob().setName(sheet.getName() + ".pdf");
// Uncomment the line below to save the PDF to the root of your drive.
// var newFile = DriveApp.createFile(response).setName(sheet.getName() + ".pdf")
if (MailApp.getRemainingDailyQuota() > 0)
GmailApp.sendEmail(email, subject, body, {
htmlBody : body,
attachments : [response],
cc : ccEmail.join(",")
});
}
As described in the doc of sendEmail, you can add options as the 4th parameter (https://developers.google.com/apps-script/reference/mail/mail-app#sendEmail(String,String,String,Object))
In the possible options parameter, there is cc with description "a comma-separated list of email addresses to CC"
So I guess you could use it like this:
ccEmails = //get your ccs here
if (MailApp.getRemainingDailyQuota() > 0)
GmailApp.sendEmail(email, subject, body, {
htmlBody : body,
attachments : [response],
cc : ccEmails.join(",")
});
Related
I want to send the active sheet in google sheet as pdf by whatsapp to given number.
There will be number with country code in the active sheet. I want to send the sheet as pdf to that number via whatsapp.
I have this code from StackOverflow to email the document as pdf:
// Define your variables here
var recipient="ronyantonyjoseph#gmail.com";
var subject=SpreadsheetApp.getActiveSpreadsheet().getName();
var body="Hello,\n\nPlease find attached bill for the month.\n\nThank you,\nMoothedam RPS";
var nameOfSender="Moothedam RPS";
// End of the stuff you need to edit
// Below, the sheet is converted to pdf in a blob object and that object
// is sent by email with the email-parameters above.
// Other stuff
var ss = SpreadsheetApp.getActiveSpreadsheet();
//var ssId = SpreadsheetApp.getActiveSpreadsheet().getId();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
//var sheetName = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName();
//var sheetId = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getSheetId();
// Base URL
var url = "https://docs.google.com/spreadsheets/d/SS_ID/export?".replace("SS_ID", ss.getId());
/* Specify PDF export parameters
From: https://code.google.com/p/google-apps-script-issues/issues/detail?id=3579
*/
var url_ext = 'exportFormat=pdf&format=pdf' // export as pdf / csv / xls / xlsx
+ '&size=A4' // paper size legal / letter / A4
+ '&portrait=true' // orientation, false for landscape
+ '&fitw=true&source=labnol' // fit to page width, false for actual size
+ '&sheetnames=false&printtitle=false' // hide optional headers and footers
+ '&pagenumbers=false&gridlines=false' // hide page numbers and gridlines
+ '&fzr=false' // do not repeat row headers (frozen rows) on each page
+ '&gid='; // the sheet's Id
var token = ScriptApp.getOAuthToken();
var response = UrlFetchApp.fetch(url + url_ext + sheet.getSheetId(), {
headers : {
'Authorization' : 'Bearer ' + token
}
}).getBlob().setName(sheet.getName() + ".pdf");
sheet_as_pdf_blob_document=response;
// Here we send the email
function sendReport() {
var message = {
to: recipient,
subject: subject,
body: body,
name: nameOfSender,
attachments: [sheet_as_pdf_blob_document]
}
MailApp.sendEmail(message);
}
//===============
//===============
But I am not having any idea how to send this using whatsapp
Just read docs and after that do simple POST request:
On /v1/messages with params type: document.
I'm receiving a gmail from the below code, but NOT the form values that I want to be included. I'm trying have a Google Form (Sheet) send an email to me (a teacher) when a student would type an important or alarming keyword in one of the form's fields (col J).
Picture a Google form with essentially the following fields:
A - Date/time stamp
B - email address collection
C - Name (short answer text)
D - what did you learn or work on yesterday? (long answer text)
E - How are you generally feeling today? (multiple choice)
F - Are you tired today? (multiple choice)
G - Are you stressed out today? (multiple choice)
H - What have you going on today? (bunch of checkboxes)
I - What could be "cool" or "good" about today? (long answer text)
J - (optional) Feel free to tell me anything more (long answer text)
If the student types any alert words, like "die" or "drugs" and so on in the last column (column J), I'd like to get a gmail with a summary of all the info on the row. So far, I've set up a trigger and am only getting a gmail with a subject and message, but the message DOES NOT contain the concatenated vars values.
ALSO, the gmail's subject DOES NOT contain the concatenated studname, which would be helpful. I'm curious how you'd fix this code.
THANK YOU!!
function checkComments(){
var commentsRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2").getRange("J2");
var sheet = SpreadsheetApp.getActive().getSheetByName("Sheet2");
var lastrow = sheet.getLastRow();
var comments = sheet.getRange('J' + lastrow).getValue();
if (comments === '.*drug.*'||'.*die.*'||'.*emotion.*'||'.*suicide.*'||) //many more root key words will be added in here in this |OR| format
{
// Send Alert Email.
var timestamp = sheet.getRange('A' + lastrow).getValue();
var studname = sheet.getRange('C' + lastrow).getValue();
var studemail = sheet.getRange('B' + lastrow).getValue();
var feelings= sheet.getRange('E' + lastrow).getValue();
var tired= sheet.getRange('F' + lastrow).getValue();
var stressed= sheet.getRange('G' + lastrow).getValue();
var studwork = sheet.getRange('H' + lastrow).getValue();
var cool = sheet.getRange('I' + lastrow).getValue();
var results = timestamp + ' \n ' + studname + ' \n ' + studemail + ' \n ' + feelings + ' \n ' + tired + ' \n ' + stressed + ' \n ' + studwork + ' \n ' + cool + ' \n ' + comments;
var emailAddress = 'my email address';
var message = 'Alert from the daily survey!\n' + results;
var subject = 'Daily Survey Alert from ' + studname;
MailApp.sendEmail(emailAddress, subject, message);
}
}```
To match a keyword, replace the
if (comments === '.*drug.*'||'.*die.*'||'.*emotion.*'||'.*suicide.*'||)
with
if(!!comments.match(/drug|die|emotion|suicide/))
I've fixed a bit your code and it seems work for me:
function checkComments() {
var sheet = SpreadsheetApp.getSheetByName('Sheet2');
var lastRow = sheet.getLastRow();
// it works faster when you grab all the row at once
var row = sheet.getRange('A'+lastRow+':J'+lastRow).getValues().flat();
var comments = row[9];
var words = ['drug','die','emotion','suicide'];
if (words.filter(w => comments.includes(w)).length == 0) return;
var emailAddress = 'your#mail.com';
var subject = row[2];
var message = row.join('\n');
MailApp.sendEmail(emailAddress, subject, message);
}
Probably it makes sense to use RegEx to search these words in comments. But I'm not sure if you're ready to dive so deep.
function doGet(e){
Logger.log("--- doGet ---");
var tag = "",
value = "";
try {
// this helps during debuggin
if (e == null){e={}; e.parameters = {tag:"test",value:"-1"};}
tag = e.parameters.tag;
value = e.parameters.value;
// save the data to spreadsheet
save_data(tag, value);
return ContentService.createTextOutput("Wrote:\n tag: " + tag + "\n value: " + value);
} catch(error) {
Logger.log(error);
return ContentService.createTextOutput("oops...." + error.message
+ "\n" + new Date()
+ "\ntag: " + tag +
+ "\nvalue: " + value);
}
}
// Method to save given data to a sheet
function save_data(tag, value){
Logger.log("--- save_data ---");
try {
var dateTime = new Date();
// Paste the URL of the Google Sheets starting from https thru /edit
// For e.g.: https://docs.google.com/..../edit
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1HYJRHfJVgZp16xYt4fipR1bH2BudhuQ4UrDhAf1rBKw/edit");
var dataLoggerSheet = ss.getSheetByName("Datalogger");
// Get last edited row from DataLogger sheet
var row = dataLoggerSheet.getLastRow() + 1;
// Start Populating the data
dataLoggerSheet.getRange("A" + row).setValue(row -1); // ID
dataLoggerSheet.getRange("B" + row).setValue(dateTime); // dateTime
dataLoggerSheet.getRange("C" + row).setValue(tag); // tag
dataLoggerSheet.getRange("D" + row).setValue(value); // value
//dataLoggerSheet.getRange("E" + row).setValue(value); // value
//dataLoggerSheet.getRange("F" + row).setValue(value); // value
// Update summary sheet
summarySheet.getRange("B1").setValue(dateTime); // Last modified date
// summarySheet.getRange("B2").setValue(row - 1); // Count
}
catch(error) {
Logger.log(JSON.stringify(error));
}
Logger.log("--- save_data end---");
}
In the example above, inside the value of "tag" there is data in the format "12345678912 | ABCDEFGHIJ". "Tag" data in column C; I want to print with the first 11 characters in column D. The "tag" data in column C; I want to print it with column E after 12 characters. How can I do that?
To see my overall objective, these two screenshots should show it.
Original Spreadsheet from Form:
enter image description here
Formatted Version of Spreadsheet:
enter image description here
Thank you in advance for your help.
You will have to manipulate the tag string in order to get the values you want.
In order to do this you will have change this:
dataLoggerSheet.getRange("C" + row).setValue(tag); // tag
To this:
dataLoggerSheet.getRange("C" + row).setValue(tag.slice(0,tag.indexOf('|')); //first part of tag
dataLoggerSheet.getRange("D" + row).setValue(tag.slice(tag.indexOf('|') + 2)); // second part of tag
dataLoggerSheet.getRange("E" + row).setValue(value); // value
Explanation
The above snippet makes use of the indexOf and slice methods from JavaScript in order to get the index of the | character in order to be able to split the tag string into two different strings.
Reference
JavaScript Array.prototype.slice();
JavaScript Array.prototype.indexOf().
I have a sheet where hyperlink is set in cell, but not through formula. When clicked on the cell, in "fx" bar it only shows the value.
I searched on web but everywhere, the info is to extract hyperlink by using getFormula().
But in my case there is no formula set at all.
I can see hyperlink as you can see in image, but it's not there in "formula/fx" bar.
How to get hyperlink of that cell using Apps Script or any formula?
When a cell has only one URL, you can retrieve the URL from the cell using the following simple script.
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var url = sheet.getRange("A2").getRichTextValue().getLinkUrl(); //removed empty parentheses after getRange in line 2
Source: https://gist.github.com/tanaikech/d39b4b5ccc5a1d50f5b8b75febd807a6
When Excel file including the cells with the hyperlinks is converted to Google Spreadsheet, such situation can be also seen. In my case, I retrieve the URLs using Sheets API. A sample script is as follows. I think that there might be several solutions. So please think of this as one of them.
When you use this script, please enable Sheets API at Advanced Google Services and API console. You can see about how to enable Sheets API at here.
Sample script:
var spreadsheetId = "### spreadsheetId ###";
var res = Sheets.Spreadsheets.get(spreadsheetId, {ranges: "Sheet1!A1:A10", fields: "sheets/data/rowData/values/hyperlink"});
var sheets = res.sheets;
for (var i = 0; i < sheets.length; i++) {
var data = sheets[i].data;
for (var j = 0; j < data.length; j++) {
var rowData = data[j].rowData;
for (var k = 0; k < rowData.length; k++) {
var values = rowData[k].values;
for (var l = 0; l < values.length; l++) {
Logger.log(values[l].hyperlink) // You can see the URL here.
}
}
}
}
Note:
Please set spreadsheetId.
Sheet1!A1:A10 is a sample. Please set the range for your situation.
In this case, each element of rowData is corresponding to the index of row. Each element of values is corresponding to the index of column.
References:
Method: spreadsheets.get
If this was not what you want, please tell me. I would like to modify it.
Hey all,
I hope this helps you save some dev time, as it was a rather slippery one to pin down...
This custom function will take all hyperlinks in a Google Sheets cell, and return them as text formatted based on the second parameter as either [JSON|HTML|NAMES_ONLY|URLS_ONLY].
Parameters:
cellRef : You must provide an A1 style cell reference to a cell.
Hint: To do this within a cell without hard-coding
a string reference, you can use the CELL function.
eg: "=linksToTEXT(CELL("address",C3))"
style : Defines the formatting of the output string.
Valid arguments are : [JSON|HTML|NAMES_ONLY|URLS_ONLY].
Sample Script
/**
* Custom Google Sheet Function to convert rich-text
* links into Readable links.
* Author: Isaac Dart ; 2022-01-25
*
* Params
* cellRef : You must provide an A1 style cell reference to a cell.
* Hint: To do this within a cell without hard-coding
* a string reference, you can use the CELL function.
* eg: "=linksToTEXT(CELL("address",C3))"
*
* style : Defines the formatting of the output string.
* Valid arguments are : [JSON|HTML|NAMES_ONLY|URLS_ONLY].
*
*/
function convertCellLinks(cellRef = "H2", style = "JSON") {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var cell = sheet.getRange(cellRef).getCell(1,1);
var runs = cell.getRichTextValue().getRuns();
var ret = "";
var lf = String.fromCharCode(10);
runs.map(r => {
var _url = r.getLinkUrl();
var _text = r.getText();
if (_url !== null && _text !== null) {
_url = _url.trim(); _text = _text.trim();
if (_url.length > 0 && _text.length > 0) {
switch(style.toUpperCase()) {
case "HTML": ret += '' + _text + '}' + lf; break;
case "TEXT": ret += _text + ' : "' + _url + '"' + lf; break;
case "NAMES_ONLY" : ret += _text + lf; break;
case "URLS_ONLY" : ret += _url + lf; break;
//JSON default : ...
default: ret += (ret.length>0?(','+ lf): '') +'{name : "' + _text + '", url : "' + _url + '"}' ; break;
}
ret += lf;
}
}
});
if (style.toUpperCase() == "JSON") ret = '[' + ret + ']';
//Logger.log(ret);
return ret;
}
Cheers,
Isaac
I tried solution 2:
var urls = sheet.getRange('A1:A10').getRichTextValues().map( r => r[0].getLinkUrl() ) ;
I got some links, but most of them yielded null.
I made a shorter version of solution 1, which yielded all the links.
const id = SpreadsheetApp.getActive().getId() ;
let res = Sheets.Spreadsheets.get(id,
{ranges: "Sheet1!A1:A10", fields: "sheets/data/rowData/values/hyperlink"});
var urls = res.sheets[0].data[0].rowData.map(r => r.values[0].hyperlink) ;
function convertSpreadsheetToPdfNonIncremental(spreadsheetId, sheetName, pdfName) {
var spreadsheet = spreadsheetId ? SpreadsheetApp.openById(spreadsheetId) : SpreadsheetApp.getActiveSpreadsheet();
spreadsheetId = spreadsheetId ? spreadsheetId : spreadsheet.getId()
var sheetId = sheetName ? spreadsheet.getSheetByName(sheetName).getSheetId() : null;
var pdfName = pdfName ? pdfName : spreadsheet.getName();
var parents = DriveApp.getFileById(spreadsheetId).getParents();
var folder = parents.hasNext() ? parents.next() : DriveApp.getRootFolder();
var url_base = spreadsheet.getUrl().replace(/edit$/,'');
var url_ext = 'export?exportFormat=pdf&format=pdf' //export as pdf
// Print either the entire Spreadsheet or the specified sheet if optSheetId is provided
+ (sheetId ? ('&gid=' + sheetId) : ('&id=' + spreadsheetId))
+ '&gid=1012506648'
+ '&id=11NMFpk15pZ12RdXUsFRN8onueG9mhZqV57xLz_YoQY8'
// following parameters are optional...
+ '&size=letter' // paper size
+ '&portrait=false' // orientation, false for landscape
+ '&scale=4' //1= Normal 100% / 2= Fit to width / 3= Fit to height / 4= Fit to Page
+ '&sheetnames=false&printtitle=false&pagenumbers=false' //hide optional headers and footers
+ '&gridlines=false' // hide gridlines
+ '&fzr=false'; // do not repeat row headers (frozen rows) on each page
var options = {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken(),
}
}
var response = UrlFetchApp.fetch(url_base + url_ext, options);
var file=DriveApp.getFileById('11NMFpk15pZ12RdXUsFRN8onueG9mhZqV57xLz_YoQY8');
var range = SpreadsheetApp.getActive().getRange('B3:C7');
var first = range.getCell(1, 1);
var last = range.getCell(5,2);
var pdfName = first.getValue() + ' Timesheet for Payroll Beginning ' + last.getDisplayValue();
var blob = response.getBlob().setName(pdfName +'.pdf');
folder.createFile(blob);
}
function convertSpreadsheetToPdfIncremental(spreadsheetId, sheetName, pdfName) {
var spreadsheet = spreadsheetId ? SpreadsheetApp.openById(spreadsheetId) : SpreadsheetApp.getActiveSpreadsheet();
spreadsheetId = spreadsheetId ? spreadsheetId : spreadsheet.getId()
var sheetId = sheetName ? spreadsheet.getSheetByName(sheetName).getSheetId() : null;
var pdfName = pdfName ? pdfName : spreadsheet.getName();
var parents = DriveApp.getFileById(spreadsheetId).getParents();
var folder = parents.hasNext() ? parents.next() : DriveApp.getRootFolder();
var url_base = spreadsheet.getUrl().replace(/edit$/,'');
var url_ext = 'export?exportFormat=pdf&format=pdf' //export as pdf
// Print either the entire Spreadsheet or the specified sheet if optSheetId1 is provided
+ (sheetId ? ('&gid=' + sheetId) : ('&id=' + spreadsheetId))
// following parameters are optional...
+ '&size=letter' // paper size
+ '&portrait=false' // orientation, false for landscape
+ '&scale=4' //1= Normal 100% / 2= Fit to width / 3= Fit to height / 4= Fit to Page
+ '&sheetnames=false&printtitle=false&pagenumbers=false' //hide optional headers and footers
+ '&gridlines=false' // hide gridlines
+ '&fzr=false'; // do not repeat row headers (frozen rows) on each page
var options = {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken(),
}
}
var response = UrlFetchApp.fetch(url_base + url_ext, options);
var file=DriveApp.getFileById('11NMFpk15pZ12RdXUsFRN8onueG9mhZqV57xLz_YoQY8');
var range = SpreadsheetApp.getActive().getRange('B3:C7');
var first = range.getCell(1, 1);
var last = range.getCell(5,2);
var pdfName = first.getValue() + ' Timesheet for Payroll Beginning ' + last.getDisplayValue();
var blob = response.getBlob().setName(pdfName +'.pdf');
folder.createFile(blob);
}
I have found, and been able to figure out the script, to convert either one workbook or all workbooks to PDF but can not find instruction/tips on how to convert more than one but no all, or exclude, workbooks when converting to PDF.
I have a Google Sheets spreadsheet that I want to convert all workbooks but one to PDF via script, and do not have the option of hiding the workbook that I don't want to convert.
Help please!