# Duty Teller (Telegram Bot) A minimal Telegram bot boilerplate using [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) v22 with the `Application` API. ## Get a bot token 1. Open Telegram and search for [@BotFather](https://t.me/BotFather). 2. Send `/newbot` and follow the prompts to create a bot. 3. Copy the token BotFather gives you. ## Setup 1. **Clone and enter the project** ```bash cd duty-teller ``` 2. **Create a virtual environment (recommended)** ```bash python -m venv venv source venv/bin/activate # Linux/macOS # or: venv\Scripts\activate # Windows ``` 3. **Install dependencies** ```bash pip install -r requirements.txt ``` 4. **Configure the bot** ```bash cp .env.example .env ``` Edit `.env` and set `BOT_TOKEN` to the token from BotFather. 5. **Miniapp access (calendar)** To allow access to the calendar miniapp, set `ALLOWED_USERNAMES` to a comma-separated list of Telegram usernames (without `@`). Users in `ADMIN_USERNAMES` also have access; the admin role is reserved for future bot commands and API features. If both are empty, no one can open the calendar. 6. **Optional env** - `DATABASE_URL` – DB connection (default: `sqlite:///data/duty_teller.db`). - `MINI_APP_BASE_URL` – Base URL of the miniapp (for documentation / CORS). - `MINI_APP_SKIP_AUTH` – Set to `1` to allow `/api/duties` without Telegram initData (dev only; insecure). - `CORS_ORIGINS` – Comma-separated allowed origins for CORS, or leave unset for `*`. ## Run ```bash python main.py ``` The bot runs in polling mode. Send `/start` or `/help` to your bot in Telegram to test. ## Run with Docker Ensure `.env` exists (e.g. `cp .env.example .env`) and contains `BOT_TOKEN`. - **Dev** (volume mount; code changes apply without rebuild): ```bash docker compose -f docker-compose.dev.yml up --build ``` Stop with `Ctrl+C` or `docker compose -f docker-compose.dev.yml down`. - **Prod** (no volume; runs the built image; restarts on failure): ```bash docker compose -f docker-compose.prod.yml up -d --build ``` For production deployments you may use Docker secrets or your orchestrator’s env instead of a `.env` file. ## Project layout - `main.py` – Builds the `Application`, registers handlers, runs polling and FastAPI in a thread. - `config.py` – Loads `BOT_TOKEN`, `DATABASE_URL`, `ALLOWED_USERNAMES`, `ADMIN_USERNAMES`, `CORS_ORIGINS`, etc. from env; exits if `BOT_TOKEN` is missing. - `api/` – FastAPI app (`/api/duties`), Telegram initData validation, static webapp mount. - `db/` – SQLAlchemy models, session, repository, schemas. - `alembic/` – Migrations (use `config.DATABASE_URL`). - `handlers/` – Command and error handlers; add new handlers here. - `webapp/` – Miniapp UI (calendar, duty list); served at `/app`. - `requirements.txt` – Pinned dependencies (PTB, FastAPI, SQLAlchemy, Alembic, etc.). To add commands, define async handlers in `handlers/commands.py` (or a new module) and register them in `handlers/__init__.py`. ## Tests Install dev dependencies and run pytest: ```bash pip install -r requirements-dev.txt pytest ``` Tests cover `api/telegram_auth` (validate_init_data), `config` (is_admin, can_access_miniapp), and the API (date validation, 403/200 with mocked auth).