Exception has occurred: ConnectTimeout HTTPSConnectionPool(host=’api.telegram.org’, port=443): Max retries exceeded with url: /bot1101114834:AAHYPyEyL7QicW8OQuKsiDrN28gBBAmcCJg/getUpdates?offset=1https://lajfhak.ru-land.com/stati/ne-rabotaet-telegram-bot-na-python» target=»_blank»]lajfhak.ru-land.com[/mask_link]
Футбольный телеграм бот на Python (1/4): Подготовка и настройка бота
В этой серии мы напишем бота для Telegram на языке python. Он работает с внешним API для запроса футбольных оценок и вывода их в сообщении.
Как только локальная версия будет готова, мы поместим бота на сервер, но не на Heroku, а на другую виртуальную машину, чтобы бот не заснул. Это ближе к реальности.
Вся разработка делится на этапы.
- Локальная установка библиотек и Redis.
- Регистрация и приобретение токенов.
- Настройка и подключение к базе данных.
- Написание базовой функциональности бота.
- Регистрация, выбор и настройка внешнего match api.
- Добавление сбора результатов матчей и интеграция их в бота.
- Развертывание, публикация серверов
- Регистрация дешевого или бесплатного VPS.
- Запуск Redis-клиента.
- Запуск и настройка бота на сервере.
Вводные данные
Данный материал предназначен для начинающих и выше уровня, вы должны понимать, как работают классы и функции, знать основы баз данных и асинхронности/ожидания. Если ваших знаний недостаточно, рекомендуется писать код в Pycharm (бесплатная версия).
Telegram бот на Python | Работа с TG API
Используя указанную версию библиотеки, вы можете заставить свой проект работать без каких-либо изменений. Установка других версий может привести к ошибкам совместимости.
Версия Python — 3.8+ aiogram==2.11.2 emoji==1.1.0 redis==3.5.3 ujson==4.0.1 uvloop==0.14.0 # не работает и не требуется на Windows
Хранилище, содержащее код для этой части бота.
https://gitlab.com/PythonRu/fonlinebot/-/tree/master/first_step
Локальная установка библиотек для бота и Redis
Сначала создайте проект «fonlinebot» в виртуальной среде. Это делается в программе Pycharm.
Затем мы устанавливаем библиотеку в виртуальной среде. Нам понадобится сразу четыре: один для бота, один для манипуляций с redis, один для ускорения и один для emoji в сообщениях.
pip install aiogram==2.11.2 redis==3.5.3 ujson==4.0.1 emoji==1.1.0
Установка Redis локально
Redis — это резидентная база данных (база данных, которая хранит записи непосредственно в памяти), состоящая из пар ключ-значение. Чтение и запись в память происходит гораздо быстрее, чем на диск, поэтому она подходит для хранения вторичных данных.
Из недавней статьи — Redis для приложений на Python
Чтобы установить Redis на Linux/Mac, следуйте приведенным ниже инструкциям, просто введите https://redis.io/download#from-source-code, и вы будете готовы к работе в кратчайшие сроки. src/redis-server .
Если вы устанавливаете на Windows, скачайте и распакуйте файл отсюда. Откройте файл «redis-server.exe» и запустите его.
Теперь вам нужно убедиться, что все работает. Создайте файл с именем «main.py» в корне вашего проекта и выполните следующий код
Копия копия копия копия копия Используйте другой браузер
# fonlinebot/main.py import redis r = redis.StrictRedis() print(r.ping())
На выходе получается True В противном случае генерируется ошибка.
Регистрация бота и получение токена
Чтобы зарегистрировать бота, необходимо написать команду https://t.me/botfather. /newbot . Затем вам будет предложено ввести имя и адрес бота. Если данные верны, вы получите токен. Обратите внимание, что адрес должен быть уникальным, и что вы не можете использовать «fonlinebot» по-разному.
Во время разработки токен будет сохранен в файле. Создайте файл «config.py» в папке вашего проекта, сохраните конфигурацию и запишите токен TOKEN = «ВАШ ТОКЕН»
Настройка бота
Теперь пришло время связать бота с redis и базой данных и проверить его работоспособность.
Создайте необходимые модули и файлы: в папку «fonlinebot» добавьте папки «database.py», «requirements.txt» и «app», в дополнение к файлам «main.py» и «config.py», которые вы только что создали; в папку «app» добавьте файл Добавлены «bot.py», «dialogs.py» и «service.py». Вот как выглядит структура.
Разделение бота на модули делает его более удобным для обслуживания и улучшения.
Теперь пора переходить к программированию. Давайте запишем зависимости в «requirements.txt».
aiogram==2.11.2 emoji==1.1.0 redis==3.5.3 ujson==4.0.1 uvloop==0.14.0
У большинства людей uvloop не установлен локально, потому что они программируют под Windows. Давайте установим его на сервер.
В «config.py» мы добавляем данные бота и соединение с redis к токену.
Копировать Копировать Использовать другой браузер
# fonlinebot/config.py import ujson import logging.basicConfig(level=logging.INFO) TOKEN = «здесь должен быть токен» BOT_VERSION = 0. 1 # Если пользователь BOT_DB_NAME = «users_leagues» # Тестовые данные для поддерживаемых лиг BOT_LEAGUES = < «1»: «Bundesliga», «2»: «Serie A», «3»: «La Liga», «4»: » Турецкая Суперлига», «5»: «Чемпионат Голландии», «6»: » Бельгия Про Лиг», «7»: «Английская Премьер Лига», «8»: «Английская Премьер Лига».» League 1″, ># Флаги и коды эмодзи для сообщений BOT_LEAGUE_FLAGS = < «1»: «:Германия:», «2»: «:Италия:», «3»: «:Испания:», «4»: «:Турция:», «5». :Netherlands:», «6»: «:Belgium:», «7»: «:England:», «8»: «:France:», ># данные redis-клиента REDIS_HOST = ‘localhost’ REDIS_PORT = 6379 # По умолчанию пароль отсутствует. Он размещается на сервере REDIS_PASSWORD = None
В будущем возможно размещение информации о лиге в отдельном json-файле. Эта версия бота поддерживает до 10 различных вариаций, и я записал их в явном виде.
Добавление базы данных
Далее мы добавляем классы для работы с базами данных sqlite и redis. База данных необходима для хранения предпочтений пользователя по лигам.
Когда пользователь выбирает три чемпионата, которые он хочет отслеживать, бот сохраняет их в базе данных и использует ее для запроса результатов.
Храня результаты совпадений, redis уменьшает количество запросов к API и, следовательно, время ответа. Как правило, бесплатный API ограничивает количество запросов.
Копировать Копировать Использовать другой браузер
# fonlinebot/database.py import os import logging import sqlite3 import redis import ujson import config # класс наследуется от redis.StrictRedis class Cache(redis. StrictRedis): def __init__(self, host, port, password, charset=»utf-8″, decode_responses=True): super(Cache, self). __init__(host, port, password=password, charset=charset, decode_responses=decode_responses) Ведение журнала. info(«Redis start») def jset(self, name, value, ex=0): «»»Функция преобразует объект python в Json и сохраняет»» r = self.get(name) if r is None: return r return ujson.loads(r) def jget(self, name): «»»Функция возвращает Json и конвертирует в объект python»» return ujson.loads(self.get(name))
Класс Cache наследуется от StrictRedis . Добавьте два метода jset , jget для хранения списков и словарей python в хранилище redis. Поначалу у них ничего не получается.
Теперь давайте создадим базу данных и добавим класс для выполнения функции CRUD.
Копировать Копировать Копировать Использовать другой браузер
# fonlinebot/database.py class database: «»» класс базы данных «»» def __init__(self, name): self.name = name self._conn = self.connection() logging.info(«» Соединение с базой данных установлено») def create_db(self): connection = sqlite3.connect(f».db») logging.info(«База данных создана») cursor = connection.cursor() cursor.execute(»’CREATE TABLE users (id INTEGER PRIMARY KEY, leagues VARCHAR NOT NULL);»’) connection.commit() cursor.close() def connection(self): db_path = os.path.join(os.getcwd(), f».db») if not os.path.exists(db_path): self.create_db() return sqlite3.connect(f». db») def _execute_query(self, query, select=False): cursor = self._conn.cursor() cursor.execute(query) if select: records = cursor.fetchone() cursor.close() return records else: self._conn.commit() cursor. close() async def insert_users(self, user_id: int, leagues: str): insert_query = f «»»INSERT INTO users (id, leagues) VALUES (, «»)»»»» self._execute_query(insert_query) logging.info(f «Leagues for user added») async def select_users(self, user_id: int): select_query = f»»»SELECT leagues from leagues where record = self._ execute_query(select_query, select=True) return record async def update_users(self, user_id: int, leagues: str): update_query = f»»»Update leagues set leagues = «» where self._execute_query(update_query) logging. info(f «Обновлены лиги для пользователя «) async def delete_users(self, user_id: int): delete_query = f»»»DELETE FROM users WHERE self._execute_query(delete_query) logging.info(f «Пользователь удален»)
Sqlite подходит для тестирования проектов. В будущем нам потребуется перейти на внешнюю базу данных и работать асинхронно. Чтобы не переписывать всю логику работы с базой данных, мы добавили асинхронный синтаксис сразу.
Файл базы данных создается автоматически, только один раз. Далее нам нужно создать экземпляр класса.
Копировать Копировать Копировать Использовать другой браузер
# fonlinebot/database.py # Создаем кэш и объект базы данных cache = Cache( host=config.REDIS_HOST, port=config.REDIS_PORT, password=config.REDIS_ PASSWORD ) database = Database(config.BOT_DB_NAME)
Добавление текстовых сообщений
В шаблоне сообщения инвариант dataclass . Здесь будут содержаться все текстовые ответы. dataclass полезно использовать при вызове аргументов.
Копировать Копировать Использовать другой браузер
Создание бота
В файле «bot.py» мы создаем бота. Импортируйте зависимости, создайте объект бота и первое сообщение.
Копировать Копировать Использовать другой браузер
Функция test_message Принимает любое сообщение и отвечает на него. Кроме того, перед выходом необходимо закрыть соединение с базой данных. Давайте добавим это в конец файла on_shutdown .
Копировать Копировать Использовать другой браузер
# fonlinebot/app/bot.py async def on_shutdown(dp): logging.warning(‘Shutting down. ‘) # Закрываем соединение с БД db._conn.close() logging.warning(«Соединение с БД закрыто»)
Первый запуск бота
Чтобы запустить его, используйте файл «main.py». Импортируйте ботов и настройте параметры объединения.
Копировать Копировать Использовать другой браузер
# fonlinebot/main.py from aiogram import executor from app import bot executor.start_polling(bot.dp, skip_updates=True, on_shutdown=bot.on_ отключение)
Теперь давайте запустим проект, если вы используете Pycharm, откройте вкладку «Terminal» и введите python main.py . Чтобы запустить бота без Pycharm
Теперь откройте Telegram и проверьте его.
Отлично, это работает!» . Теперь давайте напишем несколько основных тестов, чтобы избежать проблем в будущем.