I am trying to write a script which is attached to a Google Form. The form collects the user's name and email, then puts their name on a certificate on a Google Slide, and saves it as a PDF in a Google Drive. I want the program to send an email with the PDF or a link to the PDF.
I am running into a permissions error though. I can get it to do everything except send the email. This form is going to be housed on a Google site.
function onFormSubmit(e) {
// 1. Get form responses
var formResponse = e.response;
var itemResponses = formResponse.getItemResponses();
// First item is the user's name and the second item is the user's email
var userName = itemResponses[0].getResponse();
var userEmail = itemResponses[1].getResponse();
// 2. Open the Google Slides presentation. Presentation is shared to anyone with the link.
var presentationUrl = MY SHARED URL GOES HERE;
var presentationId = presentationUrl.match(/\/presentation\/d\/([a-zA-Z0-9-_]+)/)[1];
var presentation = SlidesApp.openById(presentationId);
// 3. Replace placeholder text with user's name
var slides = presentation.getSlides();
var shapeIndex = 3; // Index of the shape containing the placeholder text
var slide = slides[0];
var shape = slide.getShapes()[shapeIndex];
if (shape) {
shape.getText().setText(userName);
// Save changes made to the presentation
presentation.saveAndClose();
// Wait for changes to be applied
Utilities.sleep(5000); // 5 seconds delay
// 4. Export presentation as PDF. This is where I keep getting the error message.
var pdf = DriveApp.getFileById(presentationId).getAs('application/pdf');
// Extracting folder ID from the provided folder URL. The folder is shared to anyone with the link.
var folderUrl = URL TO FOLDER GOES HERE.;
var folderId = folderUrl.match(/[-\w]{25,}/);
if (folderId) {
folderId = folderId[0];
} else {
throw new Error("Folder ID not found in the URL.");
}
// Accessing the folder and saving the PDF file.
var folder = DriveApp.getFolderById(folderId);
//THIS IS WHERE I KEEP GETTING THE ERROR MESSAGE
var pdfFile = folder.createFile(pdf);
var pdfFileName = userName + "_Certificate.pdf";
pdfFile.setName(pdfFileName);
// Generating the URL for the file in the user's local Google Drive
var fileUrl = FILE URL GOES HERE;
// 5. Send email to the user with the download link
var subject = "Your Certificate";
var body = "Dear " + userName + ",\n\nPlease find your certificate attached or download it from the following link:\n" + fileUrl;
MailApp.sendEmail(userEmail, subject, body, { attachments: [pdfFile] });
} else {
Logger.log("Shape not found.");
}
}
Thoughts?
- The program has a trigger upon the submission of the form. I have tried running the program directly and allowing all relevant permissions.
- I have also gotten the program to successfully run by replacing the first variables with strings. Meaning:
var userName = 'Name'; var userEmail = 'Email'; - I have also had ChatGPT try to debug the code, but it isn't really understanding the nature of my problem.
- I have also explored having it allow users to download the certificate locally, but I am having the same problem.
- I have added the Google Drive API, the Gmail API, and the Slides API. Edit: I realized that I did not include the error code- You do not have permission to call DriveApp.Folder.createFile. Required permissions: googleapis.com/auth/drive at onFormSubmit(onFormSubmit:44:26)
I'd suggest double checking your permissions:
Re the last point, you say "the folder is shared to anyone with the link" - but do they have editor permissions? YOu probably don't want that anyway as that's giving the world full access, but so long as the owner of the form (or script if it's not bound) has editor access, it should work.
I replicated your script (with a few tweaks for personal preference about the flow), and it worked fine in my Google workspace. I've copied the slightly edited script below in case it's useful - I doubt the very minor changes I made were the issue for you.