A Telegram Userbot based on Kurigram
This repository contains the source code of a Telegram Userbot and the instructions for running a copy yourself. The bot uses Kurigram's asynchronous client and Smart Plugins; feel free to explore the source code to learn more about these topics.
Kurigram keeps the pyrogram import namespace. Existing [pyrogram] configuration
and session files continue to use the same names. Native encryption is provided
by TgCrypto-pyrofork, as in KinTab.
I assume you will read this whole README.md file before continuing.
You're gonna need to get the following programs and services either installed on your server or signed up for. You must do all. It is a cardinal sin if you don't.
-
Python 3.10 or newer. Version-specific dependency pins select the newest compatible releases for Python 3.10, 3.11, and 3.12+. The Docker images use Python 3.15.
-
virtualenvinstalled so that the packages don't interfere with other system packages. -
A C compiler, Python headers, Cairo development headers, and
pkg-configfor SVG-to-PNG rendering. On Debian/Ubuntu, install them withsudo apt-get install build-essential python3-dev libcairo2-dev pkg-config. The Docker images include these dependencies. -
Deno 2.3+ on
PATHfor YouTube downloads, plus FFmpeg for merging video and audio. Both are included in the Docker images. Theyt-dlp[default]requirement supplies the matching YouTube challenge scripts. HTTP 429 means the service is rate-limiting requests; wait before retrying and check the server/proxy's public IP if it persists. Installing Deno does not remove a rate limit. -
Storage uses SQLite, included with Python. The database is created automatically at
config/userbot.sqlite3.
The way I deploy
git clone https://github.com/athphane/userbot.git
cd userbot
virtualenv venv
source venv/bin/activate
pip install -r requirements.txt
python -m userbotWhen upgrading an existing virtual environment from pyrotgfork, remove the old packages before reinstalling so their shared modules are replaced completely:
python -m pip uninstall -y pyrotgfork TgCrypto
python -m pip install --upgrade --force-reinstall -r requirements.txtDocker deployments install the new dependencies in a fresh image.
Using docker
- Save the following content as
docker-compose.yml
services:
userbot:
hostname: userbot
volumes:
- ./config:/root/userbot/config
image: ghcr.io/athphane/userbot:latest
restart: always
labels:
com.centurylinklabs.watchtower.enable: "true"If you already run Watchtower on this Docker host, these labels opt the userbot
into automatic updates from ghcr.io/athphane/userbot:latest.
Watchtower must be configured to include this container and allow updates; the
userbot is also opted in when Watchtower uses --label-enable. See the
Watchtower container selection documentation
for name and scope filters. After adding the labels to an existing deployment,
run docker compose up -d userbot to apply them.
This example uses the published image. The repository's root docker-compose.yml
builds locally and mounts the source checkout, so its labels alone do not enable
updates from the published image.
- Config
Get your telegram api_id and api_hash from https://my.telegram.org/apps and configure them:
mkdir config
wget -O config/userbot.ini https://raw.githubusercontent.com/athphane/userbot/refs/heads/master/userbot.ini.sample
nano config/userbot.ini
- First run:
docker compose run --rm userbot python -m userbot- Configure userbot and stop container CTRL+C
- Run the container again de-attached:
docker compose up -dPM approvals, ignored users, reminders, profiles, summon settings, sticker rules,
and auto-replies are stored in config/userbot.sqlite3. Python's built-in
sqlite3 module handles storage, with no additional package or service.
The existing database()["collection"] and helper APIs remain available.
ID lookups are indexed; the adapter supports equality filters, string
$regex searches with $options, projections, $set, $inc, $unset,
and upserts. It is a small adapter for the bot's calls, not a full MongoDB driver;
unsupported operators raise errors. Music, lyrics, and Telegram message searches
continue to query their existing external services.
The optional configuration below changes the file location. Relative paths are
resolved from the working directory used to run the bot. Docker's existing
./config:/root/userbot/config mount persists the default file.
[database]
path = config/userbot.sqlite3Existing configuration files work without this section; old [mongo] settings
are ignored. A new SQLite file starts empty. Existing MongoDB records are not
copied automatically. To preserve them before switching:
-
Stop the bot so records cannot change during export and import.
-
Export each collection with MongoDB Database Tools. Set
MONGODB_URIto your existing connection URI and replaceuserbotif your database name differs:mkdir -p exports for collection in auto_replies ignored_users pmpermit profiles self_reminders settings sticker_deleter summon; do mongoexport --uri="$MONGODB_URI" --db=userbot --collection="$collection" --jsonArray --out="exports/$collection.json" done
-
Import on the host from the repository root:
python userbot/database/migrate.py exports --database config/userbot.sqlite3
For a published Docker image, mount the export directory for this one command:
docker compose run --rm -v "$PWD/exports:/exports:ro" userbot python userbot/database/migrate.py /exports --database config/userbot.sqlite3The importer accepts JSON arrays or newline-delimited JSON and preserves ObjectId values as strings, dates as Python datetimes, and numeric values. It requires only Python's standard library and refuses to merge into nonempty destination collections. All files import in one transaction; a failed import leaves existing records unchanged.
-
Start the bot and check your reminders and settings. Once verified, remove the old MongoDB service from your deployment. Keep its data and exports until you have verified the migration.
To back up SQLite, stop the bot and copy the database file, or use SQLite's
Connection.backup() API for a running bot. SQLite may create -wal and
-shm files while running, so copying only the main file while it is open
is not a complete backup. Use a local filesystem for the database.
Your own TikTok, Instagram, and YouTube Shorts links download automatically in
any chat. The owner .dl reply command also works in any chat. Links from other
people are ignored until you send .socialdl on in that chat or group. Send
.socialdl off there to disable them, .socialdl status to check the current
chat, or .socialdl list to see enabled chat IDs. In enabled groups, TikTok,
Instagram, and YouTube Shorts links download automatically; in enabled private
chats, supported links download automatically. Only your account can use the
.socialdl and .dl commands; incoming /start, /help, and /dl commands
are ignored.
Chat settings are stored in config/social_dl_chats.json and survive restarts.
The old enabled, allowed_group, ignored_users, and private user allowlist
settings no longer affect downloads. FFmpeg and ffprobe are needed to make
YouTube uploads streamable and to render Instagram
photos with music. Instagram photo-only carousels (up to 20 images) are sent
in order as albums of up to 10 photos, with one caption per post. Mixed
photo/video carousels are not supported by the photo fallback. Media larger than 50 MB is rejected for chat downloads.
To get the Spotify commands working on the Userbot, you need to get a CLIENT_ID and CLIENT_SECRET form the Spotify Developer Portal and add them into your userbot.ini file.
On the Spotify developer portal, make sure to set your application Redirect URI to
'http://localhost:8888/callback'.
Now is a good time
Then go ahead and run the command python spotify.py
in the projects root directory.
This will create a file called .cache-yourusername. You need to transfer this file to the
project root of the server that will be running your userbot. This is a one time setup.
.restartcommand do not work on Termux as psutils is not supported on Android.
CTRL+C, rungit pullandpython -m userbotto update bot on termux.
- Dan for his Pyrogram Library
- Colin Shark for his PyroBot which helped with most of the useful functions used.
- The people at MyPaperPlane for their Telegram-UserBot that gave a ton of ideas on how and what modules to include in this userbot.
- Baivaru for the ton of help that got me this far into making this repo.
Made with love from the Maldives ❤
