Script is clearing data too early, does anyone know why? - email

So I'm working on a project in Google Sheets, using scripting, that will eventually do the following;
Firstly, based on a name in a Cell , find the last 9 entries for that person in form responses.
It then arranges that data in a way that I need and writes it to a sheet, within my spreadsheet
The last part of the script (not my own work, but something i found here)
Script I found online
I've tried to adapt for my needs, not quite there yet. Creates a PDF, saves it in google drive then emails it.
This part requires a bit more work, as I want to specify what the PDF is called using the name and date. Also I'd like to specify where it's saved in google. Lastly the script only produces one PDF. Would like to eventually duplicate the script so I can either create 1 PDF or create them in batches. Will possibly post about these later, if I get stuck.
So anyways that is the overview.
Currently the script works and can query the data I want, write it to a sheet, save it to drive as PDF and email it to a single hard-coded email address. Awesomeness.
But I then tried to add a function called clearRanges which would clear out the template sheet before writing data. I used name ranges to define the 3 sections to clear. But since introducing it, and i've tried it in various parts of my script. I'm getting blank PDF's in my drive and by email.
It's like it's not waiting for the PDF to be created or email to be sent before clearing data. I've tried to put it at the start of my script too, but same thing. Got no idea why.
I was playing around with lock and waitlock as a possible solution, but it didn't seem to help.
If anyone can help out, I'd appreciate it.
function getAgentName() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
Browser.msgBox("Please go to the sheet called PDF Creator, in cell A2, choose the agent you wish to create a PDF for");
var sheet = ss.getSheetByName("PDF Creator");
var range = sheet.getRange("A2")
var value = range.getValue();
if (value == 0) {
Browser.msgBox("You need to go to the sheet named PDF Creator and put an agent name in cell A2");
} else {
getAgentData(value);
}
}
function getAgentData(value) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = ss.getSheetByName("Form responses 1")
var sourceRange = sourceSheet.getDataRange();
var sourceValues = sourceRange.getValues();
var agentData = [];
var commentsData = [];
for (i = 0; i < sourceValues.length; i++) {
// Defines the data layout for PDF.
var agentName = sourceValues[i][2];
var dateTime = sourceValues[i][3];
var callType = sourceValues[i][7];
var opening = sourceValues[i][8];
var rootCause = sourceValues[i][9];
var rootFix = sourceValues[i][10];
var process = sourceValues[i][11];
var consumer = sourceValues[i][12];
var control = sourceValues[i][13];
var wrapup = sourceValues[i][14];
var dpa = sourceValues[i][15];
var score = sourceValues[i][22];
var comments = sourceValues[i][16];
var agentRow = [dateTime, callType, opening, rootCause, rootFix, process, consumer, control, wrapup, dpa, score];
var commentsRow = [dateTime, comments];
if (agentName == value && agentData.length < 9) {
agentData.push(agentRow)
commentsData.push(commentsRow)
}
}
agentData.sort(function (a, b) {
return b[0] - a[0]
});
commentsData.sort(function (a, b) {
return b[0] - a[0]
});
var destSheet = ss.getSheetByName("AgentPDF");
destSheet.getRange("A1").setValue(value + "'s Quality Score card");
var range = destSheet.getRange(6, 1, agentData.length, agentData[0].length);
range.setValues(agentData);
var commentRange = destSheet.getRange(18, 1, commentsData.length, commentsData[0].length);
commentRange.setValues(commentsData);
emailSpreadsheetAsPDF();
}
/* Send Spreadsheet in an email as PDF, automatically */
function emailSpreadsheetAsPDF() {
// Send the PDF of the spreadsheet to this email address
var email = "firstname.lastname#domain.co.uk";
// Subject of email message
// The date time string can be formatted in your timezone using Utilities.formatDate method
var subject = "PDF Reports - " + (new Date()).toString();
// Get the currently active spreadsheet URL (link)
// Or use SpreadsheetApp.openByUrl("<<SPREADSHEET URL>>");
var ss = SpreadsheetApp.getActiveSpreadsheet();
// Email Body can be HTML too with your logo image - see ctrlq.org/html-mail
var body = "PDF generated using code at ctrlq.org from sheet " + ss.getName();
var url = ss.getUrl();
url = url.replace(/edit$/, '');
/* Specify PDF export parameters
// From: https://code.google.com/p/google-apps-script-issues/issues/detail?id=3579
exportFormat = pdf / csv / xls / xlsx
gridlines = true / false
printtitle = true (1) / false (0)
size = legal / letter/ A4
fzr (repeat frozen rows) = true / false
portrait = true (1) / false (0)
fitw (fit to page width) = true (1) / false (0)
add gid if to export a particular sheet - 0, 1, 2,..
*/
var url_ext = 'export?exportFormat=pdf&format=pdf' // export as pdf
+ '&size=a4' // paper size
+ '&portrait=1' // orientation, false for landscape
+ '&fitw=true&source=labnol' // fit to 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=928916939'; // the sheet's Id
var token = ScriptApp.getOAuthToken();
// var sheets = ss.getSheets();
//make an empty array to hold your fetched blobs
var blobs = [];
// for (var i=0; i<sheets.length; i++) {
// Convert individual worksheets to PDF
// var response = UrlFetchApp.fetch(url + url_ext + sheets[i].getSheetId(), {
var response = UrlFetchApp.fetch(url + url_ext, {
headers: {
'Authorization': 'Bearer ' + token
}
});
//convert the response to a blob and store in our array
blobs[0] = response.getBlob().setName("Tester " + '.pdf');
// }
//create new blob that is a zip file containing our blob array
// var zipBlob = Utilities.zip(blobs).setName(ss.getName() + '.zip');
var test = DriveApp.createFile(blobs[0]);
//optional: save the file to the root folder of Google Drive
DriveApp.createFile(test);
// Define the scope
Logger.log("Storage Space used: " + DriveApp.getStorageUsed());
// If allowed to send emails, send the email with the PDF attachment
if (MailApp.getRemainingDailyQuota() > 0)
var lock = LockService.getScriptLock();
GmailApp.sendEmail(email, subject, body, {
attachments: [test]
});
lock.waitLock(20000);
lock.releaseLock();
clearRanges();
}
function clearRanges() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.getRangeByName('Header').clearContent();
ss.getRangeByName('Scores').clearContent();
ss.getRangeByName('Comments').clearContent();
}

Can you try adding SpreadsheetApp.flush();
around line 60 before calling emailSpreadsheetAsPDF();
SpreadsheetApp.flush()
commentRange.setValues(commentsData);
SpreadsheetApp.flush();
emailSpreadsheetAsPDF();
I've faced a similar problem before and this worked.

Related

Sending Email Based on Cell Value

The email function works fine, but the code has the following error:
SyntaxError: Unexpected end of input (line 90, file "Code.gs") (last line) when the function checkValue was added.
Basically, we want the email to send automatically when D2 is edited. We are hoping this will eliminate the need to allow permissions to send email every time a template is copied by an aid.
function checkValue () {
var check = sheet.getRange("D2").getValue();
var rangeEdit =e.range.getA1Notation();
if(rangeEdit == "D2") {
{
function email(checkValue) {
// Send the PDF of the spreadsheet to this email address
// Get the currently active spreadsheet URL (link)
// Or use SpreadsheetApp.openByUrl("<<SPREADSHEET URL>>");
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("ClassA")
var lrow = sheet.getLastRow()
var name = sheet.getRange("E4").getValue();
var aid = sheet.getRange("E3").getValue();
var email = sheet.getRange("E5").getValue();
var pemail = sheet.getRange("E2").getValue();
var period = sheet.getRange("C1").getValue();
var og= sheet.getRange("D2").getValue();
// Subject of email message
var subject = "Grade Summary | " + og +"- " + period;
// Email Body can be HTML too with your logo image - see ctrlq.org/html-mail
var body = "Hi " + name + ", "+ "<br><br> Please find the grade summary attached for " + period + ". <br><br> Let us know if you have any questions.<br><br> Thank you,<br><br> " + aid;
var aliases = GmailApp.getAliases()
Logger.log(aliases); //returns the list of aliases you own
Logger.log(aliases[0]); //returns the alias located at position 0 of the aliases array
// 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=True' // orientation, false for landscape
+ '&fitw=true' // 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();
//make an empty array to hold your fetched blobs
var blobs;
// Convert your specific sheet to blob
var response = UrlFetchApp.fetch(url + url_ext + sheet.getSheetId(), {
headers: {
'Authorization': 'Bearer ' + token
}
});
//convert the response to a blob and store in our array
blobs = response.getBlob().setName(sheet.getName() + '.pdf');
// Define the scope
Logger.log("Storage Space used: " + DriveApp.getStorageUsed());
MailApp.sendEmail(email, subject, body, {
htmlBody: body,
name:'class',
bcc: aid,
noReply: true,
attachments:[blobs]
});
}
Basically, we want the email to send automatically when D2 is edited.
var rangeEdit =e.range.getA1Notation();
From what I see here it looks like you are trying to send an Email when the cell is changed, probably by using onEdit trigger.
You can't do that.
OnEdit belongs to simple triggers. Simple triggers can't call services that require authorization. Check here https://developers.google.com/apps-script/guides/triggers the Restrictions section.
If I'm wrong with what are you trying to do, please edit your post with the code, since "Carlos M" wrote in his reply that it can't compile.
Your code does not have enough closing brackets to terminate the function checkValue, thus it returns a syntax error.
Since your intent is to check the value first before sending the email, it is better if you separate the email function and call it from checkValue instead of enclosing it in an if statement. The parameter is not needed as well.
Also since you indicated that you need to send an email, you need an installable trigger. Create a trigger using the script service by running createSpreadsheetEditTrigger(), which will then run checkValue().
function createSpreadsheetEditTrigger() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ScriptApp.newTrigger('checkValue')
.forSpreadsheet(ss)
.onEdit()
.create();
}
function checkValue(e) {
var rangeEdit = e.range.getA1Notation();
if(rangeEdit == "D2") {
email();
}
}
function email() {
// Send the PDF of the spreadsheet to this email address
// Get the currently active spreadsheet URL (link)
// Or use SpreadsheetApp.openByUrl("<<SPREADSHEET URL>>");
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("ClassA")
var lrow = sheet.getLastRow()
var name = sheet.getRange("E4").getValue();
var aid = sheet.getRange("E3").getValue();
var email = sheet.getRange("E5").getValue();
var pemail = sheet.getRange("E2").getValue();
var period = sheet.getRange("C1").getValue();
var og= sheet.getRange("D2").getValue();
// Subject of email message
var subject = "Grade Summary | " + og +"- " + period;
// Email Body can be HTML too with your logo image - see ctrlq.org/html-mail
var body = "Hi " + name + ", "+ "<br><br> Please find the grade summary attached for " + period + ". <br><br> Let us know if you have any questions.<br><br> Thank you,<br><br> " + aid;
var aliases = GmailApp.getAliases()
Logger.log(aliases); //returns the list of aliases you own
Logger.log(aliases[0]); //returns the alias located at position 0 of the aliases array
// 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=True' // orientation, false for landscape
+ '&fitw=true' // 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();
//make an empty array to hold your fetched blobs
var blobs;
// Convert your specific sheet to blob
var response = UrlFetchApp.fetch(url + url_ext + sheet.getSheetId(), {
headers: {
'Authorization': 'Bearer ' + token
}
});
//convert the response to a blob and store in our array
blobs = response.getBlob().setName(sheet.getName() + '.pdf');
// Define the scope
Logger.log("Storage Space used: " + DriveApp.getStorageUsed());
MailApp.sendEmail(email, subject, body, {
htmlBody: body,
name:'class',
bcc: aid,
noReply: true,
attachments:[blobs]
});
}
References:
Installable Triggers | Apps Script

onFormSubmit(e) I need to sum 4 columns and output to a PDF

This seems like a simple problem, add 4 Form Event columns(Cost 1, Cost 2, Cost 3, Cost 4) and output calculated 'Total' to a PDF via email utilizing a template. I have no problem getting the Event(e) data to the template and sent via email but cannot get the total. I've tried many different Google App Scripts from this site to no avail. Currently, I have a separate sheet called 'Total' and created an array that captures the Event data columns and displays exactly what I want but I cannot get it to the template, problem code may be on line 20. I've included links to the template as well as the Spreadsheet and the Google App Script
// Get template from Google Docs and name it
var docTemplate = "1Ti1n71wpA-U5X9yLqSIfLC9VXqcxOGGsZQhYq0ZwJX4"; // *** replace with your template ID ***
var docName = "Calculate the total";
// When Form Gets submitted
function onFormSubmit(e) {
var name = "Rick"
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Total'); //Get 'Total' sheet
var row = sheet.getLastRow(); //Get 'Total' last row
//Get information from form and set as variables
var todaysDate = Utilities.formatDate(new Date(), "CST", "MM/dd/yyyy, hh:mm");
var email_address = "MyEmail address";
var cost1 = e.values[1];
var cost2 = e.values[2];
var cost3 = e.values[3];
var cost4 = e.values[4];
var total = sheet.getRange(row, [1]).getValue(); //Is this the problem?
// Logger.log(e.namedValues);
// Get document template, copy it as a new temp doc, and save the Documents ID
var copyId = DriveApp.getFileById (docTemplate)
.makeCopy(docName + ' for '+ name)
.getId();
// Open the temporary document
var copyDoc = DocumentApp.openById(copyId);
// Get the documents body section
var copyBody = copyDoc.getActiveSection();
// Replace place holder keys,in our google doc template
copyBody.replaceText('<<name>>', name);
copyBody.replaceText('<<cost1>>', cost1);
copyBody.replaceText('<<cost2>>', cost2);
copyBody.replaceText('<<cost3>>', cost3);
copyBody.replaceText('<<cost4>>', cost4);
copyBody.replaceText('<<total>>', total);
copyBody.replaceText('<<timeStamp>>', todaysDate);
// Save and close the temporary document
copyDoc.saveAndClose();
// Convert temporary document to PDF by using the getAs blob conversion
var pdf = DriveApp.getFileById(copyId).getAs("application/pdf");
// Attach PDF and send the email
var subject = "Your Total Cost Project Script";
var body = name + ", here is the total cost for your project ";
MailApp.sendEmail(email_address, subject, body, {htmlBody: body, attachments: pdf});
// Delete temp file
DriveApp.getFileById(copyId).setTrashed(true);
}
Spreadsheet - https://docs.google.com/spreadsheets/d/144t33X98eZIAH2k5hCA--fFeUzmJCGefKI7lC1EE4Xc/edit?usp=sharing
Template - https://docs.google.com/document/d/1Ti1n71wpA-U5X9yLqSIfLC9VXqcxOGGsZQhYq0ZwJX4/edit?usp=sharing

Unable to add inline image to email in google apps script

I'm new to Google Apps script and am trying to add an image inline to an automated response email.
The auto reply works perfectly, the main text of the email formats well in plain text and html.
the problem i'm facing is that the image does not appear.
my code:
// This constant is written in column Y for rows for which an email
// has been sent successfully.
var EMAIL_SENT = 'EMAIL_SENT';
/**
* Sends non-duplicate emails with data from the current spreadsheet.
*/
function sendEmails2() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
SpreadsheetApp.setActiveSheet(sheet.getSheetByName('Data'))
var startRow = 2; // First row of data to process
// Fetch the range
var dataRange = sheet.getRange("L2:L1000")
var dataRange2 = sheet.getRange("K2:K1000")
var dataRange3 = sheet.getRange("O2:O1000")
var dataRange4 = sheet.getRange("Y2:Y1000")
var dataRange5 = sheet.getRange("B2:B1000")
// Fetch values for each row in the Range.
var data = dataRange.getValues();
var data2 = dataRange2.getValues();
var data3 = dataRange3.getValues();
var data4 = dataRange4.getValues();
var data5 = dataRange5.getValues();
for (var i = 0; i < data.length; ++i) {
var yesno = data2[i]
if(yesno == "Yes"){
var TFlogoUrl = "https://drive.google.com/openid=1nzmvP_zzOms1HiBoFCsVLFjDM6ZzM287";
var TFlogoBlob = UrlFetchApp
.fetch(TFlogoUrl)
.getBlob()
.setName("TFlogoBlob");
var emailAddress = data[i];
var ShipID = data3[i];
var cmdrID = data5[i];
var TFmsg = "Hi " + cmdrID + ",/n /nThank you for signing up to The Fatherhoods Lost Souls Expedition./n /nYour unique Ship ID is: " + ShipID + "/n /nWe look forward to seeing you on the expedition CMDR!/n /nFly Safe,/nThe Lost Souls Expedition team.";
var htmlTFmsg = "Hi " + cmdrID + ",<br> <br>Thank you for signing up to The Fatherhoods Lost Souls Expedition.<br> <br>Your unique Ship ID is: " + ShipID + "<br> <br>We look forward to seeing you on the expedition CMDR!<br> <br>Fly Safe,<br>The Lost Souls Expedition team.<br><img src='cid:TFlogo'>";
emailSent = data4[i]; // email sent (column Y)
if (emailSent != EMAIL_SENT) { // Prevents sending duplicates
var subject = "Lost Souls Expedition Sign up confirmation";
MailApp.sendEmail(emailAddress,subject,TFmsg,{
htmlBody: htmlTFmsg,
inlineImage:
{
TFlogo:TFlogoBlob
}
});
sheet.getRange("Y" + (startRow + i)).setValue(EMAIL_SENT);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
}
}
How about this modification?
Modification points:
You cannot retrieve the file blob from this URL var TFlogoUrl = "https://drive.google.com/openid=1nzmvP_zzOms1HiBoFCsVLFjDM6ZzM287";. If you want to retrieve the file blob from URL, please use var TFlogoUrl = "http://drive.google.com/uc?export=view&id=1nzmvP_zzOms1HiBoFCsVLFjDM6ZzM287";. 1nzmvP_zzOms1HiBoFCsVLFjDM6ZzM287 is the file ID.
As an another method, from the file ID, it is found that the values of getSharingAccess() and getSharingPermission() are ANYONE_WITH_LINK and VIEW, respectively. So you can also retrieve the blob using var TFlogoBlob = DriveApp.getFileById("1nzmvP_zzOms1HiBoFCsVLFjDM6ZzM287").getBlob().setName("TFlogoBlob");. I recommend this.
When you want to use the inline image to email, please modify from inlineImage to inlineImages.
The script which reflected above points is as follows.
Modified script:
Please modify your script as follows.
From:
var TFlogoUrl = "https://drive.google.com/openid=1nzmvP_zzOms1HiBoFCsVLFjDM6ZzM287";
var TFlogoBlob = UrlFetchApp.fetch(TFlogoUrl).getBlob().setName("TFlogoBlob");
To:
var id = "1nzmvP_zzOms1HiBoFCsVLFjDM6ZzM287";
var TFlogoBlob = DriveApp.getFileById(id).getBlob().setName("TFlogoBlob");
And
From:
inlineImage: {TFlogo:TFlogoBlob}
To:
inlineImages: {TFlogo:TFlogoBlob}
References:
sendEmail(recipient, subject, body, options)
If I misunderstand your question, please tell me. I would like to modify it.

Send mail with attached PDF to recipient after confirmation

I have to edit a Google Spreadsheet file daily. When I'm finished, I would like to send a message to people, notifying them that I'm done. Attached to that notification mail, I want to send them one specific sheet (called Report), as a PDF.
I found this option which sends email (and is working fine):
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 2; // Number of rows to process
// Fetch the range of cells A2:B3
var dataRange = sheet.getRange(startRow, 1, numRows, 2)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
var emailAddress = row[0]; // First column
var message = row[1]; // Second column
var subject = "Sending emails from a Spreadsheet";
MailApp.sendEmail(emailAddress, subject, message);
}
}
Is there a way to add the specific sheet as a PDF?
A secondary question: How can I create some sort of button in the spreadsheet ("Send now"), to let me easily send this email, and so I don't have to open the script editor every time?
Menu-driven on-demand operation
Within the Google Sheets user interface, a menu item would be a natural way to set this up to be run on-demand.1 A good resource for learning how to do this yourself is Google's Quickstart: Macros, Menus, and Custom Functions.
From that tutorial, here's the code that would add a "Send Report" menu item to your spreadsheet, which would call a sendReport_() function when selected:
/**
* A special function that runs when the spreadsheet is open, used to add a
* custom menu to the spreadsheet.
*/
function onOpen() {
var spreadsheet = SpreadsheetApp.getActive();
var menuItems = [
{name: 'Send Report', functionName: 'sendReport_'}
];
spreadsheet.addMenu('Custom', menuItems);
}
sendReport_() function
Let's assume we have a getPdfBlob() function, that will return a blob suitable for attaching to an email. With that taken care of, here is all sendReport_() needs to do:
// From https://stackoverflow.com/a/37149036/1677912
function sendReport_() {
// Configuration parameters; customize as you wish
var sheetName = "Report";
var subject = "Email subject line";
var recipients = "user1#example.com, user2#example.com";
var htmlMessage = "Greetings,<br/><br/>"
+ "Please find today's report attached as a PDF.<br/><br/>"
+ "Cheers,<br/><br/>Paranoia";
// Get the IDs of the spreadsheet & sheet-of-interest
var ss = SpreadsheetApp.getActive();
var sheetId = ss.getSheetByName(sheetName).getSheetId();
// Retrieve the PDF blob
var pdfBlobArray = getPdfBlobs(ss.getId(),sheetId);
// Send the email + attachment
MailApp.sendEmail(recipients,subject,"Report attached.", {
htmlBody: htmlMessage,
attachments: pdfBlobArray
});
}
getPdfBlobs() utility function
A utility to generate a PDF of a spreadsheet appears in Convert all sheets to PDF with Google Apps Script.
That can be adapted to return a blob containing the PDF of the single sheet you're after.
You must enable the Advanced Drive Service through "Resources > Advanced Drive Services...", and the developer console. (See this for more info.)
Note: There is some grotty customization of the PDF output supported by editing URL parameters that are embedded inside this function.
/**
* Get one or all sheets in a spreadsheet as PDF file blobs.
*
* From: https://stackoverflow.com/a/37149036/1677912
* Adapted from https://stackoverflow.com/a/30492812/1677912
*
* #param {String} optSSId (optional) ID of spreadsheet to export.
* If not provided, script assumes it is
* sheet-bound and opens the active spreadsheet.
* #param {String} optSheetId (optional) ID of single sheet to export.
* If not provided, all sheets will export.
*/
function getPdfBlobs( optSSId, optSheetId ) {
// If a sheet ID was provided, open that sheet, otherwise assume script is
// sheet-bound, and open the active spreadsheet.
var ss = (optSSId) ? SpreadsheetApp.openById(optSSId) : SpreadsheetApp.getActiveSpreadsheet();
// Get URL of spreadsheet, and remove the trailing 'edit'
var url = ss.getUrl().replace(/edit$/,'');
// Get array of all sheets in spreadsheet
var sheets = ss.getSheets();
// Loop through all sheets, generating PDF blobs.
var blobArray = [];
for (var i=0; i<sheets.length; i++) {
var sheet = sheets[i];
// If provided a optSheetId, only save it.
if (optSheetId && optSheetId !== sheet.getSheetId()) continue;
//additional parameters for exporting the sheet as a pdf
var url_ext = 'export?exportFormat=pdf&format=pdf' //export as pdf
+ '&gid=' + sheet.getSheetId() //the sheet's Id
// 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 + url_ext, options);
var blob = response.getBlob().setName(ss.getName() + ' - ' + sheet.getName() + '.pdf');
// Add blob to our array
blobArray.push(blob);
}
// Return array of PDF blobs
return blobArray;
}
/**
* Dummy function for API authorization only.
* From: https://stackoverflow.com/a/37172203/1677912
*/
function forAuth_() {
DriveApp.getFileById("Just for authorization"); // https://code.google.com/p/google-apps-script-issues/issues/detail?id=3579#c36
}
1This could be further extended to be an add-on, so that the script would not need to be attached to a specific spreadsheet.

Google Apps Script: read text from a .txt file

After taking a look at the provided tutorial for sending emails from a spreadsheet with Google Apps Script, I modified the given code with aims to be able to send the set of emails out with attachments as well.
It works well enough, even with a couple quirks from the limitations of Google Apps Script (the files have to be in the Google Drive, and all files in the Google Drive with whichever name is appropriate are taken from all folders in the drive).
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 1; // Number of rows to process
// Fetch the range of cells A2:C3
var dataRange = sheet.getRange(startRow, 1, numRows, 3)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
var emailAddress = row[0]; // First column
var message = row[1]; // Second column
var attachment = row[2]; // File name provided.
var subject = "Mass Email";
var files = DriveApp.getFilesByName(attachment); // Get all files with name.
var blobs = []; // Array for attachment.
// Move files into blobs
while (files.hasNext()) {
var file = files.next();
blobs.push(file.getAs(MimeType.PLAIN_TEXT));
}
MailApp.sendEmail(emailAddress, subject, message, {
attachments: blobs, // add attachments
cc: "extra#email.com" // CC to employer
});
}
}
After I first used it, however, I learned that I need to send the files not as attachments, but as the message body of the emails, among some other changes (this is for work). That is, I will only ever email one 'attachment' at a time to each email, and instead of that file being an attachment, its content should be copied over to the message of the email. The attachments are currently text files, and I'd like them to stay that way, but it isn't the most vital thing.
I cannot determine a way to do this with Google Apps Script. Is this possible, or will I have to have a different way of emailing these files? (Hopefully not by hand.)
Try this. It's more faster and simpler.
var docContent = file.getBlob().getDataAsString();
Logger.log(docContent);
as mentioned in my last comment, converting your .txt files to Google documents makes it easy to achieve.
see below (suggestion)
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 1; // Number of rows to process
// Fetch the range of cells A2:C3
var dataRange = sheet.getRange(startRow, 1, numRows, 3)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
Logger.log(row)
var emailAddress = row[0]; // First column
var message = row[1]; // Second column
var attachment = row[2]; // File name provided.
var subject = "Mass Email";
var files = DriveApp.getFilesByName(attachment); // Get all files with name.
while (files.hasNext()) {
var file = files.next();
var Id = file.getId();
var content = DocumentApp.openById(Id).getBody().getText();
Logger.log(content)
MailApp.sendEmail(emailAddress, subject, message+'\n'+content)
}
}
}