A Python-based tool that parses notes from multiple sources (Google Keep, Apple Notes) and syncs them to a Notion database.
This project provides an automated workflow to migrate and manage your notes from various sources in Notion. It handles parsing, formatting, deduplication, and timestamping of notes from Google Keep and Apple Notes.
What's Included:
- Parse Google Keep JSON files (title, content, labels, creation date)
- Parse Apple Notes markdown folders (title, content with source label)
- Sync notes to Notion database with duplicate detection
- Automatic timestamp extraction and population (Google Keep)
- Cleanup utility to remove duplicate entries
- Validation tools to test Notion API connection
- Multi-source note consolidation
What's NOT Included:
- HTML files (kept for reference only)
- Images (stored locally but not uploaded)
- Real-time synchronization
- Python 3.9+
- Virtual environment (already configured)
- Notion account with API access
-
Install dependencies:
pip install -r requirements.txt
-
Create Notion integration:
- Go to Notion Developers
- Create a new integration and copy your token
- Create a Notion database with columns:
Title(text),Content(text),Labels(multi-select),Created Date(date) - Share the database with your integration
-
Configure credentials:
- Copy
.env.exampleto.env - Add your Notion API token and database ID:
NOTION_API_TOKEN=your_token_here NOTION_DATABASE_ID=your_database_id_here
- Copy
-
Prepare data:
- Create
data/google_notes/anddata/apple_notes/folders in the project root - Export your Google Keep notes via Google Takeout and place JSON files in
data/google_notes/ - Export your Apple Notes as markdown folders and place them in
data/apple_notes/ - Note: The
data/folder is excluded from version control to protect your personal information
- Create
Extracts data from JSON files. Automatically called by sync scripts.
python src/parser.pyExtracts data from markdown folders. Automatically called by sync scripts.
python src/apple_notes_parser.pyUploads Google Keep notes to your Notion database with duplicate detection.
python src/notion_sync.pyUploads Apple Notes to your Notion database with duplicate detection.
python src/apple_notes_sync.pyOutput:
- ✓ Synced - New note created
- ⊘ Skipped - Note already exists
- ✗ Failed - Error creating note
Removes duplicate notes from Notion (keeps first, archives rest).
python src/cleanup_duplicates.pyTests Notion API connection and database access.
python src/validate_notion.pyAdds creation dates to existing notes from JSON files.
python src/update_timestamps.pygkeep_notion_integration/
├── data/
│ ├── google_notes/ # Google Keep JSON/HTML exports (342 notes)
│ └── apple_notes/ # Apple Notes markdown folders
├── src/
│ ├── parser.py # Parse Google Keep JSON files
│ ├── apple_notes_parser.py # Parse Apple Notes markdown
│ ├── notion_sync.py # Sync Google Keep to Notion
│ ├── apple_notes_sync.py # Sync Apple Notes to Notion
│ ├── cleanup_duplicates.py # Remove duplicates
│ ├── update_timestamps.py # Add creation dates
│ ├── validate_notion.py # Test connection
│ └── test_create.py # Test page creation
├── .env # Credentials (DO NOT COMMIT)
├── .env.example # Template
├── .gitignore # Git ignore rules
├── requirements.txt # Python dependencies
└── README.md # This file
| Field | Source | Notion Field | Type |
|---|---|---|---|
| Title | Keep title | Title | Text |
| Content | Keep text/checklist | Content | Text |
| Labels | Keep labels | Labels | Multi-select |
| Created Date | createdTimestampUsec | Created Date | Date |
| Field | Source | Notion Field | Type |
|---|---|---|---|
| Title | Folder name | Title | Text |
| Content | Markdown file content | Content | Text |
| Labels | "Apple Notes" (source label) | Labels | Multi-select |
| Created Date | Not available | Created Date | Date |
- Duplicate Detection: Based on matching title + content across all sources
- Character Limits: Titles limited to 100 chars, content to 2000 chars
- Timestamps: Google Keep timestamps converted from microseconds to ISO format
- Checklists: Formatted as
[x] itemor[ ] item(Google Keep) - Source Labels: Apple Notes automatically tagged with "Apple Notes" label for easy filtering
- Multi-source: Consolidates notes from Google Keep and Apple Notes into single Notion database
.envfile contains sensitive credentials (Notion API token and database ID)data/folder contains your personal notes- Both are excluded from version control via
.gitignore - Never commit
.envor personal data to version control - When cloning this repo, you'll need to create your own
.envanddata/folders
"API token is invalid"
- Verify token is correct and not expired
- Confirm database is shared with integration in Notion
"Title is expected to be rich_text"
- Ensure your Notion database has correct column types
- Title column must be type "Title" (not text)
No notes found
- For Google Keep: Verify JSON files are in
data/google_notes/folder - For Apple Notes: Verify markdown folders are in
data/apple_notes/folder - Check file format from respective exports
- Additional note sources (Evernote, OneNote, etc.)
- Image upload support
- Scheduled/automated sync
- HTML content parsing
- Archive vs. delete option
- Bulk note update capability
- Timestamp extraction for Apple Notes
- Attachment handling for both sources
Personal use project
For issues, check:
.envcredentials- Notion database schema
- JSON file format from Takeout
- Run
validate_notion.pyto test connection