Finpipe is a Telegram bot that generates salary and bank documents from a saved profile. A requested document is generated as a PDF, sent to the requesting Telegram chat, and removed from the server immediately after the delivery attempt.
- Stores company, bank-account, payment, invoice-amount, and signature data.
- Generates a Salary Invoice from the current profile and amount.
- Generates a Conversion Request for the amount extracted from the latest bank document.
- Accepts a bank PDF in Telegram and generates a filled Bank Transfer Confirmation from it.
- Sends the generated PDF directly to Telegram.
- Removes generated PDF and intermediate DOCX files after delivery, including failed delivery attempts.
- Accepts commands only from the Telegram account configured by
BOT_OWNER_TELEGRAM_ID.
Finpipe does not connect to or send messages through an electronic-mail provider.
- Python 3.14 and Poetry
- PostgreSQL, SQLAlchemy, and Alembic
- Telegram Bot API (polling)
- Docker Compose
poetry install
cp .env.dist .env
# Fill in the secrets and change DATABASE_URL host to localhost:5433
docker compose -f docker-compose.yml -f docker-compose.local.yml up -d postgres
./scripts/setup_database.sh
poetry run start_botRequired application variables are documented in .env.dist. At minimum, configure the Telegram bot token, owner Telegram ID, signature encryption key, and database URL. Requests from every other Telegram account are rejected without creating user records.
DATABASE_URL is the only source of PostgreSQL host, port, database, username, and password. .env.dist contains the container-to-container address postgres:5432, which is correct when commands run through Docker Compose. When the bot and Alembic run directly on the host, use localhost:5433 and start PostgreSQL with the local Compose override shown above. The bot container translates loopback hosts (localhost, 127.0.0.1, or ::1) to postgres:5432; credentials, database name, query parameters, and non-loopback database addresses remain unchanged. The URI and password are not logged or placed in child-process arguments. For an existing volume, configure DATABASE_URL with credentials that the database role already accepts; changing the URI alone does not rotate an existing PostgreSQL role password.
- Open
Profileand download the YAML template. - Fill it in and upload it to the bot.
- Upload the signature used by signed document workflows.
- For a Salary Invoice, open
Documents→Invoice, set the amount, and chooseCreate invoice. - For a Bank Transfer Confirmation, choose it in
Documentsand upload the source bank PDF. - To generate a Conversion Request for the extracted amount, choose it in
Documentsafter the bank confirmation completes.
The bot sends every generated PDF to the same Telegram chat and deletes all temporary input, PDF, and intermediate DOCX files.
docker compose up -d postgres
docker compose run --rm finpipe-bot python -m src.workflows.monitoring.backup_database
docker compose run --rm finpipe-bot alembic upgrade head
docker compose up -d --wait finpipe-bot
# Local PostgreSQL port exposure
docker compose -f docker-compose.yml -f docker-compose.local.yml up -dProduction deploy stops the bot, invokes the database backup workflow into the persistent project directory ./backups, applies Alembic migrations, and waits for the new bot readiness check. Deploy creates one backup per run and does not prune old backups; additional scheduling and retention are outside this repository. The readiness check verifies Telegram API access and reads every active ORM table. If a migration has committed, deploy never starts the old image against the new schema.
Backups are plain PostgreSQL SQL dumps compressed as ./backups/finpipe_YYYY-MM-DD_HH-MM-SS.sql.gz. List them with:
find ./backups -maxdepth 1 -name 'finpipe_*.sql.gz' -printTo restore, first preserve the current database separately and stop the bot. The restore command recreates the database configured by DATABASE_URL, then feeds the selected dump to psql using libpq environment inherited only by its child processes:
docker compose stop finpipe-bot
docker compose exec -T postgres python3 /usr/local/bin/finpipe-postgres-runtime --restore /backups/finpipe_YYYY-MM-DD_HH-MM-SS.sql.gz
docker compose run --rm finpipe-bot alembic current
docker compose up -d --wait finpipe-botDo not run alembic upgrade automatically after restoring unless the restored revision has first been checked with alembic current and the corresponding application version is available.
poetry run ruff check .
poetry run mypy src
poetry run pytest
poetry run alembic check| Topic | File |
|---|---|
| Development and debugging | docs/development.md |
| Storage | docs/storage.md |