Gmail + NAS automation

Save invoice and receipt attachments from Gmail to your NAS automatically.

A self-hosted Go web service with a browser UI. Define rules, connect Gmail accounts, and let the scheduler handle the rest.

What it does
  • Web UI — manage everything from a browser
  • Rules with Gmail query builder + inline validation
  • Structured subfolder templates (date, sender, subject)
  • PDF → PNG conversion via poppler
  • Multiple Gmail accounts and SMB shares per rule
  • Built-in scheduler with configurable interval

Features

Browser-based UI

Create and manage rules, accounts, and file shares from any browser. No CLI required.

Gmail query builder

Visual query builder with inline validation warns about unknown operators or bad values as you type.

Structured storage

Subfolder templates use {year}, {month}, {sender}, and more.

PDF conversion

Automatically convert saved PDFs to PNG images at 150 DPI using poppler-utils.

Multi-account

Connect several Gmail accounts and assign each rule to multiple accounts and shares simultaneously.

Single Docker image

One container ships the Go backend, embedded SolidJS UI, SQLite database, and poppler.

Quick Start

The fastest way to run the service is with Docker Compose. Copy this into a docker-compose.yml:

services:
  gmail-nas:
    image: ghcr.io/pacorreia/export-gmail-attachments-to-nas:latest
    ports:
      - "8080:8080"
    volumes:
      - ./data:/data
    environment:
      SECRET_KEY: "change-me-to-a-random-string"
      GOOGLE_CLIENT_ID: "your-client-id.apps.googleusercontent.com"
      GOOGLE_CLIENT_SECRET: "your-client-secret"
      # PORT defaults to 8080
      # DATABASE_URL defaults to sqlite:///data/app.db

Then start it:

docker compose up -d
# Open http://localhost:8080 in your browser

On first run, open Settings → Accounts to connect a Gmail account via OAuth, then create your first rule under Rules.

Google OAuth Setup

The service uses OAuth 2.0 to access Gmail on behalf of each connected account. You need to create credentials in Google Cloud Console once.

1. Create a Google Cloud Project

  1. Go to Google Cloud Console
  2. Click Select a ProjectNew Project
  3. Enter a project name (e.g., "Gmail Attachments Export") and click Create

2. Enable the Gmail API

  1. Navigate to APIs & ServicesLibrary
  2. Search for "Gmail API" and click Enable

3. Create OAuth 2.0 Credentials

  1. Go to APIs & ServicesCredentials+ Create CredentialsOAuth client ID
  2. If prompted, configure the consent screen: choose External, fill in the app name, and add the scope https://mail.google.com/
  3. Set the application type to Web application
  4. Add an authorized redirect URI: http://localhost:8080/oauth/callback (or your public URL)
  5. Click Create and copy the Client ID and Client Secret

4. Configure the service

  1. Set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET environment variables (or update your docker-compose.yml)
  2. Restart the container, then open the UI and go to Settings → Accounts → Add Account
  3. Complete the Gmail consent flow in the browser — the token is stored encrypted in the database

Environment Variables

VariableRequiredDefaultDescription
SECRET_KEYEncryption key for OAuth tokens and SMB passwords (AES-256-GCM). Service will not start without it.
GOOGLE_CLIENT_IDGoogle Cloud OAuth2 client ID
GOOGLE_CLIENT_SECRETGoogle Cloud OAuth2 client secret
DATABASE_URLsqlite:///data/app.dbDatabase connection string. Supports sqlite://, postgres://, sqlserver://.
PORT8080HTTP port the server listens on.
OAUTH_REDIRECT_URLhttp://localhost:8080/oauth/callbackOAuth2 redirect URI — must match the Google Cloud console setting.

Security Notes

Secret key

Generate a strong random value: openssl rand -hex 32. Never reuse across environments.

Token encryption

OAuth tokens and SMB passwords are stored encrypted at rest with AES-256-GCM using your SECRET_KEY.

OAuth scope

The service requests the https://mail.google.com/ scope, which is the minimum needed for reading and optionally deleting messages.

NAS access

Limit SMB share permissions to a dedicated service account with write access only to the target folders.

Contributors

Thanks to all the amazing people who have contributed to this project!

Loading contributors...

Gmail + NAS automation

Save invoice and receipt attachments from Gmail to your NAS automatically.

A fast, focused Python tool to fetch matching emails, store attachments in structured folders, and optionally delete processed messages.

What it does
  • Search Gmail with filters and queries
  • Save attachments by sender and date
  • Optional content filtering
  • Convert attachments to txt, png, jpeg
  • Reliable, retry-backed uploads

Features

Query-driven selection

Define Gmail queries and attachment filters per rule. Keep it narrow and precise.

Structured storage

Attachments are saved by sender and date, making retrieval predictable.

Content filters

Scan PDF or text attachments for required phrases before saving.

Attachment conversion

Automatically convert saved PDFs to txt, png, or jpeg in a separate output folder.

Operational safety

Retries, logging, and optional delete-after-save keep runs clean.

Quick Start

pip install -r requirements.txt
python -m build
pip install .

export-gmail-attachments-to-nas \
  --username YOUR_NAS_USER \
  --password YOUR_NAS_PASSWORD \
  --credentials /path/to/credentials.json \
  --criteria /path/to/criteria.json

Criteria Configuration

Create a criteria.json file to define your email processing rules. Each entry in criteria is evaluated independently.

{
  "smb_server": "homenas.home.lan",
  "criteria": [
    {
      "enabled": true,
      "query": "{subject:Invoice subject:Receipt} filename:.pdf",
      "smb_folder": "\\documents\\invoices",
      "filters": [".pdf"],
      "attachment_content_filter": ["Invoice", "Total"],
      "delete_after_save": false,
      "convert": {
        "to": "txt",
        "output_folder": "\\documents\\invoices-txt",
        "extension_filter": [".pdf"],
        "filename_filter": "invoice.*"
      }
    }
  ]
}

Criteria fields

FieldRequiredDescription
enabledSet to false to skip this rule. Defaults to true.
queryGmail search query (supports all Gmail search operators).
smb_folderDestination folder on the SMB share.
filtersOptional list of file extensions to save (e.g. [".pdf"]). If omitted or empty, no attachments are saved for this rule.
attachment_content_filterSave only if the attachment contains at least one of these phrases (case-sensitive match).
delete_after_saveDelete the source email after a successful save. Defaults to false.
convertOptional block to convert attachments. See Convert section.

Attachment Conversion

Each rule can include a convert block to automatically convert saved attachments to another format and store the result in a separate output folder. Omitting it leaves the rule's behaviour unchanged.

Supported conversions

"convert": {
  "to": "txt",
  "output_folder": "\\documents\\converted",
  "extension_filter": [".pdf"],
  "filename_filter": "invoice.*"
}

Convert fields

FieldRequiredDescription
toTarget format: txt, png, jpeg, or jpg.
output_folderSMB folder path where converted files are saved.
extension_filterRestrict conversion to attachments with these extensions (e.g. [".pdf"]).
filename_filterRestrict conversion to filenames matching this regex (case-insensitive).

Google OAuth Setup

This tool requires Google OAuth credentials to access Gmail. Follow these steps to create them:

1. Create a Google Cloud Project

  1. Go to Google Cloud Console
  2. Click Select a ProjectNew Project
  3. Enter a project name (e.g., "Gmail Attachments Export")
  4. Click Create and wait for the project to initialize

2. Enable Gmail API

  1. In the Cloud Console, navigate to APIs & ServicesLibrary
  2. Search for "Gmail API"
  3. Click the Gmail API result
  4. Click Enable

3. Create OAuth 2.0 Credentials

  1. Go to APIs & ServicesCredentials
  2. Click + Create CredentialsOAuth client ID
  3. If prompted, configure the OAuth consent screen first:
    • Choose External user type
    • Fill in the required fields (app name, user support email)
    • Under scopes, add https://mail.google.com/
    • Save and continue
  4. Back to credentials, select Desktop application as the application type
  5. Click Create

4. Download Credentials

  1. In the Credentials page, find your newly created OAuth 2.0 Client ID
  2. Click the download icon (↓) to download the JSON file
  3. Save it as credentials.json in your project directory

5. First Run Authentication

  1. Run the tool for the first time with your credentials
  2. A browser window will open asking for Gmail access
  3. Click Allow to grant permissions
  4. The tool will create token.json automatically
  5. Keep both files secure and don't commit them to version control

Security Notes

Credentials

Store NAS credentials in env vars or pass them at runtime.

Token hygiene

Gmail tokens are stored locally in token.json. Treat it as sensitive.

Scope control

Use minimal required Gmail scope. Delete requires mail.google.com.

NAS access

Limit SMB share permissions to a dedicated account when possible.

Contributors

Thanks to all the amazing people who have contributed to this project!

Loading contributors...