A shared Inbox folder in Drive tends to accumulate files from every source imaginable, and sorting them by hand into the right project folder is tedious busywork.
This script scans a source folder, checks each file's name against a small set of keyword-to-destination mappings, and moves matching files into the correct folder using moveTo.
Files that do not match any keyword are left untouched in the source folder rather than moved somewhere wrong, so nothing disappears silently when the naming rules do not cover a case.
The keyword map is defined as plain data at the top of the script, so extending the routing rules later is a matter of adding one line rather than rewriting logic.
Need this built? Hire a Google Apps Script developer →
Sheet / project setup
| Resource | Name / value | Purpose |
|---|---|---|
| Source folder | Inbox | Drive folder scanned for files |
| Keyword map | invoice→Invoices folder ID | Routing table in script |
| Action | file.moveTo(dest) | Moves matching files |
What It Does
The script iterates over every file directly inside a source folder, tests the filename against each keyword in a routing map, and calls moveTo on the first destination folder whose keyword matches.
Because the routing map is checked in order, more specific keywords should be listed earlier so a file like invoice-contract-2026.pdf is not accidentally routed by the more generic keyword.
Prerequisites
You need a source folder ID and at least one destination folder ID for each category you plan to route files into, all copied from their respective Drive folder URLs.
Agree on the keyword conventions your team already uses in filenames, since this script relies on simple case-insensitive substring matching rather than a more elaborate classification system.
Walkthrough
Fill in the SOURCE_FOLDER_ID constant and the ROUTES array, where each entry pairs a lowercase keyword with a destination folder ID, then paste the moveFilesByName function into the editor.
Drop a handful of test files with clearly matching names into the source folder, run the function manually, and confirm each file landed in the destination you expected.
Once matching behaves correctly, decide whether to run this on a time-driven trigger or leave it as a manual cleanup function you run from the editor when the Inbox gets full.
Edge Cases
A file with a name that matches two keywords is moved to whichever route appears first in the ROUTES array, so ordering the array carefully matters more than it might first appear.
Files that are actually Drive shortcuts rather than real files are skipped, since moving a shortcut with moveTo would relocate the shortcut object rather than the file it points to.
Testing
Create three test files named to match three different keywords, run moveFilesByName, and check each destination folder contains exactly the file meant for it.
Add a fourth file with a name that matches nothing in ROUTES and confirm it remains in the source folder untouched after the run.
Hardening
Log every move as a row in a tracking sheet with the original name, matched keyword, and destination folder, so you have an audit trail if a file ever ends up in the wrong place.
Add a dry-run flag that logs intended moves without calling moveTo, letting you validate a new keyword rule against real files before it actually reorganizes anything.
Variations
Match against file metadata such as MIME type in addition to filename keywords when the type of file matters more than what it happens to be called.
Combine this script with the share-file tutorial so a file is both moved to its destination folder and shared with the right group in the same pass.
moveFilesByName.gs
moveFilesByName scans a source folder's files, matches each filename against an ordered list of keywords, and relocates the first match to its mapped destination folder.
// Move Drive files into folders based on filename keywords
function moveFilesByName() {
var SOURCE_FOLDER_ID = 'REPLACE_WITH_SOURCE_ID';
var ROUTES = [
{ keyword: 'invoice', folderId: 'REPLACE_WITH_INVOICE_FOLDER_ID' },
{ keyword: 'contract', folderId: 'REPLACE_WITH_CONTRACT_FOLDER_ID' },
{ keyword: 'report', folderId: 'REPLACE_WITH_REPORT_FOLDER_ID' }
];
var source = DriveApp.getFolderById(SOURCE_FOLDER_ID);
var files = source.getFiles();
while (files.hasNext()) {
var file = files.next();
var name = file.getName().toLowerCase();
for (var i = 0; i < ROUTES.length; i++) {
if (name.indexOf(ROUTES[i].keyword) !== -1) {
var destination = DriveApp.getFolderById(ROUTES[i].folderId);
file.moveTo(destination);
break;
}
}
}
}- Line 4: ROUTES is checked top to bottom, so listing more specific keywords earlier avoids a generic keyword grabbing a file first.
- Line 15: Lowercasing the filename before comparison makes the keyword match case-insensitive without any extra configuration.
- Line 17: indexOf looks for the keyword anywhere in the filename rather than requiring it to be an exact match or a specific position.
- Line 19: moveTo relocates the file in place, changing its parent folder rather than creating a duplicate copy in the destination.
- Line 20: Breaking out of the loop after the first match ensures a file is only ever moved once per run, even if it could match more than one keyword.
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: move files by name
- 1Source folder ID copied from its Drive URL
- 2Destination folder created and ID copied for each category
- 3ROUTES array filled in with keyword-to-folder mappings
- 4Order of ROUTES reviewed so specific keywords come first
- 5Test files created with names matching each keyword
- 6Unmatched file confirmed to remain in the source folder
Frequently asked questions
The file moves to the destination tied to whichever keyword appears first in the ROUTES array, so ordering matters for overlapping keywords.
No, the example only iterates over files with getFiles; extend it with getFolders if you also need to route subfolders.
The example lowercases the filename before comparing, so matching is case-insensitive by default; remove the toLowerCase call if you need exact case matching.
Shortcuts are skipped in the hardening notes since moving a shortcut would relocate the shortcut object rather than the file it points to.
Add the dry-run flag described in the hardening section to log intended moves without calling moveTo.
Yes, but you would need an extra getFoldersByName lookup per route, which is slower than storing IDs directly if the destination folders rarely change.