Skip to content

# Configuration reference

All configuration is read from the environment (e.g. `.env` via python-dotenv). Source of truth: `duty_teller/config.py` and `Settings.from_env()`.

Variable | Type / format | Default | Description
--- | --- | --- | ---
BOT_TOKEN | string | (empty) | Telegram bot token from @BotFather. Required for the bot to run; if unset, the entry point exits with a clear message. The server that serves the Mini App API must use the same token as the bot; otherwise initData validation returns `hash_mismatch`.
DATABASE_URL | string (SQLAlchemy URL) | `sqlite:///data/duty_teller.db` | Database connection URL. Example: `sqlite:///data/duty_teller.db`.
MINI_APP_BASE_URL | string (URL, no trailing slash) | (empty) | Base URL of the miniapp (for documentation and CORS). Trailing slash is stripped. Example: `https://your-domain.com/app`.
HTTP_PORT | integer | `8080` | Port for the HTTP server (FastAPI + static webapp).
ALLOWED_USERNAMES | comma-separated list | (empty) | Telegram usernames allowed to open the calendar miniapp (without `@`; case-insensitive). If both this and `ADMIN_USERNAMES` are empty, no one can open the calendar. Example: `alice,bob`.
ADMIN_USERNAMES | comma-separated list | (empty) | Telegram usernames with admin role (access to miniapp + `/import_duty_schedule` and future admin features). Example: `admin1,admin2`.
ALLOWED_PHONES | comma-separated list | (empty) | Phone numbers allowed to access the miniapp (user sets via `/set_phone`). Comparison uses digits only (spaces, `+`, parentheses, dashes ignored). Example: `+7 999 123-45-67,89001234567`.
ADMIN_PHONES | comma-separated list | (empty) | Phone numbers with admin role; same format as `ALLOWED_PHONES`.
MINI_APP_SKIP_AUTH | `1`, `true`, or `yes` | (unset) | If set, `/api/duties` is allowed without Telegram initData (dev only; insecure).
INIT_DATA_MAX_AGE_SECONDS | integer | `0` | Reject Telegram initData older than this many seconds. `0` = disabled. Example: `86400` for 24 hours.
CORS_ORIGINS | comma-separated list | `*` | Allowed origins for CORS. Leave unset or set to `*` for allow-all. Example: `https://your-domain.com`.
EXTERNAL_CALENDAR_ICS_URL | string (URL) | (empty) | URL of a public ICS calendar (e.g. holidays). If set, those days are highlighted on the duty grid; users can tap «i» on a cell to see the event summary. Empty = no external calendar.
DUTY_DISPLAY_TZ | string (timezone name) | `Europe/Moscow` | Timezone for the pinned duty message in groups. Example: `Europe/Moscow`, `UTC`.
DEFAULT_LANGUAGE | `en` or `ru` (normalized) | `en` | Default UI language when the user's Telegram language is unknown. Values starting with `ru` are normalized to `ru`, otherwise `en`.

## Quick setup

1. Copy `.env.example` to `.env`.
2. Set `BOT_TOKEN` to the token from BotFather.
3. For miniapp access, set `ALLOWED_USERNAMES` and/or `ADMIN_USERNAMES` (and optionally `ALLOWED_PHONES` / `ADMIN_PHONES`).

For Mini App URL and production deployment notes (reverse proxy, initData), see the README Setup and Docker sections.