Skip to content

Telegram travel assistant bot. Written using aiogram 3

License

Notifications You must be signed in to change notification settings

j3rrryy/travel_bot

Repository files navigation

Python: 3.12 License: MIT Code style: black

📜 О боте

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

Бот построен на основе асинхронной библиотеки Aiogram для создания Telegram ботов на языке Python. При его создании был сделан упор на хорошую производительность, поэтому все операции с внешними сервисами (PostgreSQL, Redis, различные API) и файловой системой выполняются асинхронно, а все синхронные операции, которые могут быть выполнены только локально, например: отрисовка маршрута на карте и сохранение в формате фото, выполняются в отдельном потоке.

  • Обязательные функциональные возможности

    • 👤 Добавление данных пользователя

    • 🌍 Управлением путешествием

    • 📓 Заметки к путешествию

    • 👥 Путешествия с друзьями

    • 🚗 Прокладывание маршрута путешествия

  • Опциональные функциональные возможности

    • ⛅ Прогноз погоды в промежуточных точках

    • 🏰 Рекомендация местных достопримечательностей

    • 👥 Поиск пользователей для совместного путешествия

    • 💸 Общие траты в путешествии

    • 💡 Ваши собственные идеи (Конвертер валют; Возврат долга в выбранной валюте; Случайный выбор участника путешествия, который платит за всех)

💻 Зависимости

  • 🐋 Docker

📄 docker-compose.yml

docker-compose.yml содержит в себе:

  • 📁 Тома
volumes:
  files: # том с фотографиями маршрутов и файлами пользователей
  pg_data: # том PostgreSQL
  redis_data: # том Redis
  • 📡 Сервисы

    • Бот

      bot:
        # сборка на основе Dockerfile
        build: .
        # перезагрузка в случае ошибки
        restart: always
        # применение миграций и запуск бота
        command: bash -c "alembic upgrade head && python bot.py"
        # открытие портов
        ports:
          - 8080:8080
        # использование файла для установки переменных окружения
        env_file:
          - .env
        # том с файлами
        volumes:
          - files:/files
        # ожидание запуска необходимых для работы контейнеров
        depends_on:
          - postgres
          - redis
        # установка имени контейнера
        container_name: travel_bot
    • PostgreSQL

      postgres:
        # сборка на основе легковесного alpine образа
        image: postgres:alpine
        # перезагрузка в случае ошибки
        restart: always
        # использование файла для установки переменных окружения
        env_file:
          - .env
        # том с данными
        volumes:
        - pg_data:/var/lib/postgresql/data/
        # установка имени контейнера
        container_name: postgres_bot
    • Redis

      redis:
        # сборка на основе легковесного alpine образа
        image: redis:alpine
        # перезагрузка в случае ошибки
        restart: always
        # запуск Redis
        command:
          - redis-server
        # использование файла для установки переменных окружения
        env_file:
          - .env
        # том с данными
        volumes:
          - redis_data:/data
        # установка имени контейнера
        container_name: redis_bot
  • 🛠️ Начало работы

    • Создайте Telegram бота с помощью @BotFather и получите токен
    • Зарегистрируйтесь в Openrouteservice и получите токен
    • Зарегистрируйтесь в Geoapify и получите токен
    • Создайте .env файл с использованием шаблона examples/.env.example
  • 🚀 Запуск бота

    docker compose up --build -d
  • Остановка

    docker compose stop

🌐 Сервисы и внешние интеграции

  • PostgreSQL — надежная SQL СУБД с отличной производительностью и масштабируемостью. Все эти качества делают ее отличным выбором для высоконагруженных проектов. В боте используется в качестве основной БД. Также в проекте используется Alembic — удобный инструмент для проведения операций с миграциями и контроля их версий. В БД содержатся следующие таблицы:

    • alembic_version (служебная таблица)
    version_num
    pk, character varying(32), not null
    • users
    id username age sex latitude longitude city country currency bio
    pk, bigint, not null character varying, not null integer, not null character varying, not null double precision double precision character varying character varying, not null character varying, not null character varying
    • trips
    id username name description locations friends
    pk, integer, not null fk (users.username), character varying, not null character varying, not null character varying json[] character varying[]
    • notes
    id user_id trip_id name path file_type width height is_private
    pk, integer, not null fk (users.id), bigint, not null fk (trips.id), integer, not null character varying, not null character varying, not null character varying, not null integer integer boolean
    • expenses
    id username trip_id name cost currency date debtors
    pk, integer, not null fk (users.username), character varying, not null fk (trips.id), integer, not null character varying, not null double precision character varying, not null timestamp without time zone, default now() character varying[]
  • Redis — масштабируемая NoSQL СУБД с потрясающей производительностью, которая хранит данные в виде пар «ключ — значение» прямо в оперативной памяти сервера, что и позволяет их быстро получать. В моем проекте используется для сохранения состояний пользователей и их промежуточных данных, кэширования.

Note

Интересный факт: до настройки кэширования с использованием Redis среднее время ответа бота составляло около 300-350 мс, после настройки оно снизилось до 200-250 мс. Кэширование данных пользователя, а также результатов запросов к внешним сервсиам сделало бота более отзывчивым.

  • OpenStreetMap — открытая карта мира, которую могут редактировать обычные люди. В моем проекте используется для обратного геокодирования (получения города и страны из координат).

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

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

  • Open-Meteo — сервис для получения прогнозов погоды с учетом множества параметров запроса. Для проекта был выбран именно он, ведь данный сервис позволяет получить погоду на целых 16 дней вперед, чего не могут вам предложить другие сервисы.

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

💬 Взаимодействие с ботом

Warning

Перед началом необходимо убедиться, что у вас в Telegram профиле указано имя пользователя в формате @example

  • По нажатию на кнопку /start начинается процедура регистрации пользователя

  • У бота есть боковое меню, которое содержит команды /menu, /profile, /help, они являются основными для взаимодействия с ботом

  • /profile позволяет просмотреть ваш профиль и, по желанию, отредактировать его

  • /menu бота позволяет просмотреть путешествия как созданные вами, так и те, в которые вас пригласили, они будут со значком 🔗; создать новое путешествие; конвертировать валюту, которую вы указали в профиле

  • В процессе создания нового путешествия вы указываете только одну локацию и даты, после создания путешествия вы сможете расширить список локаций

Important

Редактировать/удалять путешествия могут только их организаторы

  • В разделе Друзья можно пригласить своих друзей, либо найти новых друзей с учетом возраста и интересов

Important

Добавлять/находить друзей для путешествия/удалять могут только организаторы путешествия

Note

Поиск по интересам производится на основе полей О себе путем их сравнения и определения коэффициента подобия

  • В разделе Заметки можно создать свою заметку, которая будет прикреплена к данному путешествию. Можно просматривать не только свои заметки, но и открытые чужие, они будут со значком 🔗

Important

Удалять заметки могут только их создатели

  • В разделе Локации можно создать просмотреть все локации путешествию, построить маршрут или добавить новую локацию

Important

Добавлять/удалять локации может только организатор путешествия

Note

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

  • В разделе Траты можно просмотреть, кому ты должен (со значком ❗)/кто тебе; можно записать новые траты и указать всех должников

Important

Редактировать/использовать команду с игрой/удалять траты могут только их создатели

Note

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

Caution

Использование далее описанных инструкций может сильно ударить по вашему кошельку! В выбранной трате можно сыграть в мини игру: случайным образом выбирается человек, который связан с этой тратой, это может быть как один из должников, так и тот, кто за всех заплатил, на него будут списаны все долги

😊 Желаю интересных и захватывающих путешествий

💖 PROD contest 2024