Введение. До бота

Есть некоммерческий спортивный клуб, в котором хотелось бы отслеживать регулярность тренировок участников, осуждать за её отсутствие и составлять рейтинг спортсменов. Для исключительно беговых тренировок можно было бы взять одно из существующих приложений, но у нас есть и другие виды тренировок, а также разработчики с неуёмным энтузиамом.

Первым техническим решением были Google форма + Google таблица с App Scripts. Для любых операций обработки данных нужно было вычитать все строки листа с результатами формы. На определенном количестве строк расчет рейтинга стал тяжелой операцией, которая на слабых клиентских устройствах (а App Scripts выполняются в браузере/приложении таблиц при каждом открытии) выполнялась минутами и часто завершалась по таймауту не выдав результат.

Проблемой оказался и пользовательский опыт ввода тренировки: несколько раз в неделю раз открывать форму, искать себя в списке пользователей и заполнять информацию в многоступенчатой форме — сложное нудное действие, на которое участники клуба часто забивали.

Возможно какие‑то оптимизации работы с таблицей или подключение вместо формы собственного фронта могли бы продлить успешное существование таблицы, глубоко в это мы не погрузились, отказавшись от системы с рейтингом вцелом.

Спустя несколько лет захотелось попробовать сделать лучшую версию этой системы. Требования сформулированы такие:

Основное — надежное долгосрочное хранение данных, при этом бесперебойная работа ввода/получения данных и рейтинга — не критична.

Дополнительное — минимум хранения данных юзеров, при этом — пользователь должен вводить информацию только про себя и как можно проще.

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

Выбор технологий

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

Долго выбирала между тем чтобы остаться на Google таблицах или взять БД Яндекс Облака, захотелось все же больше гибкости и пощупать что‑то новое.

За что выбран Яндекс:

  • Надежное и в то же время бесплатное при малом использовании хранилище данных, простое в использовании. Бесплатно Яндекс предоставляет свою YDB — услуга называется «Managed Service for YDB»

  • Полностью бесплатный при маленькой нагрузке сервер сразу с публичным доменным именем, правда «некрасивым» (называется «технический домен» функции)

  • Удобный интерфейс для поддержки сервиса (БД, версионирование кода) — см. третье требование

Одна Yandex Function

Официальная документация по созданию телеграм бота на Яндекс Функции от Облака

Написание кода на Python было доверено нейронке. Использованные библиотеки — aiogram и ydb.

Получилась простая схема:

Схема не заработала. По логам функции я видела что запросы обрываются по таймауту. Оказалось что время, необходимое на холодный старт функции в облаке, больше чем телеграм готов ждать ответа на webhook.

Схема с двумя Yandex Functions

Логичное решение проблемы на тот момент — поставить перед основной функцией с aiogram и подключением к БД легковесную, которая бы отвечала телеграму 200 и запускала основную тяжелую.

Новая схема:

Схема выше тоже не заработала. Webhook телеграма доходил до функции (что я видела по логам) через два раза на третий. Бот при этом был скорее мёртв чем жив, присылая ответы на команды батчем спустя несколько часов. Это оcобенности работы телеграма — при недоступности сервера он делает отложенные перезапросы с большими интервалами.

Привязка функции к телеграму с помощью прокси

Вооружившись поисковиками и нейронками попробовала такие варианты решения проблемы:

Убрать функцию за Api Gateway от Яндекса. Это по сути прокси‑балансер внутри облака. Его использование рекомендуется в документации, как я поняла — исключительно ради гибкости в будущем, при масштабировании сервиса. Проблему с сетевой доступностью он не решил.

Использовать доменное имя. От старого проекта у меня осталось собственное оплаченное доменное имя в зоне .ru. Перенесла домен в Яндекс облако и привязала к функции (это делается через тот же Api Gateway). Оказалось что пользоваться доменом в яндексе так как мне нужно — платно. На тесты ушло рублей 5 и стоимость должна была вырасти при реальном пользовании, это в мои планы не входило. К тому же сам домен был продлен последний раз на год дорого, и подлевать его снова не планируется. Так что вариант был попробован «для очистки совести». К тому же домен не помог.

Наконец пришла к мысли что сервера яндекса попросту плохо доступны серверам телеграма на сетевом уровне, что сейчас не удивительно. Мысль оказалась верной, потому что использование vps в подходящей стране как прокси трафика к боту и от него решил проблему.

Тут не стану вдаваться в подробности, но в общем стоимость деплоя бота состоит у меня исключительно из стоимости vps, сейчас порядка 200 рублей в месяц.

Вот получившаяся схема с прокси (и Api Gateway):

Теперь запросы доходят до функции каждый раз! Ура, ботом можно пользоваться!

Код варианта с двумя функциями

Бот работал стабильно, но меня не устроила скорость ответов. Задержка прокси‑функции до отправки ответа — порядка 20 секунд. Все‑таки функции от Яндекса больше про редкие долгие вычисления, а не про обслуживание клиентских запросов.

При наличии nginx перед Яндекс Облаком вторую функцию (быстрого ответа) можно убрать, быстрый ответ 200 поручить nginx. Так как в итоге я отказалась от Яндекс Функций вовсе, не стала этого реализовывать в коде. Получилась бы такая упрощенная схема:

Возможно для каких‑то целей этот вариант подойдет.

Перенос бота на свой сервер

С помощью нейронки поправила код под обычный веб‑сервер, в качестве БД осталась та же YDB в Яндекс облаке (она доступна по сети). Итоговая схема:

Так как vps у меня очень дешевый и маленький, разворачиваю сервер прямо из исходников на Python с помощью systemd. Nginx используется для мгновенного ответа 200 телеграму.

Стандартно подключила ssl от Let's Encrypt с помощью Certbot.

Для закрытия всех лишних портов использовала утилиту UFW (Uncomplicated Firewall).

Код варианта с сервером

Заключение

Спасибо всем кто дочитал! Надеюсь чем‑то кому‑то будет полезно. Пишите комментарии

Комментарии (6)


  1. Bombesko
    23.10.2026 07:40

    И зачем тогда этот Яндекс?

    На том бы vps бот не заработал? Смешно ;)

    Показали бы еще как удобно эту облачную функцию запустить… я имею ввиду завливку zip архивов или вставка кода в ручную (давненько не пользовался, может улучшили).

    Если честно - выглядит как неудачная попытка сказать какой Яндекс хороший


    1. r_anisimov
      23.10.2026 07:40

      Полагаю, для хранения персональных данных в РФ)


      1. Bombesko
        23.10.2026 07:40

        а с vps нельзя подключить только ydb?


      1. SurMaster
        23.10.2026 07:40

        и при этом - использование гугл таблиц для хранения тех же ПД? по теме: на мой взгляд можно было сделать проще. Telegram API <- Long Polling -> Python (aiogram) -> SQLite (WAL mode). Бот запускается на VPS как обычный сервис systemd и выгребает сообщения через обычный start_polling(). Данные пишутся в локальный файл db.sqlite3. Раз в сутки cron запускает скрипт, который делает sqlite3 db.sqlite3 “.backup ‘backup.db’” и кидает копию в частный Telegram-канал или S3. Всё. 0 открытых портов: UFW закрывает ВСЁ, кроме SSH. Никаких Nginx, Let’s Encrypt, Certbot, доменных имён и белых IP. Если бот упал или перезагружается, Telegram держит очередь сообщений у себя до 24 часов. Бот поднялся - вычитал всё, ничего не потерялось. Скорость: SQLite в WAL-режиме выдаёт десятки тысяч операций записи в секунду прямо с локального диска. Отклик бота мгновенный (миллисекунды вместо секунд gRPC в YDB). Перенос и бекап: Вся система - это один бинарник/скрипт и один файл базы данных. Переносится на любой VPS за 2 минуты За старания, плюс в карму, но перемудрено, ИМХО


  1. MAXH0
    23.10.2026 07:40

    Я ставлю плюс. Потому, что это такой "школьный" уровень.
    Насколько это бесплатно надо посмотреть и как ВНИМАТЕЛЬНО следить, чтобы не улететь в облака на деньги. Безусловно, не для телеграмм-бота (Кстати, спасибо что опубликовали свой опыт. Самый полезный опыт - чужой негативный. Он экономит время тебе!)
    Конечно это джинса Яндекса, причем низкого технического уровня, но я со своей узкой колокольни оцениваю её позитивно


  1. lunarshade
    23.10.2026 07:40

    У меня под своего бота взят простенький впс, разворачиваю через докер. 3 контейнера - мой бот, рест апи сервер на случай, если телега умрет, и постгря. Обновы разворачиваются двумя командами, настройки больше никакой не требует. Dockerfile и docker-compose нейронки настраивали.