A self-hosted Telegram bot for shared subscriptions, payment reminders, and member balances. Built with Python 3.13, aiogram, and SQLite.
- Split subscription costs across members, with individual shares and currencies.
- Send scheduled reminders, track payment confirmations, and view payment reports.
- Invite members through personal links and manage balance top-ups with admin approval.
Payments happen outside the bot; PingSubs records them.
Requires Git, Docker with Compose, and a Telegram bot token from @BotFather.
git clone https://github.com/dcip3/DCIP3.PingSubs.git
cd DCIP3.PingSubs
cp .env.example .envIn .env, set BOT_TOKEN and put your numeric Telegram user ID into ADMIN_IDS.
Set the admin ID before the first launch: with a fresh database and no configured
admins, the first person to send /start becomes the administrator.
docker compose up -d --build
docker compose logs -f --tail=100The bot uses long polling: no domain, HTTPS certificate, or inbound port is needed.
SQLite data is stored in ./data/ and survives container recreation. Keep the default
DATABASE_PATH when using the included Compose file so it stays inside the mounted directory.
To update an existing installation:
git pull --ff-only
docker compose up -d --buildStop with docker compose down. Back up data/ while the bot is stopped, and keep
.env separately. Run only one bot instance per token.
Optional: GitHub Actions deployment
deploy.yml deploys the tip of main over SSH once
the repository checks pass. Prepare a working installation at /opt/DCIP3.PingSubs
on the server and add the repository secrets VDS_HOST, VDS_USER, and
VDS_SSH_KEY, plus VDS_HOST_FINGERPRINT to pin the server's host key: the SHA256:...
value from ssh-keygen -lf /etc/ssh/ssh_host_ecdsa_key.pub on the server. The SSH user
needs access to that directory, Git, and Docker; .env and data/ stay on the
server. The deployment points the checkout at this repository over HTTPS and resets
it to the commit that passed the checks, so keep local changes out of that
directory. It fails when the bot does not stay up for 20 seconds; the bot's logs
stay on the server. In a fork, change the repository name in the workflow's if:
condition and the installation path in its script.
Requires Python 3.13. Clone the repository and configure .env as above, then:
python3.13 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
python main.pyWindows (PowerShell)
py -3.13 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
.\.venv\Scripts\python.exe main.pySettings are read from environment variables or .env. Existing environment
variables take precedence. The data directory is created automatically.
| Variable | Default | Purpose |
|---|---|---|
BOT_TOKEN |
Required | Telegram bot token from @BotFather |
ADMIN_IDS |
Empty | Admin Telegram user IDs, separated by commas; set before first launch |
DATABASE_PATH |
data/app.db |
SQLite database path |
REMINDER_CHECK_INTERVAL |
60 |
Seconds between reminder checks, clamped to 5-60 |
BASE_REMINDER_TIME |
16:00 |
Default reminder time, HH:MM |
BASE_TIMEZONE |
Europe/Moscow |
Default IANA timezone, e.g. Europe/Belgrade |
TARGET_CURRENCY |
RUB |
Default currency for conversions |
CURRENCY_ROUNDING |
precise |
precise, floor, round, or ceil |
Rounding, base reminder time, and timezone seed a new database and can be changed
later in the admin Settings; saved values take precedence over the environment on
later starts. TARGET_CURRENCY is stored on the first launch only; to change it later,
update the target_currency row in the settings table of the database.
Cross-currency amounts use exchange rates from open.er-api.com (the ExchangeRate-API open endpoint), fetched over outbound HTTPS and cached for six hours. It is the only external service besides Telegram. When it is unreachable, converted amounts are left out and only the original currency is shown.
Send /start from an admin account, add members, and share their personal invite
links. Create a subscription, assign members, and set its amount, billing period,
and reminder schedule. Members can then view their account and confirm payments.
In Settings, users can choose their reminder time and timezone; a display currency can be picked per subscription from the subscription card. Reminders follow each recipient's timezone; subscription-specific times override base settings. Balance top-ups are credited after an admin confirms the transfer.
No license has been chosen yet; public visibility alone does not grant permission to reuse the code.
