- Changed the behavior of the group duty pin feature to send a new message, unpin the old one, and pin the new one instead of editing the existing message. This ensures the pinned message is always fresh. - Updated the `DUTY_PIN_NOTIFY` configuration description in the documentation to reflect the new message handling approach. - Revised the architecture documentation to clarify the updated group duty pin process. - Enhanced tests to verify the new behavior of the group duty pin functionality, ensuring proper message handling and scheduling.
4.7 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) | Not used for access. Kept for reference only. Access to the miniapp is controlled by roles in the DB (assigned by an admin via /set_role). |
| ADMIN_USERNAMES | comma-separated list | (empty) | Telegram usernames treated as admin fallback when the user has no role in the DB. If a user has a role in the DB, only that role applies. Example: admin1,admin2. |
| ALLOWED_PHONES | comma-separated list | (empty) | Not used for access. Kept for reference only. |
| ADMIN_PHONES | comma-separated list | (empty) | Phones treated as admin fallback when the user has no role in the DB (user sets phone via /set_phone). Comparison uses digits only. Example: +7 999 123-45-67. |
| MINI_APP_SKIP_AUTH | 1, true, or yes |
(unset) | If set, /api/duties and /api/calendar-events are allowed without Telegram initData. Dev only — never use in production. |
| 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. |
| DUTY_PIN_NOTIFY | 0, false, or no to disable |
1 (enabled) |
When the pinned duty message is updated on schedule, the bot sends a new message, unpins the old one and pins the new one. If enabled, pinning the new message sends a Telegram notification (“Bot pinned a message”). Set to 0, false, or no to pin without notification. The first pin (e.g. when the bot is added to the group or on /pin_duty) is always silent. |
| 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. |
Roles and access
Access to the calendar miniapp and admin actions is determined by roles stored in the database (table roles, link users.role_id). Roles: user (miniapp access) and admin (miniapp + /import_duty_schedule, /set_role). An admin assigns roles with /set_role @username user|admin (or by replying to a message with /set_role user|admin). If a user has no role in the DB, they are treated as admin only if they are listed in ADMIN_USERNAMES or ADMIN_PHONES (env fallback). ALLOWED_USERNAMES and ALLOWED_PHONES are not used for access.
Quick setup
- Copy
.env.exampleto.env. - Set
BOT_TOKENto the token from BotFather. - Set
ADMIN_USERNAMES(and optionallyADMIN_PHONES) so that at least one admin can use the bot and assign roles via/set_role.
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.