Google Scripts not skipping rows - google-apps-script

Pretty new to using google scripts, so forgive me if I'm doing something silly.
I am trying to write a program to take a large spreadsheet of data and fill an invoice template I have created. I have successfully done this in the past, but now when I tried to apply the app to a new spreadsheet of data, it is no longer functioning properly.
The problem is because the sheet is so large, the scripts times out, then when I go to restart the script, it starts again all the way at the beginning instead of starting where it left off. Originally the function was set to write the URL of the new invoice in the last column of spreadsheet, and the function would skip any rows with entries in that column. This was not happening, so to simplify I added another row that once the invoice is created, the word "DONE" is entered, and then I tried to set it up to skip any row with "DONE" in that column, this still is not working.
Any ideas on how I can get this to work?
function onOpen() {
const ui = SpreadsheetApp.getUi();
const menu = ui.createMenu('AutoFill Docs');
menu.addItem('Create New Docs', 'createNewGoogleDocs')
menu.addToUi();
}
function createNewGoogleDocs() {
//This value should be the id of your document template that we created in the last step
const googleDocTemplate = DriveApp.getFileById('1yXfcXTESCHqKsfMcgkhYJ9MdVwYoLYPhH1MRv4RyPk0');
//This value should be the id of the folder where you want your completed documents stored
const destinationFolder = DriveApp.getFolderById('1TXEumNJXfgFzPtKLBOAKJBXG-yNnjseQ')
//Here we store the sheet as a variable
const sheet = SpreadsheetApp
.getActiveSpreadsheet()
.getSheetByName('Export Worksheet')
//Now we get all of the values as a 2D array
const rows = sheet.getDataRange().getValues();
//Start processing each spreadsheet row
rows.forEach(function(row, index){
//Here we check if this row is the headers, if so we skip it
if (index === 0) return;
//Here we check if a document has already been generated by looking at 'Document Link', if so we skip it
if (row[31]=== 'DONE') return;
//Using the row data in a template literal, we make a copy of our template document in our destinationFolder
const copy = googleDocTemplate.makeCopy(`${row[4]}, ${row[0]} Invoice` , destinationFolder)
//Once we have the copy, we then open it using the DocumentApp
const doc = DocumentApp.openById(copy.getId())
//All of the content lives in the body, so we get that for editing
const body = doc.getBody();
//In this line we do some friendly date formatting, that may or may not work for you locale
const friendlyDate = new Date(row[3]).toLocaleDateString();
//In these lines, we replace our replacement tokens with values from our spreadsheet row
body.replaceText('{{Full Address}}', row[4]);
body.replaceText('{{unit}}', row[5]);
body.replaceText('{{Total}}', row[15]);
body.replaceText('{{Account Num}}', row[2]);
body.replaceText('{{Owner 1}}', row[6]);
body.replaceText('{{Owner 2}}', row[7]);
body.replaceText('{{CO Name}}', row[17]);
body.replaceText('{{St Address}}', row[20]);
body.replaceText('{{Address 1}}', row[18]);
body.replaceText('{{City}}', row[21]);
body.replaceText('{{State}}', row[22]);
body.replaceText('{{CO Zip}}', row[23]);
body.replaceText('{{invoice #}}', row[0]);
//We make our changes permanent by saving and closing the document
doc.saveAndClose();
//Store the url of our new document in a variable
const url = doc.getUrl();
//Write that value back to the 'Document Link' column in the spreadsheet.
sheet.getRange(index + 1, 30).setValue(url)
//Write that value back to the 'Document Link' column in the spreadsheet.
sheet.getRange(index + 1, 31).setValue("DONE")
})
}

Try this:
You were checking for DONE in the wrong location
function createNewGoogleDocs() {
const googleDocTemplate = DriveApp.getFileById('1yXfc...');
const destinationFolder = DriveApp.getFolderById('1TXE...');
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Export Worksheet');
const vs = sh.getRange(2, 1, sh.getLastRow() - 1, sh.getLastColumn()).getValues();
vs.forEach((r, i) => {
if (r[30] != 'DONE') {
const copy = googleDocTemplate.makeCopy(`${r[4]}, ${r[0]} Invoice`, destinationFolder);
const doc = DocumentApp.openById(copy.getId());
const body = doc.getBody();
body.replaceText('{{Full Address}}', r[4]);
body.replaceText('{{unit}}', r[5]);
body.replaceText('{{Total}}', r[15]);
body.replaceText('{{Account Num}}', r[2]);
body.replaceText('{{Owner 1}}', r[6]);
body.replaceText('{{Owner 2}}', r[7]);
body.replaceText('{{CO Name}}', r[17]);
body.replaceText('{{St Address}}', r[20]);
body.replaceText('{{Address 1}}', r[18]);
body.replaceText('{{City}}', r[21]);
body.replaceText('{{State}}', r[22]);
body.replaceText('{{CO Zip}}', r[23]);
body.replaceText('{{invoice #}}', r[0]);
doc.saveAndClose();
const url = doc.getUrl();
sh.getRange(i + 2, 30).setValue(url);
sh.getRange(i + 2, 31).setValue("DONE");
}
});
}

Related

Appscript save copy as docx

hey guys i found this guide https://jeffreyeverhart.com/2020/09/29/auto-fill-a-google-doc-template-from-google-sheet-data/ on transfering data for sheets to google docs but i am trying to get it to save the files as docx since the files will be sent out to customers.
Is there any easy way to get it to work?
function onOpen() {
const ui = SpreadsheetApp.getUi();
const menu = ui.createMenu('Oppdrettsbevis');
menu.addItem('Generer Oppdrettsbevis', 'createNewGoogleDocs')
menu.addToUi();
}
function createNewGoogleDocs() {
//This value should be the id of your document template that we created in the last step
const googleDocTemplate = DriveApp.getFileById('xxxxxxxx');
//This value should be the id of the folder where you want your completed documents stored
const destinationFolder = DriveApp.getFolderById('xxxxxxxxx')
//Here we store the sheet as a variable
const sheet = SpreadsheetApp
.getActiveSpreadsheet()
.getSheetByName('Data')
//Now we get all of the values as a 2D array
const rows = sheet.getDataRange().getValues();
//Start processing each spreadsheet row
rows.forEach(function(row, index){
//Here we check if this row is the headers, if so we skip it
if (index === 0) return;
//Here we check if a document has already been generated by looking at 'Document Link', if so we skip it
if (row[5]) return;
//Using the row data in a template literal, we make a copy of our template document in our destinationFolder
const copy = googleDocTemplate.makeCopy(`${row[1]}, ${row[0]} Employee Details` , destinationFolder)
//Once we have the copy, we then open it using the DocumentApp
const doc = DocumentApp.openById(copy.getId())
//All of the content lives in the body, so we get that for editing
const body = doc.getBody();
//In this line we do some friendly date formatting, that may or may not work for you locale
const friendlyDate = new Date(row[3]).toLocaleDateString();
//In these lines, we replace our replacement tokens with values from our spreadsheet row
body.replaceText('{{First Name}}', row[0]);
body.replaceText('{{Last Name}}', row[1]);
body.replaceText('{{Position}}', row[2]);
body.replaceText('{{Hire Date}}', friendlyDate);
body.replaceText('{{Hourly Wage}}', row[4]);
//We make our changes permanent by saving and closing the document
doc.saveAndClose();
//Store the url of our new document in a variable
const url = doc.getUrl();
//Write that value back to the 'Document Link' column in the spreadsheet.
sheet.getRange(index + 1, 6).setValue(url)
})
}
You are asking if it is possible to export a .docx
Try Using, from the crossreferenced post beolw the docToDocx() , which I modified to return the URL. Edited to include the Entire code with some Logger lines.
function onOpen() {
const ui = SpreadsheetApp.getUi();
const menu = ui.createMenu('AutoFill Docs');
menu.addItem('Create New Docs', 'createNewGoogleDocs')
menu.addToUi();
}
//include this function
function docToDocx(id) {
var format = 'docx',
exportLink =
'https://docs.google.com/document/d/' + id + '/export?format=' + format,
blob = UrlFetchApp.fetch(exportLink, {
headers: {
Authorization: 'Bearer ' + ScriptApp.getOAuthToken(),
},
});
var thisFile = DriveApp.createFile(blob);
return thisFile.getUrl()
}
function createNewGoogleDocs() {
//This value should be the id of your document template that we created in the last step
const googleDocTemplate = DriveApp.getFileById('xx YOUR TEMPLATE ID HERE xx');
//This value should be the id of the folder where you want your completed documents stored
const destinationFolder = DriveApp.getFolderById('xx YOUR FOLDER ID HERE xx')
//Here we store the sheet as a variable
const sheet = SpreadsheetApp
.getActiveSpreadsheet()
.getSheetByName('Data')
//Now we get all of the values as a 2D array
const rows = sheet.getDataRange().getValues();
//Start processing each spreadsheet row
rows.forEach(function(row, index){
//Here we check if this row is the headers, if so we skip it
if (index === 0) return;
//Here we check if a document has already been generated by looking at 'Document Link', if so we skip it
if (row[5])
{
Logger.log("Document Made already");
Logger.log(row[5]);
return; //Breaks this iteration of the loop should allow next row
}
//Using the row data in a template literal, we make a copy of our template document in our destinationFolder
const copy = googleDocTemplate.makeCopy(`${row[1]}, ${row[0]} Employee Details` , destinationFolder)
//Once we have the copy, we then open it using the DocumentApp
const doc = DocumentApp.openById(copy.getId())
//All of the content lives in the body, so we get that for editing
const body = doc.getBody();
//In this line we do some friendly date formatting, that may or may not work for you locale
const friendlyDate = new Date(row[3]).toLocaleDateString();
//In these lines, we replace our replacement tokens with values from our spreadsheet row
body.replaceText('{{First Name}}', row[0]);
body.replaceText('{{Last Name}}', row[1]);
body.replaceText('{{Position}}', row[2]);
body.replaceText('{{Hire Date}}', friendlyDate);
body.replaceText('{{Hourly Wage}}', row[4]);
//We make our changes permanent by saving and closing the document
doc.saveAndClose();
Logger.log("The Google Doc: " + doc.getUrl());
///Call the docToDocx Function and save the Url:
const url = docToDocx( doc.getId() );
Logger.log("The .docX URL: " + url);
//Write that value back to the 'Document Link' column in the spreadsheet.
sheet.getRange(index + 1, 6).setValue(url);
})
}
After Running the Script I can now see in my Execution log:
Cloud logs
Oct 19, 2022, 12:09:46 PM Info The Google Doc: https://docs.google.com/open?id=xx THIS FILE ID xx
Oct 19, 2022, 12:09:48 PM Info The .docX URL: https://docs.google.com/document/d/xx THIS FILE ID xx_/edit?usp=drivesdk&ouid=xx THIS TOKEN ID XX&rtpof=true&sd=true
Oct 19, 2022, 12:09:50 PM Info The Google Doc: https://docs.google.com/open?id=xx THIS FILE ID xx
Oct 19, 2022, 12:09:52 PM Info The .docX URL: https://docs.google.com/document/d/xx THIS FILE ID xx/edit?usp=drivesdk&ouid=xx THIS TOKEN ID XX&rtpof=true&sd=true
Oct 19, 2022, 12:09:54 PM Info The Google Doc: https://docs.google.com/open?id=xx THIS FILE ID xx
Oct 19, 2022, 12:09:56 PM Info The .docX URL: https://docs.google.com/document/d/xx THIS FILE ID xx/edit?usp=drivesdk&ouid=xx THIS TOKEN ID XX&rtpof=true&sd=true
That shows the Google docs url is different then the supplied uls that will lead to a download of a .docx file. Those docx Urls are also showing in column 5 of the spreadsheet.
The docX function was found at theWizEd's commented crossreference:
Converting a GDoc to docx through GAS produces corrupted document

Create PDF from Google Sheet Template

I am fairly new to code and App Script, but I've managed to come up with this from research.
Form submitted, Sheet populated, take entry data, copy and append new file, save as pdf, email pdf
I've created examples of what I've been trying to do
Link to form - https://docs.google.com/forms/d/e/1FAIpQLSfjkSBkn3eQ1PbPoq0lmVbm-Dk2u2TP_F_U5lb45SddsTsgsA/viewform?usp=sf_link
link to spreadsheet - https://docs.google.com/spreadsheets/d/1kWQCbNuisZsgWLk3rh6_Iq107HoK7g-qG2Gln5pmYTE/edit?resourcekey#gid=1468928415
link to template - https://docs.google.com/spreadsheets/d/1Ye7DyJQOjA3J_EUOQteWcuASBCfqlA-_lzyNw0REjY8/edit?usp=sharing
However I receive the following error - Exception: Document is missing (perhaps it was deleted, or you don't have read access?)
at Create_PDF(Code:32:34)
at After_Submit(Code:13:21)
App Script Code as follows - If I use a google Doc as a template it works. However I would like to use a spreadsheet as a template, and have the result pdf content fit to page. Please let me know if you need any additional information for this to work.
function After_Submit(e, ){
var range = e.range;
var row = range.getRow(); //get the row of newly added form data
var sheet = range.getSheet(); //get the Sheet
var headers = sheet.getRange(1, 1, 1,5).getValues().flat(); //get the header names from A-O
var data = sheet.getRange(row, 1, 1, headers.length).getValues(); //get the values of newly added form data + formulated values
var values = {}; // create an object
for( var i = 0; i < headers.length; i++ ){
values[headers[i]] = data[0][i]; //add elements to values object and use headers as key
}
Logger.log(values);
const pdfFile = Create_PDF(values);
sendEmail(e.namedValues['Your Email'][0],pdfFile);
}
function sendEmail(email,pdfFile,){
GmailApp.sendEmail(email, "Subject", "Message", {
attachments: [pdfFile],
name: "From Someone"
});
}
function Create_PDF(values,) {
const PDF_folder = DriveApp.getFolderById("1t_BYHO8CqmKxVIucap_LlE0MhslpT7BO");
const TEMP_FOLDER = DriveApp.getFolderById("1TNeI1HaSwsloOI4KnIfybbWR4u753vVd");
const PDF_Template = DriveApp.getFileById('1Ye7DyJQOjA3J_EUOQteWcuASBCfqlA-_lzyNw0REjY8');
const newTempFile = PDF_Template.makeCopy(TEMP_FOLDER);
const OpenDoc = DocumentApp.openById(newTempFile.getId());
const body = OpenDoc.getBody();
for (const key in values) {
body.replaceText("{{"+key+"}}", values[key]);
}
OpenDoc.saveAndClose();
const BLOBPDF = newTempFile.getAs(MimeType.PDF);
const pdfFile = PDF_folder.createFile(BLOBPDF);
console.log("The file has been created ");
return pdfFile;
}
You get the error message with Google Sheets because you are using a Google Doc class to create the PDF, which is not compatible with Google Sheets.
DocumentApp can only be used with Google Docs. I will advise you to change
const OpenDoc = DocumentApp.openById(newTempFile.getId());
for
const openDoc = SpreadsheetApp.openById(newTempFile.getId());
const newOpenDoc = openDoc.getSheetByName("Sheet1");
And depending on the Google Sheet where the "Body" of the information is located. Replace:
const body = OpenDoc.getBody();
for an equivalent like getRange() or any Range class that helps you target the information you need. For example:
// This example is assuming that the information is on the cel A1.
const body = newOpenDoc.getRange(1,1).getValue();
The template for the PDF should be something like this:

How do I get the image ID of an image IN THE CELL?

I'm currently working on a code in Google Apps Script that allows a user to fill out a spreadsheet and have the spreadsheet generate printouts for a job board. I'm trying to design this in a way where the user can simply insert a logo image into a row of my Google sheet and have it replace a placeholder in my doc template.
I have found lots of answers about how you can take an image and convert it to a blob and insert it from a url or an ID, however, I can't seem to find a way to get the ID or url from the image in the cell.
Here's my code currently:
//Creates menu option on spreadsheet
function onOpen() {
const ui = SpreadsheetApp.getUi();
const menu = ui.createMenu('AutoFill Docs');
menu.addItem('Create New Docs', 'createNewGoogleDocs');
menu.addToUi();
}
//Defines where to get template and info from
function createNewGoogleDocs() {
const googleDocTemplate = DriveApp.getFileById('14MJNd37pn6D-EmNKCQzXXvxJCcOAoB3KS-TlDgZuWMI');
const destinationFolder = DriveApp.getFolderById('120Sb_CJJlmz5NzJW8W3DB4TNuC4kdD3e');
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('JobBoard');
const rows = sheet.getDataRange().getValues();
rows.forEach(function(row, index) {
if (index === 0) return;
if (row[9]) return;
const copy = googleDocTemplate.makeCopy(`${row[1]}, ${row[0]} Printout`, destinationFolder);
const doc = DocumentApp.openById(copy.getId())
const body = doc.getBody();
const friendlyDate = new Date(row[2]).toLocaleDateString();
//Replacing text
body.replaceText('{{Company}}', row[1]);
body.replaceText('{{jobTitle}}', row[0]);
body.replaceText('{{datePosted}}', friendlyDate);
body.replaceText('{{Description}}', row[3]);
body.replaceText('{{Qualifications}}', row[5]);
body.replaceText('{{Wage}}', row[4]);
body.replaceText('{{Apply}}', row[6]);
//A subfunction to handle replacing the image
function textToImage() {
var replaceTextToImage = function(body, searchText, image, width) {
var next = body.findText(searchText);
if (!next) return;
var r = next.getElement();
r.asText().setText("");
var img = r.getParent().asParagraph().insertInlineImage(0, image);
if (width && typeof width == 100) {
var w = img.getWidth();
var h = img.getHeight();
img.setWidth(width);
img.setHeight(width * h / w);
}
return next;
};
var documentId = doc;
var replaceText = "{{Upload Image}}";
var imageFileId = "### File ID of image ###"; //I don't know how to get this variable
var body = DocumentApp.openById(documentId).getBody();
var image = DriveApp.getFileById(imageFileId).getBlob();
do {
var next = replaceTextToImage(body, replaceText, image, 200);
} while (next);
}
//Close and saves new doc
doc.saveAndClose();
const url = doc.getUrl();
sheet.getRange(index + 1, 10).setValue(url)
})
}
I think what might be messing me up is that I have to loop through all my cells right now so that I can create multiple documents at once (meaning each row will have a different doc and different image ID). I'm just not sure how to work around that.
Here's the template and spreadsheet
https://docs.google.com/spreadsheets/d/1cySHogAxcUgzr0hsJoTyPZakKQkM6uIOtmyPzcMoJUM/edit?usp=sharing
https://docs.google.com/document/d/14MJNd37pn6D-EmNKCQzXXvxJCcOAoB3KS-TlDgZuWMI/edit?usp=sharing
There is a bit of an issue trying to get an image in a specific cell. There's even a Feature Request for that. This year Google released a few classes for image management but there seems to be issues when retrieving those using cellImage class.
I found a related answer (workaround) from user #Tanaike where images are retrieved from Google Sheets, converted to a Blob and inserted into a Google Doc.
Sample code provided was:
const spreadsheetId = "###"; // Google Spreadsheet ID
const res = DocsServiceApp.openBySpreadsheetId(spreadsheetId).getSheetByName("Sheet1").getImages();
console.log(res); // You can check the retrieved images at the log.
if (res.length == 0) return;
const blob = res[0].image.blob; // Here, 1st image of Sheet1 is retrieved. Of course, you can choose the image on the sheet.
let doc = DocumentApp.create("newDocName Goes_Here");
var body = doc.getBody();
var imgPDF = body.appendImage(blob);
Take into consideration that to make the above work you need to:
Install Google Apps Script library. (instructions here)
Enable Drive API.
I tested this and indeed, got the images from the given sheet and inserted them into the Google Doc specified. For some reason, running your code did not show me a newly created file from the template but you can tweak the above accordingly to your case.

Google Apps Script: Use getFolderById for multiple variables depending on value

I think I have a very simple issue with Google Apps Script, but I already tried to google the solution for 1.5hrs without success. I guess I search for the wrong terms.
Here my code:
function folderLocations(){
var folder = {
Michael: '1bz9wIBRcRN2V-xxxxxxxxxx',
Chris: '1AEKHiI8iZKjHs-xxxxxxxxxx',
Steve: '1TD8iwjcbR7K5dN-xxxxxxxxxx',
};
return folder;
}
function createNewGoogleDocs() {
//ID of Google Docs Template, what sheet to use + save all values as 2D array
const googleDocTemplate = DriveApp.getFileById('xxxxxxxxxx_XznDn-i0WVtIM');
const sheet = SpreadsheetApp
.getActiveSpreadsheet()
.getSheetByName('Current Overview');
const rows = sheet.getDataRange().getValues();
//Start processing each spreadsheet row
rows.forEach(function(row, index){
//Destination folder ID (can differ from each person)
const destinationFolder = DriveApp.getFolderById(folderLocations().Chris);
// Set custom file name and create file
const copy = googleDocTemplate.makeCopy(`${row[15]} - ${row[3]} Quarterly Review` , destinationFolder);
const doc = DocumentApp.openById(copy.getId());
const body = doc.getBody();
// Replace placeholders with real values
body.replaceText('%NAME%', row[3]);
body.replaceText('%QUARTER%', row[15]);
body.replaceText('%ANSWER_1%', row[16]);
body.replaceText('%ANSWER_2%', row[17]);
[...]
doc.saveAndClose();
})
}
All working fine! BUT: What I want is to "dynamically" change the folder, depending on the value of a cell. It's not always "Chris"...:
const destinationFolder = DriveApp.getFolderById(folderLocations().Chris);
E.g.: If row[4] == Michael, then use the folder ID of "Michael". Somehow I can't get it to work to be "dynamically". 😔
I already tried all this, none working:
const destinationFolder = DriveApp.getFolderById(folderLocations().row[4]);
const destinationFolder = DriveApp.getFolderById(folderLocations(row[4]));
const destinationFolder = DriveApp.getFolderById(folderLocations().`${row[4]}`);
const destinationFolder = DriveApp.getFolderById(folderLocations().toString(row[4]));
etc.
👆🏻 I know what I try to do here is embarrassing. But I am normally not a developer and nobody at my company is familiar with Google Apps Script. That's the last bit I am missing, rest I put together myself using Google.
Thank you SOO much! 🙏🏻
You don't even need a function. Just an object is enough:
const folderLocations = {
Michael: '1bz9wIBRcRN2V-xxxxxxxxxx',
Chris: '1AEKHiI8iZKjHs-xxxxxxxxxx',
Steve: '1TD8iwjcbR7K5dN-xxxxxxxxxx',
};
var id = folderLocations['Chris'];
console.log(id); // 1AEKHiI8iZKjHs-xxxxxxxxxx
const destinationFolder = DriveApp.getFolderById(folderLocations[row[4]]);
This did the trick :
function folderLocations(person){
var folder = {
Michael: '1bz9wIBRcRN2V-xxxxxxxxxx',
Chris: '1AEKHiI8iZKjHs-xxxxxxxxxx',
Steve: '1TD8iwjcbR7K5dN-xxxxxxxxxx',
};
return folder[person];
}
...further below:
const destinationFolder = DriveApp.getFolderById(folderLocations(row[4]));

Creating PDFs from Spreadsheet Need PDF URL to be returned to Spreadsheet

I have a spreadsheet that contains data, a doc that is acting as my template and the start of a script that creates a PDF using the spreadsheet & doc for each line of the data. This works great!
My next step and this is where I am struggling, is I need to put the URL/identifier (from google drive) of each created PDF (each PDF goes to the same folder) into my spreadsheet so that I can then create another script to email the recipient their document.
I've seen this done when using a form and triggers but as I am not actively collecting the data, I cannot figure out this next part.
Thanks,
Nate
/*This function takes the data from the Charitable Tax Receipt summary and passes one row at a time
to the createPDF function.
*/
function createTaxRcptPDFs(){
const DOCTEMPLATE = DriveApp.getFileById("ref");
const TEMPFOLDER = DriveApp.getFolderById("ref1");
const PDFFOLDER = DriveApp.getFolderById("ref2");
const CURRENTSHEET = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("TEST");
const DATA = CURRENTSHEET.getRange(5,1,3,20).getDisplayValues(); //change 3 to formula when testing done
// this code block creates a data array to populate each PDF per (row)
DATA.forEach(row => {
const ACTIVECELL = row[20];
createPDF(row[2],row[4],row[5],row[6],row[7],row[1],row[14],row[15],row[16],new Date(),row[1] + "_" + row[2],DOCTEMPLATE,TEMPFOLDER,PDFFOLDER);
});
}
/* This function creates the PDF based on a Doc template and saves it to a specific folder
for future use.
*/
function createPDF(fullName,street,city,state,postalCode,receiptNumber,donation,advantage,eligible,rcptDate,pdfName,DOCTEMPLATE,TEMPFOLDER,PDFFOLDER){
// constants/variables to use
const TEMPFILE = DOCTEMPLATE.makeCopy(TEMPFOLDER);
const TEMPDOCFILE = DocumentApp.openById(TEMPFILE.getId());
// array of values to create body from data
const BODY = TEMPDOCFILE.getBody();
BODY.replaceText("{fullName}", fullName);
BODY.replaceText("{street}", street);
BODY.replaceText("{city}", city);
BODY.replaceText("{state}", state);
BODY.replaceText("{postalCode}", postalCode);
BODY.replaceText("{receiptNumber}", receiptNumber);
BODY.replaceText("{donation}", donation);
BODY.replaceText("{advantage}", advantage);
BODY.replaceText("{eligible}", eligible);
BODY.replaceText("{rcptDate}", rcptDate);
TEMPDOCFILE.saveAndClose();
// create pdf and delete temp file
const PDFBLOB = TEMPFILE.getAs(MimeType.PDF);
PDFFOLDER.createFile(PDFBLOB).setName(pdfName);
TEMPFOLDER.removeFile(TEMPFILE);
}
Solution:
setName(pdfName) returns a File object for chaining, so you can use getDownloadUrl() right after.
var fileUrl = PDFFOLDER.createFile(PDFBLOB).setName(pdfName).getDownloadUrl();
Reference:
getDownloadUrl()