Summarize a folder of PDFs into a briefing
Digest Northwind's research PDFs into one structured briefing Doc.
Published Aug 27, 2025
Research lands at Northwind as a folder of PDFs — vendor reports, white papers, market notes — and nobody has time to read all of them before the meeting where they matter. The documents sit unread, and the decisions get made without them.
This script turns that folder into a single briefing Doc. It walks every PDF in a Drive folder, asks Claude to condense each one to a few bullets, and stitches the results into a dated Doc with a section per source. Instead of ten PDFs to open, you get one page to skim — and a record of what each document actually said.
What you’ll need
- A Google Drive folder containing the PDFs you want digested.
- An Anthropic API key saved as
ANTHROPIC_API_KEYin Script Properties — see Store API keys and secrets securely. - Nothing else — the script creates the briefing Doc itself.
The script
// How much text to read from each PDF. Keeps every per-file prompt
// within a sensible token budget — see "Watch out for".
const PDF_CHAR_LIMIT = 6000;
// How many bullets Claude should write per source document.
const BULLETS_PER_PDF = 3;
/**
* Reads every PDF in a Drive folder, summarises each one, and writes
* the lot into a single dated briefing Doc. Returns the Doc URL.
*/
function briefFolder(folderId) {
// 1. Get an iterator over the PDFs in the folder.
const files = DriveApp.getFolderById(folderId)
.getFilesByType('application/pdf');
// 2. Summarise each PDF into its own section.
const sections = [];
while (files.hasNext()) {
const f = files.next();
// Read a slice of the PDF text — enough to summarise, not so much
// it blows the token budget.
const text = f.getBlob().getDataAsString().slice(0, PDF_CHAR_LIMIT);
const prompt =
'Summarise in ' + BULLETS_PER_PDF + ' bullets. ' +
'Source: ' + f.getName() + '.\n\n' + text;
const summary = callClaude(prompt);
sections.push('### ' + f.getName() + '\n\n' + summary);
}
// 3. No PDFs in the folder — stop before creating an empty Doc.
if (!sections.length) {
Logger.log('No PDFs in that folder — nothing to brief.');
return null;
}
// 4. Create a dated Doc and write every section into it.
const today = new Date().toISOString().slice(0, 10);
const doc = DocumentApp.create('Briefing — ' + today);
doc.getBody().setText(sections.join('\n\n'));
doc.saveAndClose();
Logger.log('Briefed ' + sections.length + ' PDFs into ' + doc.getUrl());
return doc.getUrl();
}
/**
* Minimal Anthropic API call. The key lives in Script Properties — it
* is never pasted into the code.
*/
function callClaude(prompt, model = 'claude-haiku-4-5-20251001', maxTokens = 400) {
const key = PropertiesService.getScriptProperties()
.getProperty('ANTHROPIC_API_KEY');
const res = UrlFetchApp.fetch('https://api.anthropic.com/v1/messages', {
method: 'post',
contentType: 'application/json',
headers: { 'x-api-key': key, 'anthropic-version': '2023-06-01' },
payload: JSON.stringify({
model,
max_tokens: maxTokens,
messages: [{ role: 'user', content: prompt }],
}),
muteHttpExceptions: true,
});
return JSON.parse(res.getContentText()).content[0].text.trim();
}
How it works
briefFoldertakes a folder ID and gets an iterator over just the PDF files inside it, so other file types in the folder are ignored.- For each PDF it reads a slice of the document text — capped at
PDF_CHAR_LIMITto keep every prompt within a sensible token budget — and asks Claude to condense it toBULLETS_PER_PDFbullets, naming the source. - Each summary becomes a section, prefixed with the file name as a heading, and
is pushed onto the
sectionslist. - If the folder held no PDFs at all, the script logs that and returns without creating an empty Doc.
- It creates a Doc named with today’s date, writes every section into the body, and saves. The function returns the Doc’s URL so a caller can link to it.
Example run
Say the Drive folder holds three PDFs: Market Outlook Q1.pdf,
Vendor Review.pdf, and Customer Survey Notes.pdf. After a run, the new
briefing Doc reads:
Briefing — 2026-05-25
Market Outlook Q1.pdf
- Demand in the core segment grew 8% year on year.
- Two new competitors entered the mid-market tier.
- Pricing pressure is expected to ease by Q3.
Vendor Review.pdf
- Current vendor met SLA targets in 11 of 12 months.
- Support response times slipped in the busy quarter.
- Renewal terms are broadly unchanged.
Customer Survey Notes.pdf
- Onboarding remains the most common friction point.
- Satisfaction with support scored highest overall.
- Several customers asked for better reporting.
Three PDFs nobody had time to open become one page that takes a minute to read.
Run it
This is an on-demand job — run it when a folder of research has built up:
- In the Apps Script editor, call
briefFolder('your-folder-id')from a small wrapper function, or paste the folder ID into a test run. - Approve the authorisation prompt the first time.
- Open the briefing Doc from the URL in the execution log.
To produce the briefing on a schedule, wrap the call in a no-argument function with the folder ID baked in, then add a time-driven trigger for it.
Watch out for
- PDF text extraction is rough.
getDataAsStringworks well for text-based PDFs but returns garbled output for scanned or image-only documents — those need OCR before this script can read them. - Only the first
PDF_CHAR_LIMITcharacters are read. A long report is summarised from its opening pages, which may miss conclusions buried at the end. Raise the cap for short folders, or summarise in chunks. - One API call per PDF. A folder of many documents takes time and tokens; for large folders, expect a longer run and watch the six-minute execution limit.
- A new Doc is created every run. Repeated runs leave a trail of dated briefings in your Drive — tidy them up, or write into a fixed Doc instead.
- The briefing is only as current as the folder. Old PDFs left in place will be re-summarised every time, so prune the folder between runs.
Related
Summarize chat and Slack exports
Digest Northwind's long Slack conversations into recaps — for catch-up after PTO.
Updated Dec 5, 2025
Digest daily news into a personal briefing
Summarise headlines on a schedule — Northwind morning briefing for Awadesh.
Updated Nov 19, 2025
Summarize pros and cons from reviews
Extract what Northwind customers love and hate about each product into a single roll-up.
Updated Nov 3, 2025
Summarize YouTube videos into notes
Turn transcripts into Northwind study summaries — one Doc per video.
Updated Oct 6, 2025
Build a competitor-mention monitor
Summarise what Northwind's rivals are doing each week — feeds in, summary out.
Updated Sep 12, 2025