Files
duty-teller/docs/configuration.md
Nikolay Tatarinov 9486f7004d
All checks were successful
CI / lint-and-test (push) Successful in 19s
docs: update README and configuration documentation for clarity
- Revised the README to improve clarity in instructions for accessing the calendar miniapp, including changes to the phrasing for consistency.
- Updated the configuration documentation to enhance the description of the `EXTERNAL_CALENDAR_ICS_URL` setting, ensuring users understand its purpose and usage.
- Improved the import format documentation by translating terms to English for better accessibility to a wider audience.
- Enhanced the runbook with clearer instructions regarding access issues when using direct links, emphasizing the importance of using the bot's menu button.
2026-02-20 16:26:47 +03:00

3.6 KiB

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.

Production: HTTPS

In production the application must be served over HTTPS (e.g. behind a reverse proxy such as nginx or Caddy with TLS). Without HTTPS, the Telegram Mini App initData and the calendar subscription token are sent in the clear; an attacker on the same network could capture them and gain access to the calendar or impersonate the user. Deploy the HTTP server behind a proxy that terminates TLS and forwards requests to the app.