Overview
The Obsidian Gmail script automatically syncs your labeled Gmail emails to your Obsidian vault as formatted markdown notes. It uses Gmail's IMAP interface with OAuth 2.0 for secure authentication, including support for Google Workspace SSO.
What You'll Get
- Automatic Email Ingestion - Labeled emails are saved as markdown in your vault
- Deduplication - Never creates duplicate notes; updates in-place when content changes
- Rich Metadata - YAML frontmatter with sender, recipients, date, labels, and Gmail link
- Organized Structure - Emails organized by year and quarter (e.g.,
Emails/2025/Q425/) - Slack Thread Support - Special handling for Slack notification emails
How It Works
- Label Emails - Apply a "Save" or "AI/Ingest" label to emails you want to capture
- Run the Script - The script fetches labeled emails via IMAP
- Convert to Markdown - Emails are converted to clean markdown with frontmatter
- Save to Obsidian - Notes are saved to your vault's Emails folder
Installation
Ready to set up Obsidian Gmail?
This setup requires Gmail OAuth credentials and takes about 10-15 minutes. You'll need to create a Google Cloud project with IMAP access.
Prerequisites
Let's make sure you have the required tools installed.
Do you have Python 3.8+ installed?
Google OAuth Setup
Create OAuth credentials for Gmail IMAP access.
Install Python Dependencies
Install the required Python libraries.
Download the Script
Get the Gmail to Obsidian ingestion script.
First Run & Authentication
Authenticate with Gmail and test the script.
Setup Complete!
Obsidian Gmail is ready to use.
Run the script to sync labeled emails to your Obsidian vault.
Scroll down to see usage examples.
Usage
Basic Usage
Run the script to sync emails with the "Save" label:
python3 ~/scripts/ai_scripts/imap_ingest_md_only.py Command Line Options
# Sync with specific labels
python3 ~/scripts/ai_scripts/imap_ingest_md_only.py --labels "Save" "Important"
# Sync emails from the last 30 days
python3 ~/scripts/ai_scripts/imap_ingest_md_only.py --since 30d
# Dry run (show what would be synced without creating files)
python3 ~/scripts/ai_scripts/imap_ingest_md_only.py --dry-run
# Limit to 100 emails
python3 ~/scripts/ai_scripts/imap_ingest_md_only.py --max 100
# Use a different vault
python3 ~/scripts/ai_scripts/imap_ingest_md_only.py --vault-root ~/Obsidian/WorkVault Output Format
The generated Obsidian note follows this structure:
---
type: email
source: imap/gmail
gmail:
x_gm_msgid: "1234567890"
x_gm_thrid: "1234567890"
message_id: "unique-message-id@mail.gmail.com"
subject: "Meeting Follow-up: Q4 Planning"
from: {"name": "Jane Smith", "email": "jane@example.com"}
to: [{"name": "You", "email": "you@gmail.com"}]
cc: []
date: 2025-12-15T10:30:00-05:00
labels: ["Save", "Work"]
attachments: []
checksum: "sha256:abc123..."
ingested_at: 2025-12-15T15:45:00Z
canonical_url: "https://mail.google.com/mail/u/0/#inbox/1234567890"
---
Hi,
Following up on our Q4 planning meeting...
Best,
Jane Gmail Labels
The script recognizes these Gmail labels:
SaveorAI/Ingest- Standard email ingestionSlack-ThreadorAI/Slack-Thread- Slack notification emails (marked as type: slack)
Create these labels in Gmail and apply them to emails you want to sync.
Configuration
Script Configuration
Edit the script to customize these settings:
# Line 38: Your Gmail address
os.environ['GMAIL_USER'] = 'your-email@gmail.com'
# Line 40: Your Obsidian vault root
DEFAULT_VAULT_ROOT = "~/Obsidian/YourVault"
# Line 41-42: Folder structure
EMAILS_DIR = "Emails"
ASSETS_DIR = "Assets/Emails" Automation with cron
Run automatically every hour:
# Edit crontab
crontab -e
# Add this line (runs every hour)
0 * * * * /usr/bin/python3 ~/scripts/ai_scripts/imap_ingest_md_only.py >> ~/logs/gmail-sync.log 2>&1 Downloads
Prefer to install manually? Download the script directly:
Troubleshooting
Error: Credentials file not found
Ensure your OAuth client file is at ~/scripts/ai_scripts/client_secret.json.
Download it from the Google Cloud Console.
Error: Token refresh failed
Delete ~/scripts/ai_scripts/gmail_oauth_token.json and run the script again to re-authenticate.
Error: GMAIL_USER not set
Either edit line 38 in the script to set your email, or set the environment variable:
export GMAIL_USER='your-email@gmail.com'
No emails found
Make sure you've applied the "Save" label to emails in Gmail. The script only syncs labeled emails.
Duplicate files appearing
The script uses deduplication based on Gmail message IDs. If you see duplicates, delete
.imap_ingest_index.json in your vault root and run again.