A CLI tool that downloads email attachments from Gmail and packages them into a ZIP file. Built with TypeScript and Bun runtime.
- Search emails using Gmail's powerful query syntax
- Download all attachments from matching emails
- Package attachments into a single ZIP file
- Automatic handling of duplicate filenames
- Progress display during download
- Retry logic for rate limits and transient errors
- Bun runtime (v1.0 or later)
- A Google Cloud project with Gmail API enabled
- OAuth 2.0 credentials
-
Clone the repository:
git clone https://github.com/andreacanton/gmail-attachments-downloader.git cd gmail-attachments-downloader -
Install dependencies:
bun install
-
Set up Google Cloud credentials:
- Go to the Google Cloud Console
- Create a new project (or select an existing one)
- Enable the Gmail API
- Go to APIs & Services > Credentials
- Click Create Credentials > OAuth client ID
- Select Desktop app as the application type
- Download the credentials and save as
credentials.jsonin the project root
bun run src/index.ts <query> [options]| Argument | Description |
|---|---|
<query> |
Gmail search query (required) |
| Option | Description |
|---|---|
-o, --output <file> |
Output ZIP filename (default: attachments.zip) |
-h, --help |
Show help message |
Download all attachments from a specific sender:
bun run src/index.ts "from:sender@example.com has:attachment"Download attachments larger than 1MB:
bun run src/index.ts "has:attachment larger:1M" -o large-files.zipDownload invoice attachments from 2024:
bun run src/index.ts "subject:invoice has:attachment after:2024/01/01" --output invoices.zip| Operator | Description | Example |
|---|---|---|
from: |
Sender email | from:boss@company.com |
to: |
Recipient email | to:me@example.com |
subject: |
Words in subject | subject:meeting |
filename: |
Attachment filename | filename:pdf |
larger: |
Size larger than | larger:5M |
smaller: |
Size smaller than | smaller:1M |
after: |
After date | after:2024/01/01 |
before: |
Before date | before:2024/12/31 |
is:unread |
Unread emails | is:unread |
label: |
Has label | label:important |
Note: has:attachment is supported but added automatically
Combine operators for precise searches:
bun run src/index.ts "from:reports@company.com filename:pdf after:2024/01/01"On first run, the tool will:
- Open a URL in your terminal for Google authorization
- Ask you to visit the URL and sign in with your Google account
- Grant the app permission to read your emails (readonly access)
- Paste the authorization code back into the terminal
After authorization, a token.json file is created to cache your credentials for future runs.
| Code | Description |
|---|---|
| 0 | Success |
| 1 | User error (missing query, invalid arguments) |
| 2 | Authentication error |
| 3 | Gmail API error |
| 4 | File system error |
Make sure you've downloaded your OAuth credentials from Google Cloud Console and saved them as credentials.json in the project root.
Check your Gmail query syntax. Test the query in Gmail's web interface first to verify it works.
Check that you have write permissions in the output directory.
The tool automatically retries on rate limits with exponential backoff. If you're processing many emails, it may take longer due to API limits.
Delete token.json and run the tool again to re-authorize.
# Type check
bun run tsc --noEmit
# Run the tool
bun run src/index.ts "has:attachment" -o test.zipMIT