A Telegram bot that fetches all public data of any GitHub account and delivers each repository (or gist) as a ZIP archive — with an interactive, button-driven UI.
Fork it, drop in your own tokens, and deploy anywhere: Railway, Render, Fly.io, a plain VPS with Docker, or even a Cloudflare Worker. It never runs on someone else's server — you own your instance.
A demo instance is running at @GitAccesBot — open it, send any GitHub username or profile link, and try the buttons.
The demo runs in
linkmode (public data only). For 2 GB uploads and full git history, deploy your own instance as described below.
- Profile card — send a username or profile link and get a rich card: name, bio, company, location, followers, public repo & gist counts, join date, and avatar.
- Interactive repo browser — paginated inline buttons to browse every public (non-fork) repository and download any one with a tap.
- Full git history — grab a repo with all its commits (
git clone+ zipped.git), not just a snapshot. Needslocalmode. - Batch download — grab all repos at once with a live progress indicator.
- Gist listing — list a user's public gists with direct links.
- Hybrid delivery — two upload strategies (see below) so it runs on both heavy (Docker/VPS) and serverless (Worker) hosts.
- Stateless — no database. Everything comes straight from the GitHub REST API.
- Auto-cleanup — in local mode, downloaded archives are always removed after sending (even on failure).
Set UPLOAD_MODE to pick how archives reach the user:
| Mode | How it works | Size limit | Disk/RAM | Best for |
|---|---|---|---|---|
link (default) |
Replies with GitHub's own direct ZIP URL (.../archive/refs/heads/<branch>.zip). The bot never touches the bytes. |
None | ~0 | Cloudflare Workers, tiny/free tiers, simplest setup |
local |
Downloads the ZIP and uploads the real file through a local Telegram Bot API server, lifting Telegram's upload cap from 50 MB → 2 GB. Falls back to a link automatically if a file is too big or a network error occurs. | 2 GB | needs disk + RAM | VPS / Railway / Render with Docker |
Why local mode needs
TELEGRAM_API_ID/TELEGRAM_API_HASH: the local Bot API server requires app credentials to connect to Telegram's network. These identify the application, not any user account — they are never used to log into or access a personal account. Grab them in 2 minutes at my.telegram.org. Inlinkmode you don't need them at all.
git clone https://github.com/<you>/github-archiver-bot.git
cd github-archiver-bot
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
# edit .env and set BOT_TOKEN (from @BotFather)
python -m bot.mainThat runs in link mode — fully functional, zero extra services.
The bundled docker-compose.yml starts two services: the bot and a local telegram-bot-api server.
cp .env.example .envEdit .env:
BOT_TOKEN=123456:ABC... # from @BotFather
UPLOAD_MODE=local
TELEGRAM_API_BASE=http://telegram-bot-api:8081
TELEGRAM_API_ID=1234567 # from my.telegram.org
TELEGRAM_API_HASH=abcdef123456... # from my.telegram.org
GITHUB_TOKEN= # optional, raises rate limit to 5000/hThen:
docker compose up -d --build
docker compose logs -f bot- Fork this repo.
- Create a new service from your fork (Railway auto-detects the
Dockerfile). - Add environment variables from the table below (
BOT_TOKENis enough forlinkmode). - Deploy. That's it.
For 2 GB uploads on these platforms, use the
docker-compose.yml(Railway supports multi-service via a compose file) and setUPLOAD_MODE=local.
Use link mode only. Workers have no filesystem and can't host the C++ Bot API server, so local mode is unavailable there — but link mode delivers GitHub's own download URLs, which works perfectly and needs no disk.
git clone ... && cd github-archiver-bot
cp .env.example .env # fill in values
docker compose up -d --build| Variable | Required | Default | Description |
|---|---|---|---|
BOT_TOKEN |
✅ | — | Telegram bot token from @BotFather |
UPLOAD_MODE |
link |
link or local |
|
TELEGRAM_API_BASE |
only for local |
https://api.telegram.org |
URL of the Bot API server |
TELEGRAM_API_ID |
only for local |
— | App ID from my.telegram.org |
TELEGRAM_API_HASH |
only for local |
— | App hash from my.telegram.org |
GITHUB_TOKEN |
— | Optional PAT; raises GitHub rate limit 60/h → 5000/h (no scopes needed) | |
MAX_LOCAL_UPLOAD_MB |
1900 |
Files above this fall back to a direct link | |
REPOS_PER_PAGE |
8 |
Repos shown per page in the browser |
| Input | Result |
|---|---|
torvalds |
Profile card |
@torvalds |
Profile card |
https://github.com/torvalds |
Profile card |
/fetch torvalds |
Profile card |
/help |
Shows the current delivery mode & help |
Then use the inline buttons: 📂 Browse repos, 📦 Download all, 📝 Gists, 🌐 Profile.
github-archiver-bot/
├── bot/
│ ├── main.py # entry point, Dispatcher setup, mode switch
│ ├── config.py # env-driven settings
│ ├── keyboards.py # inline keyboards & callback data
│ ├── formatting.py # profile/repo text rendering
│ ├── handlers/
│ │ └── start.py # commands + callback handlers
│ └── services/
│ ├── github.py # GitHub REST API client (public data)
│ └── delivery.py # hybrid ZIP delivery (link/local)
├── Dockerfile
├── docker-compose.yml # bot + local telegram-bot-api
├── requirements.txt
└── .env.example
- The bot only reads public GitHub data. No authentication to any GitHub account is required.
- Nothing is stored: it's fully stateless.
- In
localmode, temporary ZIPs are deleted immediately after sending. - Respect GitHub's Terms of Service and rate limits. Set a
GITHUB_TOKENto avoid403throttling on busy bots.
MIT — do whatever you want, no warranty. See LICENSE.
Built with aiogram 3 and the GitHub REST API. PRs welcome. ⭐ the repo if it's useful!