File Gmail attachments into storage with names you can find
Every hour, new email attachments get sorted by document type and vendor, saved under clear names, and logged in a spreadsheet index.
Every hour, sweep my Gmail for new attachments and file them into General Input Storage under names I can actually find later. Run this on an hourly cron schedule.
Finding new mail: use Gmail's List Messages with a search query that combines has:attachment with a time bound covering the window since the last run, for example has:attachment after:<epoch seconds>. Use epoch-second bounds rather than calendar dates, otherwise an hourly sweep re-scans the entire day. Overlap the window by a few minutes so nothing is lost at the boundary; the dedupe step below makes that overlap safe.
Getting the bytes: Gmail exposes no separate attachment operation, so call Get a Message with format set to raw. That returns the whole RFC 2822 message base64url encoded, attachments included. Decode it in the sandbox and walk the MIME parts to pull out each attachment's filename, its real Content-Type, and its bytes. Base64url differs from standard base64, so translate - back to + and _ back to / before decoding.
Skip the junk before classifying anything. Drop parts marked Content-Disposition: inline, anything referenced by a cid: link in the HTML body, images smaller than roughly 20 KB, image parts with no real filename, and the usual signature artifacts such as image001.png. Signature graphics, logos, and tracking pixels must never reach storage; they are the main source of clutter in this pattern.
Classify what survives. Read the sender address and display name, the subject line, and the actual file contents to decide the document type (invoice, receipt, contract, statement, report) and which vendor or client it belongs to. When the subject and the document contents disagree, trust the document. Pull an identifying number when one is present, such as an invoice number or a statement period, since that is what makes the final name useful.
Build a descriptive, store-relative key like invoices/acme-corp/2026-08-invoice-1042.pdf. Lowercase and hyphenate vendor names. Keys use forward slashes only, with no leading slash, no . or .. segments, and a maximum of 1024 characters. Keep the original file extension.
Dedupe in two layers, because one is not enough. First, read the index with Google Sheets Get Values and collect the email message id and attachment filename pairs already recorded, then skip anything present. Second, call Storage's Stat Object on the candidate key before uploading, since it checks existence without downloading. The index check is the load-bearing one: classification can drift slightly between runs and produce a different key for the very same file, which a key-only check would sail straight past and file twice.
Upload with Presign Upload, passing the real sizeBytes because that is what the quota check uses, then PUT the bytes to the returned URL with the returned headers. The Content-Type sent on that PUT is what the object is stored as, so set it from the attachment's actual MIME type rather than a generic fallback. Presigned URLs expire after 15 minutes, so mint one per file and never reuse or store them.
Append a row to the Google Sheets index with Append Values: the date received, the sender, the subject, the document type, the vendor or client, the storage key, and the Gmail message id. The message id column is what keeps re-runs safe, so never omit it.
Anything that cannot be confidently classified goes under an unsorted/ prefix with its original filename preserved, and still gets an index row so it is never invisible. At the end of the sweep, if anything landed in unsorted, post one Slack message with the Slack Bot's Send a Message listing each file, its sender, and the reason it could not be placed, so a person can move it. Send nothing when everything classified cleanly; no empty all-clear pings.
Never trash, relabel, or otherwise modify the source email. This workflow only reads mail.
What does this prompt do?
- Checks your inbox every hour for new mail carrying attachments, so files get archived without anyone downloading and re-uploading them by hand
- Reads each file along with who sent it and what the subject says, then works out whether it is an invoice, receipt, contract, statement, or report and which vendor or client it belongs to
- Saves every file under a clear, searchable name like invoices / acme-corp / 2026-08-invoice-1042.pdf, and checks first so a repeat run never files the same attachment twice
- Logs each file in a spreadsheet index and posts a Slack note listing anything it could not confidently place, while skipping email signatures, logos, and tracking images
What do I need to use this?
- A Gmail account holding the mail you want archived
- A General Input storage space to keep the files in
- A Google Sheet to act as the running index
- A Slack workspace where flags about unclear files should land
How can I customize it?
- Change how often the sweep runs. Hourly suits a busy inbox, while a few times a day is plenty for lighter volume
- Adjust the document types and the folder naming pattern so they match how your team already files things
- Narrow the sweep to certain senders or labels, for example only mail from your suppliers, and pick which Slack channel gets the flags
FAQs
Will it save the same attachment twice if it runs again?
What happens to files it cannot identify?
Does it archive email signatures and company logos?
Will this change or delete any of my email?
What kinds of documents can it recognize?
Related templates
Every weekday at 10am, an AI voice agent phones your most overdue Xero accounts, logs what each customer promised, and reports back to finance in Slack.
See every Google Maps listing you manage on one screen, ranked worst first, with an audit button that writes the fix list for you.
Every couple of hours we find the chats your team never answered, email those visitors a real reply, and hand the sensitive ones to a support lead.
Your team picks a template, finds the customer, checks they are safe to email, then sends it, with every send logged where the whole team can see it.
Every logo, photo, video cut and ad export in one searchable grid, with previews, campaign tags and rights expiry dates at a glance.
Twice a day we spot the people clicking your pricing and demo pages, create a follow-up task for their owner, and post a ranked recap to Slack.
Stop digging through email for that one PDF.
Let every invoice, contract, and statement file itself the moment it arrives, under a name you will actually recognize months later.