Hide emails from specific senders outside of business hours and surface them during business hours. Uses Gmail API filters and labels to silently park emails — no notifications fire outside your configured visibility window.
- At visible end (e.g. 5 PM): Creates a Gmail filter that skips the inbox for the sender's emails, applies a "Parked/Name" label, and sweeps any existing inbox emails from that sender.
- At visible start (e.g. 9 AM): Deletes the filter so new emails arrive normally, and moves all parked emails back to the inbox.
- Read/unread status is never modified — only INBOX and Parked labels are changed.
- Go to Google Cloud Console
- Create a new project (or select existing)
- Enable the Gmail API: APIs & Services → Enable APIs → search "Gmail API" → Enable
- Create OAuth credentials:
- APIs & Services → Credentials → Create Credentials → OAuth 2.0 Client ID
- Application type: Desktop app
- Download the JSON file
- Configure the OAuth consent screen if prompted (add your email as a test user)
# Create data volume directory and add credentials
docker compose run --rm gmail-parker sh -c "mkdir -p /data"
# Copy your downloaded credentials.json into the volume
# Option: mount a local directory instead
# Or copy directly:
docker cp credentials.json gmail-parker:/data/credentials.json
# Run interactive OAuth setup (opens browser for auth)
docker compose run --rm -p 8080:8080 gmail-parker python -m gmail_parker.cli setup
# Start the daemon
docker compose up -d
# View the web UI
open http://localhost:8081pip install -e .
# Place credentials.json in ~/.gmail-parker/
mkdir -p ~/.gmail-parker
cp credentials.json ~/.gmail-parker/
# Authenticate
gmail-parker setup
# Add a rule
gmail-parker config add --sender user@example.com --name "User"
# Check status
gmail-parker status
# Manual operations
gmail-parker park # Park now
gmail-parker unpark # Unpark now
gmail-parker park --force # Park even during visible hoursgmail-parker setup # OAuth flow + initial setup
gmail-parker park [--force] # Create filter, sweep inbox
gmail-parker unpark [--force] # Delete filter, restore emails
gmail-parker status # Show current state
gmail-parker config show # Show configuration
gmail-parker config set-timezone America/Chicago
gmail-parker config add --sender user@example.com --name "User" --start 09:00 --end 17:00
gmail-parker config remove <rule-id>
The web interface runs on port 8081 (configurable) and provides:
- Dashboard: View all rules, their status, and parked email counts
- Add/Edit Rules: Configure sender, visibility window, and active days
- Settings: Change timezone, view auth status
Optional basic auth: set GMAIL_PARKER_AUTH=user:password environment variable.
Stored in $GMAIL_PARKER_HOME/config.json (default: ~/.gmail-parker/config.json):
{
"timezone": "America/New_York",
"web_port": 8081,
"rules": [
{
"id": "uuid",
"sender_email": "user@example.com",
"sender_name": "User",
"schedule": {
"visible_start": "09:00",
"visible_end": "17:00",
"visible_days": [0, 1, 2, 3, 4]
},
"enabled": true,
"label_name": "Parked/User",
"filter_id": null,
"label_id": null
}
]
}Days: 0=Monday through 6=Sunday.
docker compose up -d # Start daemon + web UI
docker compose logs -f # View logs
docker compose exec gmail-parker gmail-parker status
docker compose down # StopThe Docker container runs a single Python process that:
- Starts the FastAPI web server (uvicorn) for the configuration UI
- Runs APScheduler with per-rule CronTriggers for automated park/unpark
- On startup, evaluates all rules against current time and corrects state immediately
- Logs a heartbeat every hour
- Handles SIGTERM for clean Docker stops