This project converts Twitter/X bookmarks exported as JSON into a CSV format compatible with Raindrop.io, using OpenAI's GPT-3.5-turbo for intelligent title generation and folder/tag reclassification.
Supports two export formats:
- Twitter Bookmark Exporter (Chrome extension) - July 2025
- BirdBear (app/extension) - August 2025
Transform JSON files containing Twitter bookmarks into a clean, organized CSV that can be imported into Raindrop.io with:
- Intelligent title generation (concise one-liners)
- Smart folder and tag reclassification
- Proper nested folder structure under "X/"
- Clean tag taxonomy (removing low-usage tags)
X Bookmarks to Raindrop/
βββ README.md # This file
βββ sources/ # Source JSON export files
β βββ twitter_exporter/ # Twitter Bookmark Exporter format
β β βββ twitter_bookmarks.json # Original export
β β βββ twitter_bookmarks_tagged_full.json # Manually enhanced (1,778 bookmarks)
β βββ birdbear/ # BirdBear format
β βββ birdbear-export-2025-08-16T21_20_47.259Z.json
βββ scripts/ # Python conversion scripts
β βββ shared/ # Scripts that work with both formats
β β βββ reclassify_with_openai.py # Main conversion script (supports both formats)
β β βββ analyze_folders_tags.py # Extract folders/tags from JSON
β β βββ analyze_tags.py # Analyze tag usage in CSV
β β βββ clean_tags.py # Remove low-usage tags
β β βββ setup_openai.py # OpenAI API key setup utility
β βββ twitter_exporter/ # Scripts specific to Twitter Exporter format
β βββ json_to_raindrop_csv.py # Basic conversion with OpenAI titles
β βββ create_clean_csv.py # Clean CSV generation
β βββ create_raindrop_json.py # JSON format generation
βββ outputs/ # Generated CSV/JSON files
β βββ twitter_exporter/ # Outputs from Twitter Exporter format
β β βββ raindrop_format.csv # Final output (all bookmarks)
β β βββ raindrop_cleaned.csv # Cleaned output (tags with β₯5 uses)
β β βββ [other CSV variations]
β βββ birdbear/ # Outputs from BirdBear format
β β βββ birdbear_reclassified.csv
β βββ test/ # Test/sample outputs
β βββ test_*.csv
βββ references/ # Reference files and configuration
βββ APIKEY.txt # OpenAI API key (user-provided)
βββ folders_list.txt # Extracted folder list for AI prompts
βββ tags_list.txt # Extracted tag list for AI prompts
pip install openaiOPENAI_API_KEY: Your OpenAI API key (set viascripts/shared/setup_openai.pyor manually)
- Source: Chrome extension "Twitter Bookmark Exporter"
- Format: Array of bookmark objects with
text,author,timestamp,link,id - Files:
sources/twitter_exporter/twitter_bookmarks.json - Scripts:
scripts/twitter_exporter/*.pyorscripts/shared/reclassify_with_openai.py
- Source: BirdBear app/extension
- Format: JSON object with
version,exported_at,tweetsarray containing full tweet metadata - Files:
sources/birdbear/birdbear-export-*.json - Scripts:
scripts/shared/reclassify_with_openai.py(auto-detects format)
python3 scripts/shared/setup_openai.pyOr manually set: export OPENAI_API_KEY="your-key-here"
If you've exported bookmarks again and there's overlap with a previous export:
# Remove duplicates from newer export
python3 scripts/twitter_exporter/deduplicate_exports.py \
sources/twitter_exporter/older_export.json \
sources/twitter_exporter/newer_export.json \
-o sources/twitter_exporter/new_bookmarks_only.json- Start with
sources/twitter_exporter/twitter_bookmarks.json(original export) - Manually add
"folder"and"tags"fields to each bookmark - Save as
sources/twitter_exporter/twitter_bookmarks_tagged_full.json
python3 scripts/shared/analyze_folders_tags.py# Using the universal script (recommended)
python3 scripts/shared/reclassify_with_openai.py sources/twitter_exporter/twitter_bookmarks.json -o outputs/twitter_exporter/raindrop_reclassified.csv
# Or using format-specific script
python3 scripts/twitter_exporter/json_to_raindrop_csv.pypython3 scripts/shared/clean_tags.py outputs/twitter_exporter/raindrop_format.csv outputs/twitter_exporter/raindrop_cleaned.csvpython3 scripts/shared/setup_openai.py# Auto-detects BirdBear format
python3 scripts/shared/reclassify_with_openai.py sources/birdbear/birdbear-export-*.json -o outputs/birdbear/birdbear_reclassified.csv
# Test with first 10 bookmarks
python3 scripts/shared/reclassify_with_openai.py sources/birdbear/birdbear-export-*.json -o outputs/test/test_birdbear.csv -t 10python3 scripts/shared/clean_tags.py outputs/birdbear/birdbear_reclassified.csv outputs/birdbear/birdbear_cleaned.csvUpload the cleaned CSV file from outputs/ to Raindrop.io
Purpose: Universal conversion script that supports both export formats
- Auto-detects format (Twitter Exporter or BirdBear)
- Generates concise titles (max 100 chars) using GPT-3.5-turbo
- Reclassifies folders and tags based on content analysis
- Outputs CSV in exact Raindrop.io export format
- Single OpenAI API call per bookmark (cost-optimized)
Usage:
python3 scripts/shared/reclassify_with_openai.py <input.json> -o <output.csv> [-t N]Key Features:
- Format auto-detection
- Single OpenAI API call per bookmark
- Text cleaning for CSV compatibility
- ISO 8601 timestamp format
- Nested folders under "X/"
- Adds "twitter" tag to all entries
Purpose: Removes tags with less than 5 uses to create cleaner taxonomy
- Reduces unique tags significantly (84% reduction example)
- Maintains meaningful tags only
- Provides detailed analysis of tag usage
Usage:
python3 scripts/shared/clean_tags.py <input.csv> <output.csv> [min_uses=5]Purpose: Remove duplicates from newer export by comparing with older export
- Compares two Twitter Bookmark Exporter JSON files
- Uses tweet ID (
idfield or extracted from URL) to identify duplicates - Outputs only new bookmarks that don't exist in older export
- Useful when Chrome extension exports all current bookmarks (not just new ones)
Usage:
python3 scripts/twitter_exporter/deduplicate_exports.py older.json newer.json -o new_only.json [-v]Key Features:
- Automatic ID extraction from
idfield or URL - Handles bookmarks without IDs gracefully
- Detailed statistics and verbose mode
- Preserves all bookmark data structure
Purpose: Basic conversion with OpenAI title generation
- Works with
twitter_bookmarks_tagged_full.json - Generates titles using OpenAI
- Simple CSV output
Purpose: Clean CSV generation with folder/tag reclassification
- Uses folders_list.txt and tags_list.txt
- Single API call for title + classification
Purpose: Generate JSON format compatible with Raindrop.io
- Creates structured JSON output
- Includes folder and tag classification
Purpose: Secure OpenAI API key setup
- Prompts for API key securely (no echo)
- Sets environment variable
- Validates key format
Purpose: Extract unique folders and tags from source JSON
- Creates
references/folders_list.txtandreferences/tags_list.txt - Used as reference lists for OpenAI reclassification
- Provides usage statistics
Note: Update script paths if running from different directory:
analyze_bookmarks("../sources/twitter_exporter/twitter_bookmarks_tagged_full.json")Purpose: Analyze tag distribution in generated CSV
- Counts total vs unique tags
- Shows most popular tags
- Helps understand Raindrop.io import statistics
Note: Update script paths if running from different directory:
analyze_tags("../outputs/twitter_exporter/raindrop_format.csv")- Model: GPT-3.5-turbo
- Single API Call: Combines title generation + classification
- Rate Limiting: 0.2s delay between calls
- Cost Optimization: ~$5-10 for 1,778 bookmarks
- Exact Format Match: Based on actual Raindrop export
- Required Fields:
id,title,note,excerpt,url,folder,tags,created,cover,highlights,favorite - Folder Structure: All nested under "X/" (e.g., "X/ai", "X/devtools")
- Tag Format: Comma-separated, includes "twitter" tag
- Text Cleaning: Removes problematic newlines and quotes
- Timestamp Conversion: ISO 8601 format (
2025-07-19T18:34:39.000Z) - Tag Optimization: Removes tags with <5 uses
- Content Preservation: Full text in
excerptfield
- Bookmarks: 1,778
- Folders: 17 (nested under "X/")
- Tags (before cleaning): 1,247 unique, 2,669 total uses
- Tags (after cleaning): 203 unique, 7,393 total uses
- Average tags per bookmark: 4.2
- twitter: 1,778 uses
- devtools: 840 uses
- ai: 588 uses
- opensource: 328 uses
- GPT: 207 uses
The AI uses a sophisticated prompt that:
- Analyzes full text content and URL
- References predefined folder and tag lists (from
references/) - Suggests most appropriate folder from existing options
- Selects relevant tags from existing list + new important ones
- Generates concise, descriptive titles
- Solution: Run scripts from project root directory
- Alternative: Update hardcoded paths in scripts to use relative paths from script location
- Solution: Use cleaned CSV files from
outputs/directory - Cause: CSV formatting, newlines in fields, wrong headers
- Rate Limits: Script includes 0.2s delays
- Invalid Key: Use
scripts/shared/setup_openai.pyor checkreferences/APIKEY.txt - Cost Control: Test with small subset first using
-tflag
- Raindrop.io reports total tag uses, not unique tags
- Use
scripts/shared/analyze_tags.pyto understand the breakdown
- Large Files: JSON files can be 700KB-2MB, CSV files 500KB-800KB
- Encoding: All files use UTF-8
- Line Endings: Handled by Python CSV writer
- Single API Call: Combining title + classification saves ~50% on API costs
- Exact Format Matching: Raindrop.io is strict about CSV format
- Tag Cleanup: Essential for usable taxonomy (1,247 β 203 tags)
- Text Cleaning: Critical for CSV compatibility
- Rate Limiting: Prevents API throttling
- Format Detection: BirdBear format has richer metadata but needs conversion
- Initial: Started with Twitter Bookmark Exporter format
- Manual Enhancement: User added
folderandtagsfields - V1: Basic conversion with timestamp fixes
- V2: Added OpenAI title generation
- V3: Added folder/tag reclassification (separate API calls)
- V4: Optimized to single API call per bookmark
- V5: Multiple CSV format attempts to fix Raindrop.io compatibility
- V6: Final format matching Raindrop export structure
- V7: Added BirdBear format support with auto-detection
- Final: Tag cleanup for better taxonomy
- Export bookmarks using Twitter Bookmark Exporter β
sources/twitter_exporter/twitter_bookmarks.json - (Optional) Manually add
"folder"and"tags"fields βsources/twitter_exporter/twitter_bookmarks_tagged_full.json - Obtain OpenAI API key
- Place key in
references/APIKEY.txtor set environment variable - Run conversion script
- Clean tags (optional but recommended)
- Import final CSV to Raindrop.io
- Export bookmarks using BirdBear β
sources/birdbear/birdbear-export-*.json - Obtain OpenAI API key
- Place key in
references/APIKEY.txtor set environment variable - Run conversion script (auto-detects format)
- Clean tags (optional but recommended)
- Import final CSV to Raindrop.io
- Batch API calls for better efficiency
- Support for other bookmark sources
- Custom tag taxonomy rules
- Automated import via Raindrop.io API
- Progress bars for long operations
- Update all scripts to use relative paths from project root
- The user prefers Python3 over python
- OpenAI API key was provided in
references/APIKEY.txtdue to terminal paste issues - Tag cleaning with min 5 uses was crucial for usability
- Raindrop.io is very strict about CSV format - use exact export structure
- User values cost optimization (single API call approach)
- All folders should be nested under "X/"
- Always add "twitter" tag to all entries
- Two export formats exist: Twitter Bookmark Exporter (older, July) and BirdBear (newer, August)
- Use
reclassify_with_openai.pyfor both formats - it auto-detects
Last Updated: November 2025
Total Processing Time: ~15 minutes for 1,778 bookmarks
Estimated API Cost: $5-10 USD