Kalorik: Telegram-бот на Rust для анализа питания

от автора

Mascot Kalorik

Mascot Kalorik

Введение

В данной статье мы рассмотрим архитектуру и реализацию Telegram-бота Kalorik, написанного на языке программирования Rust. Этот бот предоставляет пользователям возможность анализировать свой рацион питания, получая автоматический расчёт калорий, макроэлементов и индекса массы тела. Особенностью проекта является использование современного стека на основе tokio, sqlx, teloxide, а также продуманная архитектура с учётом масштабируемости.

Задачи, решаемые ботом

Kalorik реализует следующие функции:

  • Обработка текстовых сообщений с описанием приёма пищи

  • Распознавание изображений и голосовых сообщений

  • Подсчёт калорий, БЖУ, ИМТ

  • Хранение истории и профиля пользователя

  • Настройка целей и отслеживание прогресса

Архитектура проекта

Проект состоит из следующих ключевых модулей:

  • main.rs — точка входа, инициализация окружения и запуск бота

  • telegram/handlers.rs — обработка входящих сообщений Telegram

  • db/queries.rs — доступ к базе данных (PostgreSQL через sqlx)

  • db/models.rs — структура таблиц и моделей

  • services/nutrition.rs — логика анализа продуктов и подсчёта нутриентов

Проект построен с использованием OnceLock для глобального пула соединений с базой данных и асинхронного исполнения через tokio.

Пример: Регистрация пользователя

pub async fn register_user(chat_id: i64) -> Result<(), sqlx::Error> {     let Some(pool) = DB_POOL.get() else {         return Err(sqlx::Error::PoolTimedOut);     };      sqlx::query!(         r#"         INSERT INTO users (chat_id, created_at)         VALUES ($1, $2)         ON CONFLICT (chat_id) DO NOTHING         "#,         chat_id,         Utc::now()     )     .execute(pool)     .await?;      Ok(()) } 

Здесь реализуется вставка пользователя в таблицу, если он отсутствует. Используется UPSERT-подход, обеспечивающий идемпотентность.

Работа с Telegram

match &msg.kind {     MessageKind::Common(msg) => match &msg.media_kind {         MediaKind::Text { text, .. } => {             if text == "/start" {                 register_user(msg.chat.id).await?;                 bot.send_message(msg.chat.id, "Введите описание приёма пищи").await?;             } else {                 let result = analyze_food_description(text).await;                 bot.send_message(msg.chat.id, result).await?;             }         }         MediaKind::Photo { photo, .. } => {             // Обработка фото через модель         }         MediaKind::Voice { voice, .. } => {             // Обработка голосовых сообщений         }         _ => {}     }     _ => {} } 

Здесь представлен разбор варианта обработки текста и мультимедиа. Используется teloxide, который предоставляет удобный API для работы с Telegram Bot API.

Хранение и миграции

let db_url = env::var("DATABASE_URL").expect("DATABASE_URL not set"); let pool = PgPoolOptions::new().connect(&db_url).await?; sqlx::migrate!("./migrations").run(&pool).await?;

Проект использует sqlx с автоматическим применением миграций. Миграции хранятся в отдельной папке и обеспечивают прозрачность в изменениях схемы.

Развёртывание

Бот может быть запущен как systemd-сервис или Docker-контейнер. Пример systemd unit-файла:

[Unit] Description=Kalorik Telegram Bot After=network.target  [Service] ExecStart=/usr/local/bin/kalorik WorkingDirectory=/var/www/kalorik Restart=always Environment=DATABASE_URL=postgres://...  [Install] WantedBy=multi-user.target 

Также возможно подключение GitHub Actions для CI/CD и обновления контейнера при пуше в main ветку.

Заключение

Kalorik демонстрирует, как на Rust можно создать безопасного и надёжного Telegram-бота с использованием производительных и типобезопасных библиотек. Благодаря sqlx, tokio и teloxide, разработка получилась эффективной и лаконичной. Проект легко масштабируется и адаптируется под другие задачи, связанные с пользовательскими данными или обработкой сообщений.

Проект открыт для расширений: можно добавить мини-приложение, авторизацию через Telegram Web App, отчёты по питанию, интеграцию с OpenAI или Hugging Face для анализа описаний еды.

Попробовать бота @kalorikbot
Репозиторий проект, где находится весь код https://github.com/digkill/Kalorik


ссылка на оригинал статьи https://habr.com/ru/articles/910298/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *