Google App Script. Retrieve emails list from the sheet - google-apps-script

In the following script I have to manually insert the email addresses. I rather get the list from the sheet to be able to update it without editing the script.
How do I retrieve a list of email addresses from the sheet (Sheet!A2:A)?
function sendReport() {
EMAIL = 'email'
URL = 'url'
+ '/export?'
+ 'format=pdf'
+ '&size=A4'
+ '&gid=id'
+ '&scale=4'
+ '&portrait=true';
SpreadsheetApp.getActive();
var response = UrlFetchApp.fetch(URL, {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()
}
});
var message = {
to: EMAIL,
subject: "subject",
body: "body",
attachments: [response.getBlob().setName('file.pdf')]
}
MailApp.sendEmail(message);
}

Is the script you expect as follows?
Modified script:
function sendReport() {
URL = 'url'
+ '/export?'
+ 'format=pdf'
+ '&size=A4'
+ '&gid=id'
+ '&scale=4'
+ '&portrait=true';
var response = UrlFetchApp.fetch(URL, {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()
}
});
// Retrieve values from Spreadsheet.
var sheet = SpreadsheetApp.getActiveSheet();
var values = sheet.getRange("A2:A" + sheet.getLastRow()).getDisplayValues();
// Send the email using the email addresses.
values.forEach(([email]) => {
if (email) {
var message = {
to: email,
subject: "subject",
body: "body",
attachments: [response.getBlob().setName('file.pdf')]
}
MailApp.sendEmail(message);
}
});
}
If you want to set the specific sheet, please modify var sheet = SpreadsheetApp.getActiveSheet(); to var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");.
Reference:
forEach()

Related

Google sheet script suddenly stops working and fails to send email attachment due to attachment authentication failure

Software: Google Sheets & Google App Script
Hi all,
I have been sending test emails to myself with attachments from my google sheet. They have been going great. Then I hop on one day and start receiving authentication errors. I have tried several different fixes but I'm still stuck. I'm not sure why it broke if I didn't change anything. Anyways, I'm changing stuff now to try and fix it.
It will let me send plain emails, but when I try to attach pdf's or xsls files, it fails. This was working great until it stopped working... Setting 'muteHttpExceptions' : true, allows the email to send, but the attachments are empty / corrupt.
Do you know of a better way to send specific sheets via email as pdf's or perhaps a way to fix this?
Code:
function SampleEmail() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var ssID = ss.getId();
var sheetgId = ss.getActiveSheet().getSheetId();
var sheetName = ss.getName();
var email = "test#gmail.com";
var subject = "Important Info!";
var body = "Test email.";
var url = "https://docs.google.com/spreadsheets/d/" + ssID + "/export?" + "format=pdf" + "&gid=" + sheetgId + "&portrait=true" + "&exportFormat=pdf";
var token = ScriptApp.getOAuthToken();
var result = UrlFetchApp.fetch(url, {
headers: {
'Authorization': 'Bearer ' + token
},
'muteHttpExceptions': false
});
var contents = result.getContent();
GmailApp.sendEmail(email, subject, body, { attachments: [{ fileName: sheetName + ".pdf", content: contents, mimeType: "application//pdf" }] });
}
Error message:
5:58:33 AM Error
Exception: Request failed for https://docs.google.com returned code 401. Truncated server response: <HTML>
<HEAD>
<TITLE>Unauthorized</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Unauthorized</H1>
<H2>Error 401</H2>
</BODY>
</HTML>
(use muteHttpExceptions option to examine full response)
SampleEmail # code.gs:108
SOLUTION: (Thank you #Amit_Singh for the advice.)
Try running this function to send your google sheet as a pdf to your google drive. This cleared the cache or something with the getOAuthToken() for me and allowed the original script to authenticate and send email attachments properly. Here is the function:
function convertSheetToPDF() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var ssID = ss.getId();
var sheetgId = ss.getActiveSheet().getSheetId();
var sheetId = sheetgId; // "2SqIXLiic6-gjI2KwQ6OIgb-erbl3xqzohRgE06bfj2c";
var spreadsheetName = "My Spreadsheet";
var destination = DriveApp.createFolder('new folder');
//var destination = DriveApp.getFolderById("1vFL98cgKdMHLNLSc542pUt4FMRTthUvL");
//var url = "https://docs.google.com/feeds/download/spreadsheets/Export?key=" + sheetId + "&exportFormat=xlsx";
var url = "https://docs.google.com/spreadsheets/d/" + ssID + "/export?" + "format=pdf" + "&gid=" + sheetgId + "&portrait=true" + "&exportFormat=pdf";
var params = {
method: "get",
headers: { "Authorization": "Bearer " + ScriptApp.getOAuthToken() },
muteHttpExceptions: false
};
var blob = UrlFetchApp.fetch(url, params).getBlob();
blob.setName(spreadsheetName + ".xlsx");
destination.createFile(blob);
}

How to I email a certain part of a spreadsheet as PDF in google apps script?

I was wondering if it was possible to specify a certain part of a Sheet to email as a pdf.
Here I have some code that emails an entire sheet(i.e. Sheet3 or Sheet 2....) Is there a way to email only a certain range as pdf(Cells A1:J13 get converted to a pdf but everything outside of that range gets left out)?
//This is a modified version of the code to keep personal data out. Sorry if some varriables
//are missing
function sendReport() {
var sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet3')
var AgentEmail = sh.getRange("B5").getValue();
let token = ScriptApp.getOAuthToken();
let spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
let spreadsheetId = spreadsheet.getId();
let sheetId = spreadsheet.getSheetByName("Sheet3").getSheetId();
let sheetUrl = "https://docs.google.com/spreadsheets/d/" + spreadsheetId + "/export?" + "format=xlsx" + "&gid=" + sheetId + "&portrait=true" + "&exportFormat=pdf";
let request = UrlFetchApp.fetch(sheetUrl, {
headers: {
'Authorization': 'Bearer ' + token
}
});
let content = request.getContent();
let message = {
to:Agentemail, cc:email1, email2, email3,
subject: "Subject",
attachments: [{
fileName: "Filename",
content: content,
mimeType: "application/pdf"
}]
}
MailApp.sendEmail(message);
spreadsheet.getSheetByName("Sheet3").activate();
}

How to rename pdf file when emailed in Google Apps Script [duplicate]

I have this script to export three separate sheets as PDF's using Google Apps Script which works fine except for the fact that the PDF's are exported with the file name of export.pdf in each case. I would like to rename them to 'Yesterday', 'Last 7 Days' and 'Last 30 Days' respectively, can anyone help me to achieve this, please?
//Menu in Google Sheet
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Dashboard')
.addItem('Email Dashboard','emailDashboard')
.addToUi();
}
//Convert dashboard to PDF and email a copy to user
function emailDashboard() {
// get sheet id
var ss = SpreadsheetApp.getActiveSpreadsheet();
var id = ss.getId();
// setup sheets
var yesterdaySheet = ss.getSheetByName('Yesterday');
var last7DaysSheet = ss.getSheetByName('Last 7 Days');
var last30DaysSheet = ss.getSheetByName('Last 30 Days');
var settingsSheet = ss.getSheetByName('Settings');
var dashboardURL = ss.getUrl() + "?usp=sharing";
// Send the PDF of the spreadsheet to this email address
// get this from the settings sheet
var email = settingsSheet.getRange(8,2).getValue();
var cc_email = settingsSheet.getRange(9,2).getValue();
var bcc_email = settingsSheet.getRange(10,2).getValue();
// Subject of email message
var subject = "Dashboard PDF generated from " + ss.getName() + " - " + new Date().toLocaleString();
// Email Body
var body = `A pdf copy of your dashboard is attached.<br><br>
To access this Google Sheet,;
<a href="` + dashboardURL + `" >click here</a>`;
// Base URL
var url = "https://docs.google.com/spreadsheets/d/" + id + "/export?";
var url_ext = 'exportFormat=pdf&format=pdf&size=A4&portrait=false&fitw=true&gid=';
// Auth value
var token = ScriptApp.getOAuthToken();
var options = {
headers: { 'Authorization': 'Bearer ' + token }
}
// helps initialize first time using the script
var driveCall = DriveApp.getRootFolder();
// create the pdf
var responseYesterday = UrlFetchApp.fetch(url + url_ext + yesterdaySheet.getSheetId(), options);
var response7Days = UrlFetchApp.fetch(url + url_ext + last7DaysSheet.getSheetId(), options);
var response30Days = UrlFetchApp.fetch(url + url_ext + last30DaysSheet.getSheetId(), options);
// send the email with the PDF attachment
GmailApp.sendEmail(email, subject, body, {
cc: cc_email,
bcc: bcc_email,
htmlBody: body,
attachments:[responseYesterday,response7Days, response30Days]
});
}
Explanation:
Just add these three lines after the pdf creation part:
var blob_Y = responseYesterday.getBlob().setName('Yesterday' + '.pdf');
var blob_L7D = response7Days.getBlob().setName('Last 7 Days' + '.pdf');
var blob_L30D = response30Days.getBlob().setName('Last 30 Days' + '.pdf');
and then change this part:
GmailApp.sendEmail(email, subject, body, {
cc: cc_email,
bcc: bcc_email,
htmlBody: body,
attachments:[blob_Y, blob_L7D, blob_L30D ]
});
Solution:
//Menu in Google Sheet
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Dashboard')
.addItem('Email Dashboard','emailDashboard')
.addToUi();
}
//Convert dashboard to PDF and email a copy to user
function emailDashboard() {
// get sheet id
var ss = SpreadsheetApp.getActiveSpreadsheet();
var id = ss.getId();
// setup sheets
var yesterdaySheet = ss.getSheetByName('Yesterday');
var last7DaysSheet = ss.getSheetByName('Last 7 Days');
var last30DaysSheet = ss.getSheetByName('Last 30 Days');
var settingsSheet = ss.getSheetByName('Settings');
var dashboardURL = ss.getUrl() + "?usp=sharing";
// Send the PDF of the spreadsheet to this email address
// get this from the settings sheet
var email = settingsSheet.getRange(8,2).getValue();
var cc_email = settingsSheet.getRange(9,2).getValue();
var bcc_email = settingsSheet.getRange(10,2).getValue();
// Subject of email message
var subject = "Dashboard PDF generated from " + ss.getName() + " - " + new Date().toLocaleString();
// Email Body
var body = `A pdf copy of your dashboard is attached.<br><br>
To access this Google Sheet,;
<a href="` + dashboardURL + `" >click here</a>`;
// Base URL
var url = "https://docs.google.com/spreadsheets/d/" + id + "/export?";
var url_ext = 'exportFormat=pdf&format=pdf&size=A4&portrait=false&fitw=true&gid=';
// Auth value
var token = ScriptApp.getOAuthToken();
var options = {
headers: { 'Authorization': 'Bearer ' + token }
}
// helps initialize first time using the script
var driveCall = DriveApp.getRootFolder();
// create the pdf
var responseYesterday = UrlFetchApp.fetch(url + url_ext + yesterdaySheet.getSheetId(), options);
var response7Days = UrlFetchApp.fetch(url + url_ext + last7DaysSheet.getSheetId(), options);
var response30Days = UrlFetchApp.fetch(url + url_ext + last30DaysSheet.getSheetId(), options);
var blob_Y = responseYesterday.getBlob().setName('Yesterday' + '.pdf');
var blob_L7D = response7Days.getBlob().setName('Last 7 Days' + '.pdf');
var blob_L30D = response30Days.getBlob().setName('Last 30 Days' + '.pdf');
GmailApp.sendEmail(email, subject, body, {
cc: cc_email,
bcc: bcc_email,
htmlBody: body,
attachments:[blob_Y, blob_L7D, blob_L30D ]
});
}

Sending Email of Multiple Google Sheets as Excel Attachment (As 3 x Sheets or 1 with Sub Sheets) from App Script

I am trying to send 3 x Sheets from a Google Sheet using App Script. Following code is working perfectly for 1 Sheet, but when i try to sent 3 Sheets, it not working.
function sendExcel() {
var url = "https://docs.google.com/spreadsheets/d/"+SpreadsheetApp.getActiveSpreadsheet().getId()+"/export"+"?format=xlsx&"+"gid="+SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getSheetId();
var url1 = "https://docs.google.com/spreadsheets/d/"+SpreadsheetApp.getActiveSpreadsheet().getId()+"/export"+"?format=xlsx&"+"gid="+SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2").getSheetId();
var url2 = "https://docs.google.com/spreadsheets/d/"+SpreadsheetApp.getActiveSpreadsheet().getId()+"/export"+"?format=xlsx&"+"gid="+SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet3").getSheetId();
var params = {method:"GET",headers:{"authorization":"Bearer "+ ScriptApp.getOAuthToken()}};
var blob = UrlFetchApp.fetch(url, url1, url2, params).getBlob().setName("Orders.xlsx");
var message = {
to: "email#domain.com",
cc: "email#domain.com",
subject: "My Email Subject",
body: "Hi Team, details....",
name: "My Name",
attachments: [blob]
}
MailApp.sendEmail(message);
}
Can someone please guide me on correct code for sending 3 / multiple sheets as attachment (As 1 Excel file or 3x Separate Attached Excel Files)?
The main problem with your code is that the UrlFetchApp.fetch() method doesn't take multiple URLs so you have to export each sheet separately.
There's probably a more elegant solution to combine the blobs into a single spreadsheet file but a quick fix to your code to send the three files separately would be the following:
var url = "https://docs.google.com/spreadsheets/d/"+SpreadsheetApp.getActiveSpreadsheet().getId()+"/export"+"?format=xlsx&"+"gid="+SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getSheetId();
var url1 = "https://docs.google.com/spreadsheets/d/"+SpreadsheetApp.getActiveSpreadsheet().getId()+"/export"+"?format=xlsx&"+"gid="+SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2").getSheetId();
var url2 = "https://docs.google.com/spreadsheets/d/"+SpreadsheetApp.getActiveSpreadsheet().getId()+"/export"+"?format=xlsx&"+"gid="+SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet3").getSheetId();
var params = {method:"GET",headers:{"authorization":"Bearer "+ ScriptApp.getOAuthToken()}};
var blob = UrlFetchApp.fetch(url, params).getBlob().setName("Orders.xlsx");
var blob1 = UrlFetchApp.fetch(url1, params).getBlob().setName("Orders 2.xlsx");
var blob2 = UrlFetchApp.fetch(url2, params).getBlob().setName("Orders 3.xlsx");
var message = {
to: "email#domain.com",
cc: "email#domain.com",
subject: "My Email Subject",
body: "Hi Team, details....",
name: "My Name",
attachments: [blob, blob1, blob2]
}
MailApp.sendEmail(message);
}
I think this will send 3 separate messages each with one attachment:
function sendThree() {
var url0 = "https://docs.google.com/spreadsheets/d/" + SpreadsheetApp.getActiveSpreadsheet().getId() + "/export" + "?format=xlsx&" + "gid=" + SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getSheetId();
var url1 = "https://docs.google.com/spreadsheets/d/" + SpreadsheetApp.getActiveSpreadsheet().getId() + "/export" + "?format=xlsx&" + "gid=" + SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2").getSheetId();
var url2 = "https://docs.google.com/spreadsheets/d/" + SpreadsheetApp.getActiveSpreadsheet().getId() + "/export" + "?format=xlsx&" + "gid=" + SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet3").getSheetId();
[url0, url1, url2].forEach((url,i) => {
var params = { method: "GET", headers: { "authorization": "Bearer " + ScriptApp.getOAuthToken() } };
var blob = UrlFetchApp.fetch(url,params).getBlob().setName(`Orders${i+1}.xlsx`);
var message = {
to: "email#domain.com",
cc: "email#domain.com",
subject: "My Email Subject",
body: "Hi Team, details....",
name: "My Name",
attachments: [blob]
}
MailApp.sendEmail(message);
});
}
I think this will send one email with three attachmentments:
function sendOneEmailWithThreeAttachments() {
var url0 = "https://docs.google.com/spreadsheets/d/" + SpreadsheetApp.getActiveSpreadsheet().getId() + "/export" + "?format=xlsx&" + "gid=" + SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getSheetId();
var url1 = "https://docs.google.com/spreadsheets/d/" + SpreadsheetApp.getActiveSpreadsheet().getId() + "/export" + "?format=xlsx&" + "gid=" + SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2").getSheetId();
var url2 = "https://docs.google.com/spreadsheets/d/" + SpreadsheetApp.getActiveSpreadsheet().getId() + "/export" + "?format=xlsx&" + "gid=" + SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet3").getSheetId();
var urlA = [];
[url0, url1, url2].forEach((url, i) => {
var params = { method: "GET", headers: { "authorization": "Bearer " + ScriptApp.getOAuthToken() } };
urlA.push(UrlFetchApp.fetch(url, params).getBlob().setName(`Orders${i + 1}.xlsx`));
});
var message = {
to: "email#domain.com",
cc: "email#domain.com",
subject: "My Email Subject",
body: "Hi Team, details....",
name: "My Name",
attachments: urlA
}
MailApp.sendEmail(message);
}

Export multiple sheets in a single PDF

Just wondering how I would be able to export a PDF file to contain multiple sheets, but not all in the workbook. I've been only been able to send single sheets as separate PDF attachments. Any insight on this would be great.
var url = ss.getUrl(); //gets url
url = url.replace(/edit/,'');
var url_ext = 'export?exportFormat=pdf&format=pdf' +
'&size=letter' +
'&portrait=false' +
'&fitw=true' +
'&sheetnames=false&printtitle=false' +
'&pagenumbers=true&gridlines=false' +
'&fzr=true' +
'&gid=GID'
var token = ScriptApp.getOAuthToken();
var response = UrlFetchApp.fetch(url + url_ext, {
headers: {
'Authorization': 'Bearer ' + token
}
});
var blob = response.getBlob().setName(sheet.getName() + '.pdf');
A guide has been written about this in this blog post by Andrew Roberts, the source code from that post is as follows:
function convertSpreadsheetToPdf(email, 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))
// following parameters are optional...
+ '&size=letter' // paper size
+ '&portrait=true' // orientation, false for landscape
+ '&fitw=true' // fit to width, false for actual size
+ '&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 blob = response.getBlob().setName(pdfName + '.pdf');
folder.createFile(blob);
if (email) {
var mailOptions = {
attachments:blob
}
MailApp.sendEmail(
email,
"Here is a file named " + pdfName,
"Please let me know if you have any questions or comments.",
mailOptions);
}
} // convertSpreadsheetToPdf()
function test() {
var TEST_EMAIL = 'your email address'
// Create a PDF containing all the tabs in the active spreadsheet, name it
// after the spreadsheet, and email it
convertSpreadsheetToPdf(TEST_EMAIL)
// Create a PDF containing all the tabs in the spreadsheet specified, name it
// after the spreadsheet, and email it
convertSpreadsheetToPdf(TEST_EMAIL, '1r9INcnsyvSQmeduJWVYAvznOOYei9jeAjsy0acA3G1k')
// Create a PDF just containing the tab 'Sheet2' in the active spreadsheet, specify a name, and email it
convertSpreadsheetToPdf(TEST_EMAIL, null, 'Sheet2', 'PDF 3')
}