Exception: Request failed for https://docs.google.com returned code 400 - google-apps-script

My response is :
Exception: Request failed for https://docs.google.com returned code 400. Truncated server response: <meta nam... (use muteHttpExceptions option to examine full response)
could anyone help me please ? Thank you ! (i'm french... sorry ;)
My code is :
function emailSpreadsheetAsPDF() {
DocumentApp.getActiveDocument();
DriveApp.getFiles();
// This is the link to my spreadsheet with the Form responses and the Notification of Absence Template sheet
// Add the link to your spreadsheet here
// or you can just replace the text in the link between "d/" and "/edit"
// In my case is the text: 1Kj4U5hrIPiRAjceHkySUlLFXjckh75R-KVqn0IsNrjA
const ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1ktAc1lf1lhQ9xf04sRm18l-8GQurW4eqnqrldbBNYj8/edit");
// We are going to get the email address from the cell "A1" from the "Notification of Absence" sheet
// Change the reference of the cell or the name of the sheet if it is different
const value = ss.getSheetByName("NOA PDF").getRange("a1").getValue();
const email = value.toString();
// Subject of the email message
const subject = 'Notification of Absence Form';
// Email Text.
const body = "Hello Cerian, <br/> <br/> Please find attached a Notification of Absence Form. <br/> This has also been automatically saved to the Sickness folder, but will need to be sorted into the correct employee's file. <br/> <br/> Sickness Folder - https://drive.google.com/drive/folders/1SCPGzH4fz7ryna7SSuXSTtYbJlJ52r0U?usp=sharing.";
// Again, the URL to your spreadsheet but now with "/export" at the end
// Change it to the link of your spreadsheet, but leave the "/export"
const url = 'https://docs.google.com/spreadsheets/d/1ktAc1lf1lhQ9xf04sRm18l-8GQurW4eqnqrldbBNYj8/export?';
const exportOptions =
'exportFormat=pdf&format=pdf' + // export as pdf
'&size=a4' + // paper size letter / You can use A4 or legal
'&portrait=true' + // orientation portal, use false for landscape
'&fitw=true' + // fit to page width false, to get the 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=852132144'; // the sheet's Id. Change it to your sheet ID.
// You can find the sheet ID in the link bar.
// Select the sheet that you want to print and check the link,
// the gid number of the sheet is on the end of your link.
var params = {method:"GET",headers:{"authorization":"Bearer "+ ScriptApp.getOAuthToken()}};
// Generate the PDF file
var response = UrlFetchApp.fetch(url+exportOptions, params).getBlob();
// Send the PDF file as an attachement
GmailApp.sendEmail(email, subject, body, {
htmlBody: body,
attachments: [{
fileName: "Notification of Absence Form" + ".pdf",
content: response.getBytes(),
mimeType: "application/pdf"
}]
});
// Save the PDF to Drive. The name of the PDF is going to be the name of the employee (cell b9)
const nameFile = ss.getSheetByName("NoA PDF").getRange("b9").getValue().toString() +".pdf"
DriveApp.createFile(response.setName(nameFile));
var files = DriveApp.getRootFolder().getFiles();
while (files.hasNext()) {
var file = files.next();
var destination = DriveApp.getFolderById("1SCPGzH4fz7ryna7SSuXSTtYbJlJ52r0U");
destination.addFile(file);
var pull = DriveApp.getRootFolder();
pull.removeFile(file);
}
}

Related

What code can I use to put the pdf link in google sheet using app script?

I have this existing code that I use in google sheet that whenever I run the script, the paychecks would automatically convert to pdf and will have its own folder. Now, I want to add the link of the pdf inside the google sheet but I don't know what code should I add into it. Below is my existing code that I use in my google sheet.
function finishedPayslip(){
makePDF()
mnthly()
clearPayslipFields()
}
function makePDF() {
// Get the currently active spreadsheet URL (link)
var ss = SpreadsheetApp.getActiveSpreadsheet();
var token = ScriptApp.getOAuthToken();
var sheet = ss.getSheetByName("Paycheck");
//Creating an exportable URL
var url = "https://docs.google.com/spreadsheets/d/SS_ID/export?".replace("SS_ID", ss.getId());
var folderID = "1A691O2hh96wlKWDuZ-P9S9CK_MDTAWcm"; // Folder id to save in a folder.
var folder = DriveApp.getFolderById(folderID);
var employeeName = ss.getRange("'Paycheck'!C4").getValue()
var pdfName = employeeName;
/* 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&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
// Convert individual worksheet to PDF
var response = UrlFetchApp.fetch(url + url_ext + sheet.getSheetId(), {
headers: {
'Authorization': 'Bearer ' + token
}
});
var blobs = response.getBlob().setName(pdfName + '.pdf');
var folders = folder.getFoldersByName(pdfName);
folder = folders.hasNext() ? folders.next() : folder.createFolder(pdfName);
var newFile = folder.createFile(blobs);
// Define the scope
Logger.log("Storage Space used: " + DriveApp.getStorageUsed());
}
The output will be like I will add an another column at the end of my sheet named "pdf link" and the links for pdf per employee will appear inside my google sheet. What code should I add?
Additional information: My sheet looks like I have a template generator or paycheck generator inside my sheet, and whenever I run the script, it would automatically go to their designated sheet since it is separated by period (January, February and so on)
Thank you!
I believe your goal is as follows.
You want to create a PDF file and retrieve the URL of the PDF file, and want to put the URL to the column "S".
In this case, the sheet name is retrieved from the cell 'Paycheck'!H3. And, you want to search the name from the column "A" of the sheet and put the URL to the column "S" of the same row.
In this case, how about the following modification?
From:
var newFile = folder.createFile(blobs);
To:
var newFile = folder.createFile(blobs);
var sheetName = ss.getRange("'Paycheck'!H3").getValue();
var range = ss.getSheetByName(sheetName).getRange("A2:A").createTextFinder(employeeName).findNext();
if (range) {
range.offset(0, 18).setValue(newFile.getUrl());
}
In this modified script, the sheet name is retrieved from the cell 'Paycheck'!H3 and the row is searched by TextFinder, and the URL is put to the column "S" of the searched row.
Reference:
Class TextFinder

Everything works but the subject line blank... why? What am I missing?

I think this must be very easy to see, but I cannot see it! This script sends out a sheet as a PDF. It works well, except that the subject line is blank. I've tried substituting an actual string for the variable in the class gmailApp at the bottom, but the subject line is still blank when the email arrives. Help! Thank you.
P.S.-- note that I took out the email address for privacy.
function emailPDF(email, subject, body, sheetName) {
var email = "...";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Client');
var cost = sheet.getSheetValues(1,1,1,1).toLocaleString();
var subject = ss.getName();
var body = "Hi Serenity, the material cost is $" + cost +" Thank you!";
// 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&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(ss.getName() + ".pdf");
// save PDF to drive
// var newFile = DriveApp.createFile(response).setName(sheet.getName() + ".pdf")
if (MailApp.getRemainingDailyQuota() > 0)
GmailApp.sendEmail(email, subject, body, {
htmlBody : body,
attachments : [response]
});
}
I've figured it out... this was just petty error. The spreadsheet has a lot of scripts. I picked up this script from a month ago, started from scratch and accidentally gave it the same function name. Both scripts were being called simultaneously, causing this result. Everything works now.
I appreciate your comment Lamblichus... I was so focused on the script being wrong that I didn't realize what was happening. Then I realized that it can't be wrong. You got me thinking the right way. Best.

How can I generate and open pdf as a link with google sheet script?

I'm doing an invoice program in google spreadsheets, and in the program I'm using drawings as buttons (create new invoice, increase/decrease invoice number and clear data). Those functions works well, but I also want to add a button that will create a PDF file and open as a tab in the web browser. So far I had to duplicate the Invoice-sheet as a tempSheet and then remove the buttons, and then download pdf of the tempSheet. I've found this code below which I've tried to change so it will fit with my program (the original program is only for the active sheet). I think maybe the problem is when I use getId() and getSheetId().
If I use ss.getId() in the url I only get the active sheet (invoice-sheet) as the pdf.
If I use tempSheet.getId(), I get an error (ERROR TypeError: tempSheet.getId is not a function)
Do you know what I'm doing wrong? If I understand it correctly it is the same Id for all the sheets and then the different sheets also have its own id which I can get from getSheetId().
getId()- the number after docs.google.com/spreadsheets/d/
getSheetId() - #gid=xxxxxxxxx
function createPDF(){
//create a temporary sheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var tempSpreadsheet = SpreadsheetApp.getActiveSpreadsheet().duplicateActiveSheet();
SpreadsheetApp.getActiveSpreadsheet().renameActiveSheet('temp');
var tempSheet = SpreadsheetApp.getActive().getSheetByName('temp');
var invoiceNbr = tempSheet.getRange('C3').getValue().toString();
var tempId = tempSheet.getId(); //ERROR TypeError: tempSheet.getId is not a function
var tempSheetId = tempSheet.getSheetId();
var drawings = tempSheet.getDrawings();
for (var i = 0; i < drawings.length; i++) {
drawings[i].remove();
}
const url = 'https://docs.google.com/spreadsheets/d/{ID}/export?'.replace('{ID}', tempId);
const exportOptions =
'exportFormat=pdf&format=pdf' + // export as pdf
'&size=letter' + // paper size letter / You can use A4 or legal
'&portrait=true' + // orientation portal, use false for landscape
'&fitw=false' + // fit to page width false, to get the 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=' + tempSheetId; // the sheet's Id. Change it to your sheet ID.
// You can find the sheet ID in the link bar.
// Select the sheet that you want to print and check the link,
// the gid number of the sheet is on the end of your link.
var params = {method:"GET",headers:{"authorization":"Bearer "+ ScriptApp.getOAuthToken()}};
var blob = UrlFetchApp.fetch(url + exportOptions, params).getBlob().setName(invoiceNbr+'.pdf');
var pdfFile = DriveApp.createFile(blob);
var downloadLink = HtmlService
.createHtmlOutput('<p>Download your file here.</p>')
.setWidth(200)
.setHeight(100);
SpreadsheetApp.getUi().showModalDialog(downloadLink, "Download PDF");
ss.deleteSheet(tempSheet);
Add SpreadsheetApp.flush() before getSheetByName('temp'):
SpreadsheetApp.getActiveSpreadsheet().renameActiveSheet('temp');
SpreadsheetApp.flush();
var tempSheet = SpreadsheetApp.getActive().getSheetByName('temp');
Related
Google Script import form data to new spreadsheet, then send as PDF
Why do we use SpreadsheetApp.flush();?

How to get the “shareable link” of a Google Drive file via Google Apps Script and paste the link into a cell in Google Sheets?

I have a script that makes a PDF of my invoice and sends it to a Google drive folder.Now I want to get the "Shareable link" from the file it just made and paste it into a specific Cell in google Sheets. I don't have a coding background and at most I can understand and modify some code. So I'm using code I found online to create the PDF. I tried making my own code for the shareable link but I'm getting nowhere. Can anyone help me. This is the code I'm using for the PDF. If I can provide any more useful information please let me know. Thank you! :)
// Get the currently active spreadsheet URL (link)
var ss = SpreadsheetApp.getActiveSpreadsheet();
var token = ScriptApp.getOAuthToken();
var sheet = ss.getSheetByName("Invoice");
//Creating an exportable URL
var url = "https://docs.google.com/spreadsheets/d/SS_ID/export?".replace("SS_ID", ss.getId());
var folderID = "#### Folder ID ####"; // Folder id to save in a folder.
var folder = DriveApp.getFolderById(folderID);
var invoiceNumber = ss.getRange("'Invoice'!I16").getValue()
var InvoiceDate = ss.getRange("!I17").getValue()
var pdfName = "Invoice #"+ invoiceNumber + " - " + Utilities.formatDate(new Date(), "GMT-7", "MM-dd-yyyy");
/* 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&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
// Convert individual worksheet to PDF
var response = UrlFetchApp.fetch(url + url_ext + sheet.getSheetId(), {
headers: {
'Authorization': 'Bearer ' + token
}
});
//convert the response to a blob
var blobs = response.getBlob().setName(pdfName + '.pdf');
//saves the file to the specified folder of Google Drive
var newFile = folder.createFile(blobs);
// Define the scope
Logger.log("Storage Space used: " + DriveApp.getStorageUsed());
}```
Intuitively, you can achieve a lot only by yourself, and this is the way to go at the beginning:
You want to retrieve the link of the pdf, so you know for sure that it can happen only when the pdf has been created, which is after this line var newFile = folder.createFile(blobs);
Therefore newFile is the PDF you've created, what's left is just to get the link of this file, you can use either getUrl() or getId():
var newFileLink = newFile.getUrl()
or
var newFileLink = "http://drive.google.com/uc?export=view&id=" + newFile.getId()
Now you have stored the link of the created PDF, and you want to write data into your spreadsheet within a specific cell, maybe you want it in J16, since you're using invoiceNumber = ss.getRange("'Invoice'!I16").getValue() to get a value from I16
Assuming you want to set a value in J16. Intuitively again, since getValue retrieve something, so maybe something link setValue will do the opposite:
var writePDFLink = ss.getRange("'Invoice'!J16").setValue(newFileLink)
Hope this was insightful.

MailApp.sendEmail emails the user who is not a recipient

(Note: I edited the title for clarity)
I've been trying to figure out what's causing this problem but to no avail.
I created a Google script that allows a Requester to submit a Google sheet for approval. Upon submission it emails the Requester that it has been submitted. It also emails the Approver with the option to APPROVE or DISAPPROVE. My problem: this same exact mail for Approver is also received by the Requester.
Here's a snapshot of the code for your review and kind support:
function emailSpreadsheetAsPDF(time, approverEmail, requesterEmail, financeEmail, approvalNeeded) {
var timestamp = time;
var approverEmail = approverEmail;
var requesterEmail = requesterEmail;
var financeEmail = financeEmail;
var approvalNeeded = approvalNeeded;
Logger.log("Approver: " + approverEmail);
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Form"); // Enter the name of the sheet here
//*******************************************
//* Enter the name of the TEMP folder ID here
//*******************************************
var TEMPfolderid = "xxxyyyzzz"; // TEMP folder to store the PDF export
var body4Requester = "\n\nAttached is a PDF copy of the Price Maintenance Form that you submitted. \n\nPlease note that you will be automatically notified via email when: \n(a) Your request is approved (or disapproved), and \n(b) When it is approved and already processed in SAP. \n\nAPAC Finance Team";
var body4Finance = "\n\nAttached is a PDF copy of the Price Maintenance Form submitted by " + requesterEmail + ". It does not require an approval as per current policy.\n\nKindly process.";
var url = "https://docs.google.com/spreadsheets/d/SS_ID/export?".replace("SS_ID", ss.getId());
// Specify PDF export parameters
var url_ext = 'exportFormat=pdf&format=pdf' // export as pdf / csv / xls / xlsx
+ '&size=A4' // 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
},
muteHttpExceptions: true
});
var pdfFile = response.getBlob();
//Create the file...
var file = DriveApp.createFile(pdfFile).setName(timestamp + ".pdf");
//Store the file's ID for retrieval later during approval and post-SAP processing
var PDFfileID = file.getId();
//Save the file in TEMP folder
DriveApp.getFolderById(TEMPfolderid).addFile(file);
//Now, get the file and email as attachment
var blob = DriveApp.getFileById(file.getId());
// Email with Approve/Disapprove link
var url = ScriptApp.getService().getUrl();
var options = '?approval=%APPROVE%&timestamp=%TIMESTAMP%&reply=%EMAIL%&pdffileid=%FILEID%'
.replace("%TIMESTAMP%",encodeURIComponent(timestamp))
.replace("%EMAIL%",requesterEmail)
.replace("%FILEID%",PDFfileID);
var approve = url+options.replace("%APPROVE%","Approved");
var disapprove = url+options.replace("%APPROVE%","Disapproved");
var html = "<body>"+
"Attached is the Price Change request<br /><br />"+
"Approve<br />"+
"Disapprove<br />"+
"</body>";
if (approvalNeeded == "Yes") { //send email with Approve and Disapprove option to Approver
MailApp.sendEmail(approverEmail, "TEST ONLY: Price Maintenance Form for your approval", body4Requester, {
htmlBody: html,
attachments : [blob]
});
MailApp.sendEmail(requesterEmail, "TEST ONLY: Your Price Maintenance request has been submitted", body4Requester, {
attachments : [blob]
});
} else { //send straight to Finance
MailApp.sendEmail(financeEmail, "TEST ONLY: Price Maintenance Form for processing. No approval neeed", body4Finance, {
cc:requesterEmail,
attachments : [blob]
});
}}
Not sure if it's relevant -- I deployed this as a web app with the setting "Execute the app as User accessing the web app".
Many thanks in advance for any advice.
I tried replacing MailApp.sendEmail with GmailApp.sendEmail.
It worked.