Download and file documents from a link sheet
Pull referenced files from URLs in a Sheet into Northwind's Drive automatically.
Publié le 24 oct. 2025
Northwind’s team collects file links all over the place — a supplier emails a spec PDF, a freelancer drops an asset in a shared note, a brief links to a reference image. Those links rot. The sensible fix is to pull a copy into Drive, but doing it by hand for a long list is exactly the kind of chore nobody gets to.
This script reads a Links sheet where each row names a URL, a destination
folder, and a filename, downloads each file, and saves it into Drive. It marks
every row as it goes, so a re-run only picks up the rows that have not been
downloaded yet — and a row that fails gets the error written next to it instead
of silently disappearing.
What you’ll need
- A Google Sheet with a
Linkstab and these four columns in row 1:url,targetFolderId,filename,downloaded. Leave thedownloadedcolumn blank — the script fills it in. - The destination folders must already exist in Drive; put each folder’s ID in
the
targetFolderIdcolumn. - Nothing else — the script writes its own status back to the sheet.
The script
// The Sheet that holds the list of links to download.
const LINKS_SHEET_ID = '1abcLinksId';
/**
* Reads the Links sheet, downloads every not-yet-fetched URL into its
* target Drive folder, and writes a timestamp or error back per row.
*/
function downloadFromLinks() {
const sheet = SpreadsheetApp.openById(LINKS_SHEET_ID).getSheets()[0];
// 1. Read the whole sheet and split off the header row.
const values = sheet.getDataRange().getValues();
const [header, ...rows] = values;
// 2. Bail out if there are no data rows to process.
if (!rows.length) {
Logger.log('Links sheet has no rows — nothing to download.');
return;
}
// 3. Map column names to indexes so the order of columns does not matter.
const col = Object.fromEntries(header.map((name, i) => [name, i]));
// 4. Walk each row, skipping any that already has a "downloaded" value.
rows.forEach((r, i) => {
if (r[col.downloaded]) return;
try {
// 5. Fetch the file, name the blob, and save it into the target folder.
const blob = UrlFetchApp.fetch(r[col.url])
.getBlob()
.setName(r[col.filename]);
DriveApp.getFolderById(r[col.targetFolderId]).createFile(blob);
// 6. Record success as a timestamp (i + 1 skips the header row).
values[i + 1][col.downloaded] = new Date();
} catch (e) {
// 7. Record the failure inline so it is visible and re-runnable.
values[i + 1][col.downloaded] = `error: ${e.message}`;
}
});
// 8. Write the updated grid back in one call.
sheet.getDataRange().setValues(values);
Logger.log('Finished processing ' + rows.length + ' link row(s).');
}
How it works
downloadFromLinksopens theLinkssheet and reads the entire data range in one go, then peels the header row off the front.- If there are no data rows it logs a message and stops, so an empty sheet never triggers a needless write.
- It builds a
collookup from header name to column index, so you can reorder or insert columns without breaking the script. - For each row it checks the
downloadedcolumn first — any row that already has a timestamp or an error is skipped, which makes re-runs safe. - For a fresh row it fetches the URL with
UrlFetchApp, turns the response into a blob, and names that blob from thefilenamecolumn. - It creates the file in the folder named by
targetFolderIdand writes the current date into thedownloadedcell. - If anything throws — a dead URL, a bad folder ID — it writes
error:plus the message into the same cell, so the row stays visible and can be retried. - After the loop it writes the whole grid back in a single
setValuescall.
Example run
Before the run, the Links sheet looks like this:
| url | targetFolderId | filename | downloaded |
|---|---|---|---|
| https://example.com/spec.pdf | 1abcBriefsFolder | acme-spec.pdf | |
| https://example.com/logo.png | 1abcAssetsFolder | partner-logo.png | |
| https://broken.example/x.zip | 1abcAssetsFolder | archive.zip |
After the run, the files are in Drive and the sheet records what happened:
| url | targetFolderId | filename | downloaded |
|---|---|---|---|
| https://example.com/spec.pdf | 1abcBriefsFolder | acme-spec.pdf | 2025-10-24 09:15:02 |
| https://example.com/logo.png | 1abcAssetsFolder | partner-logo.png | 2025-10-24 09:15:04 |
| https://broken.example/x.zip | 1abcAssetsFolder | archive.zip | error: DNS error |
Run it again and only the failed row is retried — the two timestamped rows are skipped.
Trigger it
Most teams run this on a schedule so links added during the day get filed overnight:
- In the Apps Script editor open Triggers (the clock icon).
- Add a trigger for
downloadFromLinks, time-driven, on a daily timer.
You can also run it by hand straight after pasting a batch of new links.
Watch out for
UrlFetchAppfollows redirects but cannot get past login pages — a link that needs a session will download an HTML error page named like your file. Spot these by their size in Drive.- The
filenameyou set is what you get;UrlFetchAppdoes not infer an extension. Include the correct extension in thefilenamecolumn. - There is a daily
UrlFetchAppquota. A very long list may stop partway — because finished rows are marked, the next run simply continues where it left off. - The script does not de-duplicate. The same URL in two rows downloads twice into Drive as two separate files.
- A row with a malformed
targetFolderIdfails per-row and is logged inline — it does not stop the rest of the batch.
À 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
Bundle a folder of images into one PDF
Combine Northwind scans into a single deliverable PDF using a generation service.
Mis à jour le 17 nov. 2025