Automatically synchronize Google Docs (from one Google account) with Markdown files in your Obsidian vault (stored in another Google account's Drive).
Local Obsidian Vault (/Users/weilinchen/Documents/CEsecondbrain)
↕ (Obsidian Sync - for multi-device sync)
Other Devices
Local Obsidian Vault
↕ (Google Drive Desktop Client - Account B)
Google Drive Account B (Vault Copy)
↕ (Railway - This Sync Program)
Google Drive Account A (Google Docs)
- Bi-directional sync: Changes in Google Docs → Markdown, and Markdown → Google Docs
- Conflict detection: Alerts when both sides are modified simultaneously
- Automatic conversion: Google Docs HTML → Markdown with proper formatting
- Scheduled polling: Configurable sync interval
- Railway deployment: Runs in the cloud, no local machine needed
- Multi-account support: Different Google accounts for Docs and Vault
-
Two Google accounts:
- Account A: Contains your Google Docs
- Account B: Contains your Obsidian vault in Google Drive
-
Google Drive Desktop Client installed (logged in with Account B)
-
Obsidian vault synced to Google Drive via Desktop Client
-
Install dependencies:
pip install -r requirements.txt
-
Set up Google Cloud credentials (see SETUP_GUIDE.md)
-
Create config file:
cp config.yaml.example config.yaml # Edit config.yaml with your settings -
Set environment variables:
export ACCOUNT_A_CREDENTIALS_PATH="path/to/account_a_service_account.json" export ACCOUNT_B_CREDENTIALS_PATH="path/to/account_b_service_account.json"
-
Run sync:
# Run once python sync.py --once # Run continuously with 5-minute interval python sync.py --interval 300 # Show status python sync.py --status
-
Push to GitHub:
git init git add . git commit -m "Initial commit" git remote add origin https://github.com/yourusername/your-repo.git git push -u origin main
-
Deploy to Railway:
- Connect your GitHub repository
- Set environment variables (see SETUP_GUIDE.md)
- Deploy as Worker
-
Configure environment variables in Railway:
ACCOUNT_A_CREDENTIALS: Service Account JSON (Account A)ACCOUNT_B_CREDENTIALS: Service Account JSON (Account B)VAULT_FOLDER_ID: Google Drive folder ID for vaultCONFIG_YAML: Your config.yaml content (or use file)SYNC_INTERVAL: Sync interval in seconds (e.g., 300)
Edit config.yaml:
sync_interval: 300 # seconds
vault_folder_id: "your_vault_folder_id"
mappings:
- doc_id: "google_doc_id_from_account_a"
vault_path: "path/in/vault.md"- Google Doc ID: From URL
https://docs.google.com/document/d/DOC_ID/edit - Folder ID: From URL
https://drive.google.com/drive/folders/FOLDER_ID
python sync.py [OPTIONS]
Options:
--config PATH Path to config file (default: config.yaml)
--once Run sync once and exit
--interval SEC Sync interval in seconds
--status Show current sync status
--debug Enable debug loggingWhen both Google Doc and Markdown are modified since last sync:
- Sync will detect the conflict and log it
- Check
conflicts.logfor details - Manually review and resolve (keep one version or merge)
- Next sync will proceed based on modification times
.
├── sync.py # Main entry point
├── modules/
│ ├── auth.py # Google authentication
│ ├── gdrive_client.py # Drive API wrapper
│ ├── converter.py # Doc ↔ Markdown conversion
│ ├── sync_engine.py # Core sync logic
│ └── conflict_handler.py # Conflict management
├── config.yaml.example # Configuration template
├── requirements.txt # Python dependencies
├── Procfile # Railway deployment
└── README.md # This file
- Polling: Every X seconds, check all mapped files
- Change Detection: Compare modification times with last sync
- Direction Determination:
- If only Doc changed → sync to Markdown
- If only Markdown changed → sync to Doc
- If both changed → flag as conflict
- Conversion:
- Doc → Markdown: Export as HTML, convert with markdownify
- Markdown → Doc: Convert to plain text, update via Docs API
- State Tracking: Save sync state to
.sync_state.jsonin vault
- Verify Service Account credentials are valid
- Check that Service Accounts have access to both Google Drives
- Ensure API scopes include Drive and Docs
- Check logs for error messages
- Verify vault_folder_id is correct
- Ensure mappings use correct doc_id and vault_path
- Test with
--onceand--debugflags
- Review
conflicts.log - Manually resolve by editing one version
- Next sync will detect the newer version
For issues, questions, or contributions:
- Check SETUP_GUIDE.md for detailed setup instructions
- Review logs with
--debugflag - Check Railway logs if deployed
MIT