Bundle a folder of images into one PDF
Combine Northwind scans into a single deliverable PDF using a generation service.
Publié le 17 nov. 2025
Northwind’s site team comes back from a job with a folder of photos — twenty JPEGs of a finished install. The client wants one tidy PDF, not a shared folder they have to scroll through. Doing it by hand means dragging every image into a document and exporting, which is fine once and tedious the tenth time.
Apps Script cannot assemble a PDF from images on its own, so this script takes the same approach as the other PDF automations: it collects the images from a Drive folder, base64-encodes them, and posts the lot to a small PDF-building service. The service stitches them into a single document and the script files the finished PDF straight back into the folder.
What you’ll need
- A PDF-building endpoint that accepts a JSON array of base64-encoded images and returns a base64 PDF. This can be a hosted service or a small function you deploy; the script only depends on the request and response shape.
- If the endpoint needs an API key, keep it in Script Properties rather than in the code — see Store API keys and secrets securely.
- A Drive folder of images to bundle. The script handles any
image/*file and skips everything else.
The script
// PDF-building endpoint. It takes { "images": ["<base64>", ...] }
// and returns { "pdf": "<base64>" }.
const PDF_BUILDER = 'https://your-pdf-service.example/images-to-pdf';
/**
* Bundles every image in a Drive folder into a single PDF and saves
* the result back into that folder.
*
* @param {string} folderId The folder of images to bundle.
* @param {string} outputName The file name for the finished PDF.
*/
function bundleImagesToPdf(folderId, outputName) {
const folder = DriveApp.getFolderById(folderId);
// 1. Collect every image in the folder, base64-encoded for the request.
const images = [];
const files = folder.getFiles();
while (files.hasNext()) {
const f = files.next();
if (!f.getMimeType().startsWith('image/')) continue;
images.push(Utilities.base64Encode(f.getBlob().getBytes()));
}
// 2. Bail out if the folder has no images — nothing to bundle.
if (images.length === 0) {
Logger.log('No images in the folder — nothing to bundle.');
return;
}
// 3. Post the images to the PDF-building service.
const res = UrlFetchApp.fetch(PDF_BUILDER, {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify({ images }),
muteHttpExceptions: true,
});
// 4. Guard against a failed call before parsing the body.
if (res.getResponseCode() !== 200) {
throw new Error('PDF service returned ' + res.getResponseCode());
}
// 5. Decode the returned PDF and save it back into the folder.
const pdfBase64 = JSON.parse(res.getContentText()).pdf;
const pdf = Utilities.newBlob(
Utilities.base64Decode(pdfBase64),
'application/pdf',
outputName
);
folder.createFile(pdf);
Logger.log('Bundled ' + images.length + ' image(s) into ' + outputName + '.');
}
How it works
bundleImagesToPdfopens the folder and walks its files, encoding eachimage/*file as base64 and skipping anything that is not an image.- If the folder turned up no images, it logs a message and stops before making a pointless API call.
- It POSTs the collected images as a JSON array to
PDF_BUILDER.muteHttpExceptionslets the script inspect a bad response instead of throwing on it. - It checks the response code first, so a service that is down or rejecting the request fails clearly rather than producing a broken file.
- It pulls the base64
pdffield from the response, decodes it back into bytes, wraps them in a PDF blob with the chosen name, and saves it into the same folder.
Example run
Say a folder holds the photos from one job, plus a stray notes file:
| File in folder | MIME type | Included? |
|---|---|---|
install-01.jpg | image/jpeg | Yes |
install-02.jpg | image/jpeg | Yes |
install-03.png | image/png | Yes |
site-notes.txt | text/plain | No — skipped |
Calling bundleImagesToPdf(folderId, 'Acme install report.pdf') produces a
single Acme install report.pdf in that folder, with the three images as its
pages in folder order. The log reads
Bundled 3 image(s) into Acme install report.pdf.
Run it
This runs on demand, once a job’s photos are in place:
- Set
PDF_BUILDERto your PDF-building endpoint. - In the Apps Script editor, call
bundleImagesToPdffrom the Run panel with the folder ID and a name for the output PDF. - Approve the authorisation prompt the first time.
- Open the folder and check the new PDF.
To bundle jobs automatically, wrap bundleImagesToPdf in a function that
loops over a parent folder of job folders and run it on a time-driven trigger.
Watch out for
- Page order follows whatever order Drive returns files in, which is not
guaranteed to be alphabetical. Name images with zero-padded numbers
(
01,02, …) and sort the list before sending if order matters. - Every image is base64-encoded and held in memory at once. A folder of large, high-resolution photos can hit Apps Script’s memory or runtime limits — bundle in smaller batches if it fails.
- The images leave your account. Whatever service
PDF_BUILDERpoints at receives every photo — only use an endpoint you trust, and prefer one you control for client work. - Re-running on the same folder adds another PDF, and since the PDF lands in the source folder, a later run would also try to encode it (it is not an image, so it is skipped — but the folder fills with old PDFs). Clear or rename previous outputs between runs.
- The script does not resize or compress images. If the service expects a size limit, downscale large photos before encoding them.
À voir aussi
Build a recurring file-delivery system
Drop a fresh report file into a Northwind client folder weekly — they don't even ask.
Mis à jour le 15 déc. 2025
Build a Drive search index in Sheets
Make Northwind's file metadata searchable in a Sheet — like Spotlight for Drive.
Mis à jour le 7 déc. 2025
Build a shared-folder onboarding kit
Auto-grant new Northwind hires the folders they need on day one.
Mis à jour le 29 nov. 2025
Route saved email attachments to project folders
File Gmail attachments into the right Northwind client folder based on subject keywords.
Mis à jour le 25 nov. 2025
Keep a self-updating contents file per folder
Auto-create a `_contents.md` Doc inside every Northwind folder, refreshed nightly.
Mis à jour le 13 nov. 2025