A Python-based tool to automatically sync posts from Bluesky to Mastodon with GitHub Actions automation.
- π Automated Syncing: Schedule posts sync from Bluesky to Mastodon
- π― User-Friendly Setup: Interactive setup wizard with helpful error messages
- π§΅ Thread Support: Maintains conversation threading for reply posts
- π GitHub Actions: Run automatically via CI/CD workflows
- π― Smart Deduplication: Prevents duplicate posts across sync runs
- π« Selective Sync: Skip posts with
#no-synctag to control what gets synced - π Smart Filtering: Filters out replies to others, reposts, and quotes of other people's content
- π Content Processing: Handles links, images, and self-quoted posts
- π§ͺ Dry Run Mode: Test functionality without actual posting
π₯ Setting up your own instance? β Fork Setup Guide
π§ First time setup:
# Interactive setup wizard
python sync.py setup
# Or manual setup:
cp .env.example .env
# Edit .env with your credentialsπ οΈ Local development? β Contributing Guide
# Interactive setup wizard (first time)
python sync.py setup
# Sync posts (dry run first)
python sync.py sync --dry-run
python sync.py sync
# Check configuration and test connections
python sync.py config
python sync.py test- Automated: Runs every 6 hours (00:00, 06:00, 12:00, 18:00 UTC) via cron schedule
- Manual: Actions β Social Sync β Run workflow
- Optional: Enable "Run in dry-run mode" to test without posting
- Logs: Check Actions tab for execution details
# Bluesky Credentials
BLUESKY_HANDLE=your-handle.bsky.social
BLUESKY_PASSWORD=your-app-password
# Mastodon Credentials
MASTODON_API_BASE_URL=https://your-instance.social
MASTODON_ACCESS_TOKEN=your-access-tokenSYNC_START_DATE: Date to start syncing from (default: 7 days ago)MAX_POSTS_PER_SYNC: Maximum posts per sync run (default: 10)DRY_RUN: Test mode without posting (default: false)DISABLE_SOURCE_PLATFORM: Disable source attribution (default: false)
π Full setup details: Setup Guide
| Topic | Description |
|---|---|
| Setup Guide | Complete installation and configuration |
| Fork Setup | Guide for forking and personal instances |
| API Documentation | Client APIs and integration details |
| Threading | How conversation threading works |
| Edge Case Analysis | Comprehensive analysis of 15 API edge cases |
| Edge Case Quick Reference | At-a-glance summary of known edge cases |
| Contributing | Development workflow and standards |
| Testing | Test suite and validation procedures |
| Changelog | Version history and release notes |
| Project Summary | Architecture and design overview |
- Connect to Bluesky and Mastodon APIs
- Fetch recent posts from Bluesky feed
- Process content (adapt links, images, threading)
- Filter duplicates and
#no-synctagged posts using sync state tracking - Post to Mastodon with proper threading
- Save sync state for next run
π§΅ Threading: Reply posts maintain conversation context across platforms.
π« Selective Sync: Add #no-sync to any Bluesky post to prevent it from syncing. The tag is case-insensitive (#No-Sync, #NO-SYNC, etc. all work).
GitHub Actions Failing?
- Repository rule violations β Use Personal Access Token
- Missing secrets β Check repository secrets configuration
- Branch protection β See Setup Guide
Posts Not Syncing?
- Run
python sync.py setupfor first-time configuration - Verify credentials and API access with
python sync.py test - Check for reply/repost filtering
- Review logs for specific errors
π Full troubleshooting: Setup Guide
- Fork the repository
- Create feature branch:
git checkout -b feature/amazing-feature - Follow code quality standards: Contributing Guide
- Run tests:
python -m pytest - Submit pull request
MIT License - see LICENSE for details.
- AT Protocol and Bluesky teams
- Mastodon.py library
- atproto Python SDK
Need help? Check Issues or create a new one with details.
Happy syncing! π