An open-source Telegram bot that copies an entire sticker pack into a new pack owned by you. After cloning, you can add stickers, remove stickers, rename the visible title, and manage multiple packs from the bot.
You need two things before deploying:
- A Telegram bot token from @BotFather.
- A MongoDB Atlas connection string from MongoDB Atlas.
Never paste either secret into the source code or commit them to GitHub.
- Send the bot a sticker from the pack you want to copy.
- Enter the visible title for your new pack.
- Wait for the bot to clone it and send you the new pack link.
The permanent link name is generated automatically from the title with a unique suffix.
- Copies complete sticker packs without downloading or re-encoding their files.
- Supports static, animated, and video stickers.
- Lets each user manage multiple cloned packs.
- Adds and removes individual stickers.
- Changes the visible pack title.
- Stores user state and pack ownership in MongoDB.
- Shows cloning progress and preserves usable partial packs if Telegram stops a large clone.
- Recovers abandoned cloning sessions instead of leaving users permanently stuck.
| Command | What it does |
|---|---|
/clone |
Start cloning another sticker pack |
/packs |
List your cloned packs and choose the active one |
/add |
Add stickers to the active pack |
/remove |
Remove stickers from the active pack |
/rename |
Change the active pack's visible title |
/done |
Finish add or remove mode |
/cancel |
Cancel the current input step |
/help |
Show the help message |
| Variable | Required | Default | Description |
|---|---|---|---|
BOT_TOKEN |
Yes | — | Token issued by BotFather |
MONGODB_URI |
Yes in production | mongodb://localhost:27017 |
MongoDB or Atlas connection string |
MONGODB_DATABASE |
No | sticker_kang_bot |
MongoDB database name |
LOG_LEVEL |
No | INFO |
Python logging level |
DROP_PENDING_UPDATES |
No | false |
Discard Telegram updates queued before startup |
WEBHOOK_SECRET |
Vercel only | — | Random secret containing letters, numbers, _, or - |
Run only one deployment for a bot token. Telegram cannot use long polling and a webhook for the same bot simultaneously.
Click Deploy to Heroku, enter BOT_TOKEN and MONGODB_URI, and deploy. The included
app.json and Procfile create one worker process automatically.
Click Deploy to Render and enter the two requested secrets. The included
render.yaml creates a Docker background worker. Render does not offer its free
instance type for background workers, so choose an available worker plan.
The Railway button opens a new project because Railway requires the maintainer to publish a
platform template before a repository-specific one-click URL exists. Select Deploy from GitHub,
choose this repository or your fork, then add BOT_TOKEN and MONGODB_URI in Variables.
Railway detects the root Dockerfile and reads railway.json.
The Koyeb button preconfigures this repository as a Docker worker. Enter BOT_TOKEN and
MONGODB_URI, review the selected instance, and deploy.
Vercel cannot run the long-polling worker, so this repository includes a FastAPI webhook at
/api. The deploy button asks for BOT_TOKEN, MONGODB_URI, and WEBHOOK_SECRET.
MONGODB_DATABASE keeps its default value unless you add an override.
Generate the webhook secret locally:
openssl rand -hex 32After Vercel finishes deploying, register its production URL with Telegram:
export STICKER_BOT_URL="https://your-project.vercel.app"
export STICKER_WEBHOOK_SECRET="the-same-value-used-in-vercel"
curl -X POST "$STICKER_BOT_URL/api/setup" \
-H "Authorization: Bearer $STICKER_WEBHOOK_SECRET"A successful response contains "status":"configured". Vercel Hobby functions currently have
a five-minute maximum duration, so the webhook uses a 270-second clone limit. If a large pack is
heavily rate-limited, the bot saves the copied stickers as a partial pack instead of hanging.
Copy the example environment file, add your secrets, and start the service:
cp .env.example .env
docker compose up --build -d
docker compose logs -f botCoolify users can set the same variables under Configuration → Environment Variables. The Compose file exposes them as editable runtime variables.
Requirements: Python 3.9+, MongoDB 5.0+ or Atlas, and a Telegram bot token.
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e '.[dev]'
cp .env.example .envEdit .env, then start the bot:
sticker-kang-botThe normal application uses long polling and automatically removes any old webhook before it starts.
- Telegram requires permanent pack names to end in
_by_<bot_username>and limits them to 64 ASCII letters, numbers, and underscores. The bot handles this automatically. - Permanent pack link names cannot be renamed. Only the visible title can change.
- Normal sticker sets can contain up to 120 stickers; custom emoji sets can contain up to 200.
- Telegram returns only the primary emoji association for each sticker. Hidden emoji associations and search keywords cannot be copied through the Bot API.
- A bot can modify only sticker packs that it created.
See Telegram's Bot API sticker methods for the upstream API rules.
api/
└── index.py # Vercel FastAPI entry point
src/sticker_kang_bot/
├── app.py # long-polling entry point
├── webhook.py # serverless webhook application
├── runtime.py # shared bot and dispatcher setup
├── config.py # environment configuration
├── database.py # MongoDB client and indexes
├── domain.py # modes and Telegram naming rules
├── handlers.py # commands, messages, and callbacks
├── keyboards.py # inline keyboards
├── locks.py # per-user mutation locks
├── models.py # typed MongoDB documents
├── repositories.py # MongoDB data access
└── services.py # Telegram sticker operations and retries
ruff check .
ruff format --check src
mypy srcPlease read CONTRIBUTING.md before opening a pull request.
Released under the MIT License.