Telegram-powered social media crossposting tool. Post once to Telegram, publish everywhere.
Accept text, photos, videos, and documents via a Telegram bot, then publish them across all your social platforms simultaneously.
A lightweight, self-hosted alternative to Postiz, Buffer, and Hootsuite for developers who want full control over their social media automation.
- I am fed up with posting and managing different platforms.
- I have multiple thoughts popping up in my head which I would like to convey to people
- But I lack the patience to go through multiple different apps just to say something...
- And to update the content based on the app is more hated.
- Post to multiple social networks simultaneously from Telegram
- Supports text, images, videos, and documents
- Alt-text support for accessible image posts
- Self-hosted and privacy-focused
- Multi-arch Docker images (amd64, arm64)
- Lightweight Go binary with minimal dependencies
| Platform | Text | Images | Videos |
|---|---|---|---|
| Twitter/X | Yes | Yes | Caption only |
| Bluesky | Yes | Yes | Caption only |
| Mastodon | Yes | Yes | Caption only |
| Yes | Yes | No | |
| Discord | Yes | Yes | Yes |
| Telegram | Yes | Yes | Yes |
| Slack | Yes | Yes | No |
| Dev.to | Yes | No | No |
| Nostr | Yes | No | No |
| Feature | shitpost | Postiz | Buffer |
|---|---|---|---|
| Self-hosted | Yes | Yes | No |
| Free | Yes | Freemium | Freemium |
| Telegram interface | Yes | No | No |
| No web UI required | Yes | No | No |
| Privacy-focused | Yes | Partial | No |
| Open source | Yes | Yes | No |
Pre-built multi-arch images (amd64, arm64) are available:
# Primary (Harbor)
docker pull registry.goharbor.io/bupd/shitpost:latest
# Alternative (GitHub Container Registry)
docker pull ghcr.io/bupd/shitpost:latest| Tag | Description |
|---|---|
latest |
Most recent build from main branch. May include untested changes. |
v1.0.0 |
Specific release version. Stable and tested. Recommended for production. |
v1.0 |
Latest patch release in v1.0.x series. |
v1 |
Latest minor release in v1.x.x series. |
For production, use a versioned tag (e.g., v1.0.0) to avoid unexpected updates.
-
Create
.envfile:curl -o .env https://raw.githubusercontent.com/bupd/shitpost/main/.env.example
Edit
.envand set your tokens. -
Run the container:
docker run -d --name shitpost \ --env-file .env \ -v ./downloads:/app/downloads \ registry.goharbor.io/bupd/shitpost:latest
-
Check logs:
docker logs -f shitpost
-
Clone and enter repo:
git clone https://github.com/bupd/shitpost.git cd shitpost -
Create
.envfile from template and setBOT_TOKEN:cp .env.example .env
-
Build & run with Docker Compose:
docker compose up --build
-
Confirm the bot is running by checking logs for:
Authorized as @<your_bot_username> -
Send messages or media to your bot in Telegram. The bot will post using crosspost and reply with logs.
- Docker/Podman (recommended) or Go 1.25+
- Telegram bot token (create via @BotFather)
- API keys for target platforms (Twitter, Bluesky, Mastodon, etc.)
| Variable | Required | Description |
|---|---|---|
BOT_TOKEN |
Yes | Telegram bot token from BotFather |
AUTH_TOKEN |
No | X auth_token cookie value used by the emusks-backed crosspost Twitter strategy |
TWITTER_AUTH_TOKEN |
No | Explicit X auth_token cookie value; overrides the AUTH_TOKEN alias when set |
TWITTER_API_CONSUMER_KEY |
No | Twitter API consumer key |
TWITTER_API_CONSUMER_SECRET |
No | Twitter API consumer secret |
TWITTER_ACCESS_TOKEN_KEY |
No | Twitter access token |
TWITTER_ACCESS_TOKEN_SECRET |
No | Twitter access token secret |
BLUESKY_HOST |
No | Bluesky host (e.g., bsky.social) |
BLUESKY_IDENTIFIER |
No | Bluesky handle or email |
BLUESKY_PASSWORD |
No | Bluesky app password |
MASTODON_HOST |
No | Mastodon instance URL |
MASTODON_ACCESS_TOKEN |
No | Mastodon access token |
crosspost itself may require additional environment variables (API keys, tokens for target platforms). For details about those envs and how to obtain them, consult the crosspost documentation.
Send any text message to your bot. It will be posted to all configured platforms.
Send images with an optional caption. Videos and non-image documents are downloaded, but the current crosspost CLI path posts their caption text only.
Add alt text for accessibility by ending your caption with alt::
Check out this sunset!
alt: Orange and purple sunset over mountains
-
Install Go 1.25+ and crosspost CLI:
git clone https://github.com/bupd/crosspost.git cd crosspost bun install bun run build bun link -
Build and run:
task setup task up
task setup # create .env and download deps
task up # run in a container
task up:dry-run # run in a container without posting
task up:dry-run:detached # run dry-run mode in the background
task up:detached # run in a container in the background
task logs # follow container logs
task down # stop the container
task doctor # check .env shape without printing secret values
task validate # gofmt, go vet, go test, go buildSet CROSSPOST_FLAGS=-bmt to post to Bluesky, Mastodon, and X. Set AUTH_TOKEN to your X auth_token cookie value to use the emusks-backed X poster in crosspost. Set AUTHORIZED_TELEGRAM_USERS to your Telegram username or numeric user ID so only you can use the bot.
Use task up:dry-run first. Send a Telegram message to the bot and it will reply with the crosspost command it would run without posting anything.
Run task doctor if a platform fails. It prints which keys are present and their lengths without exposing token values. For X, shitpost accepts AUTH_TOKEN as an alias for TWITTER_AUTH_TOKEN, and accepts the legacy official API aliases consumer_key, consumer_key_secret, access_token, and access_token_secret before invoking crosspost.
Telegram → shitpost bot → crosspost CLI → Social platforms
Built as a lightweight wrapper around humanwhocodes/crosspost.
- Self-hosted: your data stays on your server
- No third-party analytics or tracking
- Media files stored locally (configure volume mounts)
- Consider implementing allowlists for public-facing bots
- Verify
BOT_TOKENis set correctly - Check logs:
docker compose logs -f
- Verify platform API keys are configured
- Check crosspost output in bot logs
- Ensure
./downloadsdirectory exists and is writable - Check disk space
Contributions welcome! Please open an issue or PR.
See LICENSE in the repository.
- crosspost - CLI tool powering the cross-posting
- Postiz - Full-featured social media scheduler
- Buffer - Commercial social media management
Add these topics to your repository for better discoverability:
crosspost, social-media, telegram-bot, twitter, bluesky, mastodon, automation, self-hosted, golang, docker