Abitly Telegram bot
Метадані
Section titled “Метадані”| Поле | Значення |
|---|---|
| Продукт | Abitly.org |
| Тип | Bot |
| Статус | 🟢 prod (перевірено: ECS-сервіс abitly-prod-tg-bot 1/1 RUNNING, таск HEALTHY) |
| Власник | @Vladbandurin |
Призначення
Section titled “Призначення”Telegram-бот Abitly.org (@abitlybot) для абітурієнтів: моніторинг вступу — пропозиції (офери), бали й рейтинг, шанси на вступ, дні відкритих дверей. Щодня о 07:00 (Київ) надсилає нагадування про дні відкритих дверей (за 1 і 3 дні); адмінам — розсилки.
Репозиторій та рантайм
Section titled “Репозиторій та рантайм”| Репо | abitly-org/abitly-tg-bot-v3 (main) |
| Стек | aiogram 3 · SQLAlchemy 2.0 (async) · asyncpg · Redis · APScheduler · aiohttp · pydantic-settings · aiolimiter (Python 3.12) |
| Хостинг | AWS ECS Fargate (eu-central-1), кластер abitly-prod-backend, сервіс abitly-prod-tg-bot (1 таск, 256 CPU / 512 MB) |
| Контейнери | bot (образ ECR abitly/tg-bot) + redis:7-alpine sidecar (FSM + link-токени на localhost:6379) |
| Деплой | GitHub Actions (OIDC, без статичних AWS-ключів) → ECR abitly/tg-bot → ECS, push у main (.github/workflows/deploy-bot.yml) |
| Режим | Long polling, строго один інстанс (ADR 0001) |
| HTTP healthcheck | GET /healthcheck на :3000 (aiohttp; ECS health-check + readiness) |
| Cron | APScheduler 0 7 * * * (Europe/Kyiv) → нагадування про дні відкритих дверей |
| Bot username | prod — @abitlybot · dev/staging — @abtltestbot (сервіс abitly-dev-tg-bot, dev-БД) |
| Секрети | SSM Parameter Store: /abitly-prod/tg-bot/BOT_TOKEN, …/DB_PASSWORD (SecureString) |
Команди
Section titled “Команди”User-facing (меню setMyCommands, UI українською):
| Команда | Що робить |
|---|---|
/start | головне меню + привітання; deep-links: link_<token> (прив’язка акаунту), chances_<spec>_<score> (шанси на вступ), open_day_university_<id> (дні відкритих дверей ЗВО) |
/myprofile | профіль і бали |
/myoffers | відстежувані пропозиції (ліміт моніторингу — 5) |
/statistics | статистика по оферу (позиції: середня / мін / макс) |
/myopendays | мої дні відкритих дверей (пагінація) |
/opendayfilters | фільтри сповіщень (за регіоном) |
/notifications | налаштування підписок |
/help | у меню — «Довідка», але хендлера немає → no-op (відоме обмеження, див. нижче) |
| (текст) | вставлення URL офера (abitly.org/uk/offers/result/<id> або vstup.edbo.gov.ua/offer/<id>) → бали + рейтинг (catch-all, реєструється останнім) |
Admin (за ADMIN_IDS):
| Команда | Що робить |
|---|---|
/broadcast | розсилка всім користувачам |
/notifyOpenDaysUpdate | фан-аут оновлення дня відкритих дверей (матч за регіональним фільтром — ADR 0008) |
Масова відправка — MessageSender: обмежена конкурентність (деф. 5), глобальний rate-cap (деф. 30/с, aiolimiter), retry на 429/TelegramRetryAfter, відкидає заблокованих користувачів (TelegramForbiddenError) без зупинки черги (ADR 0005).
Діаграми та сценарії
Section titled “Діаграми та сценарії”UML (use-case, state, class) + sequence-діаграми всіх user-сценаріїв бота (привітання, deep-links, моніторинг, дні відкритих дверей, сповіщення, прив’язка акаунту, адмін-розсилки) → Telegram-бот: user-сценарії. Базовий крос-сервісний потік — data-flows.
Залежності
Section titled “Залежності”- Залежить від: Abitly API (
abitly-api-v2— власник схеми) · Postgres схемаabitly(read-mostly, через SQLAlchemy 2.0 reflection, без міграцій — ADR 0006; camelCase-колонки збережено, бо їх генерує TypeORM бекенду) · sidecar-Redis (FSM + link-токени) · Telegram API - Власні дані: схема
telegramна тому ж кластері (telegram.update_log/telegram.sent_log— логування вхідних/вихідних, ADR 0009/0010) - Domain entities (з коду):
BaseUser,TelegramUser,Offer,OpenDay,Speciality+ reference-таблиці та monitoring-зв’язки - Від нього залежать: —
Env-змінні
Section titled “Env-змінні”Значення — у secret-сховищі, ніколи в git. SecureString-секрети — у SSM /abitly-{prod,dev}/tg-bot/; решта — plain env у ECS task-definition. Повний індекс назв — environments.
| Категорія | Змінні (* — секрет у SSM) |
|---|---|
| Telegram | BOT_TOKEN*, ADMIN_IDS, ACCOUNT_LINK_URL, SEND_MAX_CONCURRENCY, SEND_RATE_PER_SECOND, DEFAULT_TELEGRAM_MESSAGE_MAX_RETRY, DEFAULT_TELEGRAM_MESSAGE_RETRY_DELAY_MS |
| Postgres | DB_HOST, DB_PORT, DB_USERNAME, DB_PASSWORD*, DB_NAME, DB_SCHEMA (abitly), DB_SSL (true), DB_CA_FILE (RDS CA bundle) |
| Redis | REDIS_HOST, REDIS_PORT, REDIS_PASSWORD, REDIS_DB |
| Логування | LOG_LEVEL, LOG_SCHEMA (telegram), LOG_MESSAGES_ENABLED (true) |
| Runtime | PORT (3000), TZ (Europe/Kyiv) |
Ключові команди
Section titled “Ключові команди”uv venv && source .venv/bin/activateuv pip install -e ".[dev]"cp .env.example .env # заповнити BOT_TOKENpython -m abitly_bot # polling + healthcheck на $PORTruff check . && mypy src && pytest # offline quality-gateДеплой та відкат
Section titled “Деплой та відкат”- Deploy: push у
main(pathssrc/**,Dockerfile,pyproject.toml,uv.lock) → GitHub Actions збирає образ, пушить у ECRabitly/tg-bot:<sha>+:latest, рендерить нову task-definition і деплоїть у ECS зwait-for-service-stability. Concurrencycancel-in-progress: false— ніколи два деплої одночасно (один інстанс). Деталі → deploy-pipeline. - Rollback: ECS → попередня ревізія task-definition (або redeploy попереднього
:<sha>-образу з ECR). Доступ —awsCLI (профільabitly) / ECS Exec (enable_execute_command=true). Загальний процес → deploy-rollback.
Логи та моніторинг
Section titled “Логи та моніторинг”- CloudWatch Logs
/abitly-prod/tg-bot(30 дн; stream-prefixbot/redis); dev —/abitly-dev/tg-bot(14 дн). - Стан сервісу:
aws ecs describe-services --cluster abitly-prod-backend --services abitly-prod-tg-bot --profile abitly(див. MCP-реєстр → AWS). - Доступ у контейнер: ECS Exec.
- Самологування в БД:
telegram.update_log/telegram.sent_log.
Типові проблеми
Section titled “Типові проблеми”- 409 Conflict /
TelegramConflictError→ дваgetUpdatesна один токен (напр. локальний запуск + prod, або два сервіси з тим самим токеном). Тримати рівно один інстанс (ADR 0001). → service-down - Бот не відповідає → ECS service/task health + CloudWatch. → service-down
- Помилки БД / TLS → перевірити
DB_CA_FILE(RDS CA) і доступ security-group до RDS:5432. → db-issues - Schema drift → reflection-тест падає, якщо схему
abitlyзмінив бекенд; синхронізувати моделі (ADR 0006).
Власна документація бота
Section titled “Власна документація бота”Канонічні дизайн-доки й ADR живуть у самому репо: Astro + Starlight docs-site (docs-site/, деплой на Cloudflare Pages, проєкт abitly-bot-docs) — overview, architecture, data-model, runtime-flows, operations, 10 ADR. Цей хаб дає крос-сервісний контекст; за деталями внутрішнього дизайну — у docs-site бота.
Відомі обмеження / TODO
Section titled “Відомі обмеження / TODO”- Прив’язка акаунту: узгодити Redis (бекенд мінтить
abitly:link:*у спільний Redis ↔ бот має sidecar-Redis) і підтвердити mint-ендпоінт уabitly-api-v2. -
/help— no-op (команда в меню без хендлера). - Prod Terraform (
infra/terraform/) безbackend.tf→ схоже на local state (dev — на S3 remote). Імпортувати в remote state. -
abitly-dev-tg-bot(dev-сервіс) керується out-of-band, не цим Terraform →terraform import.