Назад к articles
article

Telegram-бот для изучения языков на C# и .NET 9 — архитектура и технические решения

[Laraue.Apps.LearnLanguage](https://github.com/win7user10/Laraue.Apps.LearnLanguage) — open-source Telegram-бот для изучения словарного запаса на нескольких языках. В этой статье разбираем архитектуру, технические решения и детали реализации — полезно, если вы строите Telegram-бота на C#, проектируете пайплайн с AI-переводом или просто интересуетесь, как устроено production-приложение для изучения языков.

Задеплоенный бот — @learnlangbot.


Стек технологий

Слой Технология
Язык C#
Фреймворк .NET 9
Бот-фреймворк Telegram.NET
AI-перевод Ollama (локальный LLM-инференс)
Формат данных JSON (слова и переводы) + EF Core миграции
Лицензия MIT

Проект — монорепозиторий с двумя запускаемыми приложениями и общим слоем доступа к данным.


Структура репозитория

src/
  Laraue.Apps.LearnLanguage.Host/           # Telegram-бот (web API хост)
  Laraue.Apps.LearnLanguage.AutoTranslator/ # Консольное приложение для AI-перевода
  Laraue.Apps.LearnLanguage.DataAccess/     # Общий EF Core контекст, миграции, seed-данные
tests/
  Laraue.Apps.LearnEnglish.IntegrationTests/

Оба приложения разделяют проект DataAccess, который владеет схемой БД, миграциями и JSON-файлами со словами.


Приложение 1: TelegramApiHost

Основное приложение — .NET 9 Web API, которое обрабатывает входящие Telegram-апдейты через Telegram.NET. В режиме локальной разработки используется long-polling, в production — webhook.

Команды и контроль доступа

Команды разделены на две группы:

  • Публичные — доступны всем пользователям (запуск квиза, просмотр слов, настройки, статистика прогресса)
  • Админские — ограничены настроенным списком ID администраторов (например, принудительный ресид, инспекция состояния)

Это стандартный паттерн для Telegram-ботов: middleware-слой проверяет update.Message.From.Id по списку админов перед роутингом к соответствующим обработчикам.

Логика квиза

Сессия квиза загружает 20 слов за раунд. Алгоритм выбора слов поддерживает баланс между тремя группами:

  • Слова, которые пользователь ещё не встречал
  • Слова, пройденные недавно (краткосрочное закрепление)
  • Слова из старых сессий (проверка долгосрочного запоминания)

Это приближение к облегчённой системе интервального повторения (SRS) без оверхеда полноценного SRS-планировщика. Слова, на которые был дан неверный ответ, возвращаются в последующие раунды.

Выбор языковой пары

При первом использовании бот предлагает выбрать языковую пару. Предпочитаемая пара сохраняется в настройках, чтобы не переспрашивать каждый раз. Хранится в БД на уровне пользователя.


Приложение 2: AutoTranslator

AutoTranslatorApp — самостоятельное консольное приложение, которое сканирует translations.json в поисках слов без переводов на один или несколько языков и заполняет их через локально запущенный Ollama.

Пайплайн перевода

translations.json
       ↓
Найти слова, где translation[language] == null
       ↓
Отправить в Ollama (локальный LLM)
       ↓
Записать результат обратно в translations.json
       ↓
Создать EF Core миграцию
       ↓
Применяется автоматически при следующем старте приложения

Использование локального LLM (через Ollama) вместо платного API обнуляет стоимость переводов и убирает зависимость от сети при массовых прогонах. Переводы также можно исправить вручную — просто отредактировав translations.json.

Ранние версии использовали Google Translate API (добавлен в июне 2024 года). Переход на Ollama произошёл в августе 2025-го: это дало более высокое качество контекстных переводов и убрало зависимость от API-ключей.


Модель данных

Файлы слов и переводов

Все данные о словах хранятся в JSON-файлах внутри проекта DataAccess. Это осознанное архитектурное решение — данные становятся:

  • Версионированными вместе с кодом
  • Удобными для Pull Request — любой может добавить слова или исправить переводы через GitHub
  • Аудируемыми — полная история каждого изменения в git

Два ключевых файла:

`translations.json` — мастер-список слов. Каждая запись содержит английское слово, уровень CEFR, связанные темы и словарь переводов с языковым кодом в качестве ключа:

{
  "word": "resilient",
  "cefr": "B2",
  "topics": ["personality", "general"],
  "translations": {
    "ru": "устойчивый",
    "de": "belastbar",
    "fr": null
  }
}

Значение null сигнализирует AutoTranslatorApp, что перевод отсутствует и должен быть сгенерирован.

`languages.json` — определяет поддерживаемые языковые пары. Добавить новый язык = добавить запись сюда и запустить EF Core миграцию.

База данных

Данные из JSON-файлов засеиваются в реляционную БД через EF Core. При каждом старте хост проверяет наличие новых записей в JSON и применяет их. Деплой новых слов — просто выкатить новую сборку, никаких ручных SQL-скриптов.


Добавление слов и языков

README репозитория документирует процесс для контрибьюторов.

Добавить слова

  1. Отредактировать translations.json
  2. Создать миграцию:
cd src && dotnet ef migrations add MigrationName \
  -p Laraue.Apps.LearnLanguage.DataAccess \
  -s Laraue.Apps.LearnLanguage.Host -v
  1. Новые переводы применятся автоматически при следующем запуске.

Добавить язык

  1. Отредактировать languages.json
  2. Выполнить ту же команду создания миграции.

Больше никаких изменений в коде не нужно — пайплайн переводов, режим квиза и выбор языка подхватят новые языки автоматически.


Локальная разработка

Бот локально запускается в режиме long-polling (публичный URL и webhook не нужны):

  1. Создайте бота через @BotFather и скопируйте токен.
  2. Создайте appsettings.Development.json в проекте Laraue.Apps.LearnLanguage.Host:
{
  "Telegram": {
    "Token": "ваш_токен_бота"
  }
}
  1. Запустите Laraue.Apps.LearnLanguage.Host.
  2. Напишите боту /start в Telegram.

Для AutoTranslator также потребуется локально запущенный Ollama с подходящей моделью.


CI/CD

Репозиторий содержит GitHub Actions воркфлоу (.github/workflows/) для автоматической сборки и прогона тестов. Интеграционные тесты находятся в tests/Laraue.Apps.LearnEnglish.IntegrationTests/.


История развития проекта

Эволюция архитектуры объясняет часть текущих проектных решений:

Дата Изменение
Янв 2023 Первая версия: просмотр списка слов + ручная кнопка «отметить как выученное»
Янв 2024 Добавлен просмотр по уровням CEFR
Фев 2024 Архитектура рефакторена для поддержки нескольких языковых пар
Июн 2024 Добавлен AutoTranslatorApp (Google Translate API)
Авг 2025 Переход на Ollama для локального AI-перевода
Сен 2025 Добавлен режим квиза
Фев 2026 Релиз v1.0.0 — квизы по уровням CEFR

Планы на будущее

  • Гибкая фильтрация квиза — ограничение пула слов по теме или уровню CEFR
  • Контекстные предложения от AI — объединение недавно изученных слов в короткие тексты для долгосрочного запоминания
  • Тематические паки слов — наборы для конкретных жизненных ситуаций: аэропорт, ресторан, транспорт

Как помочь проекту

Проект распространяется под лицензией MIT и открыт для контрибьюций. Самый простой вклад — редактирование translations.json для добавления недостающих переводов или исправления существующих: знание C# не требуется. Для фичей архитектура чистая и хорошо изолированная, так что добавить новую команду бота или расширить движок квиза несложно.