Skip to content

eqyv/bsky

Repository files navigation

bsky crosspost logo

bsky crosspost

Automatically mirror your Bluesky posts to X (Twitter) and Instagram.

Stars Forks Issues License

Python Telegram


Overview

bsky crosspost watches a Bluesky account and re-publishes each new post (text and media) to your other social platforms. It runs as a lightweight polling loop with per-platform adapters, so you can enable only the targets you need.

Platform Role Library Auth
🦋 Bluesky Source atproto App password
✖️ X (Twitter) Target twikit Cookies (recommended) or login
📸 Instagram Target instagrapi Session / login

Features

  • Multi-target fan-out — one Bluesky post → many platforms in a single pass.
  • Media-aware — downloads and re-uploads images attached to the source post.
  • Resilient state — tracks the last processed post; only advances state when a target succeeds, so nothing is silently dropped.
  • Drop-in adapters — each platform is isolated behind a common interface; missing credentials simply skip that target.
  • Cookie-based X auth — sidesteps X's Cloudflare-protected login (essential on VPS/datacenter IPs).

Installation

git clone https://github.com/eqyv/bsky.git
cd bsky

python -m venv venv
source venv/bin/activate          # Windows: venv\Scripts\activate

pip install -r requirements.txt

Configuration

Copy the example env file and fill in your credentials:

cp .env.example .env
Variable Required Description
BSKY_HANDLE Your Bluesky handle (name.bsky.social)
BSKY_APP_PASSWORD Bluesky app password (not your login password)
X_AUTH_TOKEN / X_CT0 ▶️ Browser-exported X cookies — preferred auth
X_USERNAME / X_EMAIL / X_PASSWORD ▶️ X login fallback (blocked on datacenter IPs)
X_TOTP_SECRET X 2FA base32 secret, if enabled
IG_USERNAME / IG_PASSWORD ▶️ Instagram credentials
POLL_INTERVAL_SECONDS How often to check Bluesky (default 180)

▶️ = required only for that target. Enable any subset of X / Instagram.

Getting your X cookies: log into X in a browser → DevTools → Application → Cookies → https://x.com → copy the auth_token and ct0 values into .env. See TROUBLESHOOTING.md for why this is recommended.

Usage

python main.py

On first run the bot seeds its state with your latest existing post, so only posts created after startup are mirrored. Press Ctrl+C to stop.

Project structure

bsky/
├── adapters/        # Per-platform source & target adapters
│   ├── bluesky_source.py
│   ├── twitter.py / twitter_patch.py
│   └── instagram.py
├── core/            # Detector, orchestrator, state manager
├── utils/           # Logger, media downloader
├── storage/         # Session cookies & state (gitignored)
├── config.py        # Env-backed configuration
└── main.py          # Entry point & polling loop

Troubleshooting

X (Twitter) relies on twikit, an unofficial client that occasionally drifts from X's changing internals. Common errors and their fixes are documented in TROUBLESHOOTING.md.

Disclaimer

This project uses unofficial clients for X and Instagram. Automating these platforms may violate their Terms of Service and can put your account at risk. Use responsibly, at your own risk, and prefer dedicated/secondary accounts.

Support

If this project saved you time and you'd like to support, donations are welcome, thank you! 🙏

You can send toncoin or tokens in (only) TON network to this address.

UQA1aKaBehiY-TJzDffLFPaZzHYa6nHxZUAl8MKCrJnlnBx-

um :)

Releases

No releases published

Packages

 
 
 

Contributors

Languages