Recipe
Save Gmail attachments to Google Drive automatically
Every hour the script finds recent mail with attachments, copies each attachment into one Drive folder with a date prefix, and labels the thread so it is not processed twice.
Set it up
- Make a Drive folder and copy its ID from the address bar (the text after /folders/).
- Open script.google.com, paste the script, set folderId in GA, and save.
- Triggers > Add trigger > saveAttachments > Time-driven > Hour timer > Every hour. Approve the prompts.
The script
/**
* Save Gmail attachments to one Drive folder, then label the thread.
* Set folderId, then add a time-driven trigger (every hour) for saveAttachments.
*/
var GA = { query: 'has:attachment -label:saved-to-drive newer_than:7d', folderId: 'PASTE_FOLDER_ID', label: 'saved-to-drive', maxThreads: 20 };
function saveAttachments() {
var folder = DriveApp.getFolderById(GA.folderId);
var label = GmailApp.getUserLabelByName(GA.label) || GmailApp.createLabel(GA.label);
var threads = GmailApp.search(GA.query, 0, GA.maxThreads);
var saved = 0;
threads.forEach(function (thread) {
thread.getMessages().forEach(function (msg) {
msg.getAttachments({ includeInlineImages: false }).forEach(function (att) {
var day = Utilities.formatDate(msg.getDate(), Session.getScriptTimeZone(), 'yyyy-MM-dd');
folder.createFile(att.copyBlob()).setName(day + ' ' + att.getName());
saved++;
});
});
thread.addLabel(label);
});
return saved;
}What you should see
| File | Saved |
|---|---|
| 2026-11-12 invoice-1043.pdf | yes |
| 2026-11-13 timesheet.csv | yes |
Drive folder after one run. Sample values, not output from a real account.
Common errors and fixes
- Exception: No item with the given ID could be found
- folderId is wrong, or the account has no access to that folder.
- Exceeded maximum execution time
- Lower maxThreads to 10. See the fix page for batching.
- Attachments are saved again
- The label saved-to-drive was removed from the thread, or the search no longer excludes it.
Permissions. Running this script asks you to grant Google permissions for the services listed above, to your own script. TriggerShelf never receives your Google data. See the permissions table. Google will show "Google hasn't verified this app"; that is expected for a script you paste yourself.
TriggerShelf is independent and not affiliated with or endorsed by Google LLC. Google Sheets, Gmail, Google Drive and Apps Script are trademarks of Google LLC. Quota figures come from Google's Apps Script quotas page. Test on a copy first.