Sharing a finished Slides deck as a static PDF avoids surprising a recipient with an accidental edit or a comment thread they never intended to trigger, and Apps Script can generate that PDF without opening a single dialog.
This script builds the special export URL Google Slides uses internally for its own Download as PDF menu option, fetches it with UrlFetchApp using the script's own OAuth token, and saves the resulting bytes as a Drive file.
Because the export endpoint accepts size parameters, the script can also request the PDF at a specific pixel width, which is useful when the deck's export needs to match a particular print or embed size.
The result is a fully automatable path from finished deck to PDF sitting in a Drive folder, suitable for wiring into a trigger that runs right after a deck is generated from a template.
Need this built? Hire a Google Apps Script developer →
Sheet / project setup
| Resource | Name / value | Purpose |
|---|---|---|
| Presentation | SLIDES_ID | Exported via UrlFetchApp |
| Dest folder | PDF_FOLDER_ID | Drive destination for PDF |
| Filename | DeckName.pdf | Created file title |
What It Does
The script constructs the Slides export URL for a given presentation ID, sends an authenticated GET request through UrlFetchApp with the script's OAuth token attached, and receives the PDF bytes back as a response blob.
It then saves that blob into a destination Drive folder with DriveApp.createFile, giving the new PDF a filename derived from the original presentation's name and the current date.
Prerequisites
You need the presentation ID from the Slides URL and a destination folder ID where you want the exported PDF to be saved once the export completes.
The script relies on ScriptApp.getOAuthToken to authenticate the export request, so the Apps Script project needs the appropriate Slides and Drive scopes already authorized.
Walkthrough
Set PRESENTATION_ID and DEST_FOLDER_ID at the top of the script, then run exportSlidesToPdf and grant the requested scopes the first time it executes.
Open the destination folder in Drive and confirm a new PDF file appears with a filename that matches the presentation's title, then open it to verify every slide rendered correctly.
Compare the exported PDF against manually choosing File, Download, PDF from the Slides UI to confirm the automated export produces an equivalent result.
Edge Cases
Presentations with custom fonts not available to the export renderer may render with a substituted font in the PDF, which matches the same limitation you would see using the manual export menu.
Very large presentations with dozens of high-resolution images can take noticeably longer to export and occasionally approach UrlFetchApp's response size limits, in which case exporting in smaller batches of slides is worth considering.
Testing
Export a small three-slide test deck first and open the resulting PDF to confirm slide order and content match the original presentation exactly.
Run the export twice in a row and confirm two separate PDF files are created rather than the second run silently overwriting the first, unless you specifically add overwrite logic.
Hardening
Check the HTTP response code from UrlFetchApp.fetch before treating the response as a valid PDF, since a permissions problem or invalid presentation ID returns an error page instead of PDF bytes.
Add a retry with a short delay if the export request returns a 429 or 5xx response, since transient rate limiting is more common on this endpoint than on typical Apps Script API calls.
Variations
Request only a specific slide range by adjusting the export URL parameters when you need a PDF of a subset of slides rather than the entire deck.
Email the generated PDF as an attachment immediately after export using GmailApp.sendEmail, chaining this script directly onto the mail-merge tutorial's sending logic.
exportSlidesToPdf.gs
exportSlidesToPdf calls the Slides export endpoint directly with the script's OAuth token, checks the response code, and saves the returned PDF bytes into a Drive folder.
// Export a Slides presentation to PDF via UrlFetchApp
function exportSlidesToPdf() {
var PRESENTATION_ID = 'REPLACE_WITH_PRESENTATION_ID';
var DEST_FOLDER_ID = 'REPLACE_WITH_DEST_FOLDER_ID';
var exportUrl = 'https://docs.google.com/presentation/d/' + PRESENTATION_ID + '/export/pdf';
var response = UrlFetchApp.fetch(exportUrl, {
headers: { Authorization: 'Bearer ' + ScriptApp.getOAuthToken() },
muteHttpExceptions: true
});
if (response.getResponseCode() !== 200) {
throw new Error('Export failed with status ' + response.getResponseCode());
}
var presentation = SlidesApp.openById(PRESENTATION_ID);
var name = presentation.getName() + ' - ' + Utilities.formatDate(new Date(), Session.getScriptTimeZone(), 'yyyy-MM-dd') + '.pdf';
var destFolder = DriveApp.getFolderById(DEST_FOLDER_ID);
var pdfFile = destFolder.createFile(response.getBlob().setName(name));
Logger.log('Saved PDF: ' + pdfFile.getUrl());
}- Line 6: The export URL mirrors exactly what the Slides UI itself calls when you choose Download as PDF from the File menu.
- Line 8: Attaching the script's own OAuth token as a Bearer header authenticates the request without needing any separate API key.
- Line 9: muteHttpExceptions keeps a non-200 response from throwing immediately, so the script can inspect and report the status itself.
- Line 12: Checking the response code before treating the body as PDF bytes avoids silently saving an error page as if it were a real file.
- Line 20: getBlob pulls the raw PDF bytes out of the response, and setName gives the resulting Drive file a readable filename.
Deploy this example
- 01
Open Apps Script
In the bound spreadsheet: Extensions → Apps Script. For standalone projects, create one at script.google.com and link your Sheet by ID.
- 02
Paste and save
Add a .gs file, paste the code below, rename constants at the top (sheet names, column letters, API property keys), then save.
- 03
Authorize once
Run the main function from the editor. Accept OAuth scopes when prompted — triggers cannot run until authorization succeeds once.
- 04
Add the trigger
Triggers → Add trigger → choose the handler function and event (time-driven, on edit, or on form submit). Delete test triggers before production.
Before you run: export slides to pdf
- 1Presentation ID copied from the Slides URL
- 2Destination Drive folder ID chosen for the exported PDF
- 3Slides and Drive scopes authorized on first run
- 4Function run and PDF confirmed to appear in Drive
- 5Exported PDF compared against the manual Download as PDF menu option
- 6Response code checked before treating output as valid PDF bytes
Frequently asked questions
That works fine for a one-off export, but this script lets the same export run automatically right after a deck is generated or updated by another automation.
The script checks the HTTP response code and throws a clear error rather than saving whatever error page came back as if it were a valid PDF.
Yes, adjust the export URL's parameters to request a specific slide range, as mentioned in the variations section.
No, it relies on UrlFetchApp and the script's own OAuth token rather than a separate Advanced Service.
Fonts not available to the export renderer may be substituted, which matches the same behavior you would see using the manual export menu.
Yes, pass the resulting blob straight into GmailApp.sendEmail as an attachment, chaining it onto the mail-merge tutorial's sending logic.