Словари python telegram bot

Футбольный телеграм бот на Python (1/4): Подготовка и настройка бота

В этой серии статей мы напишем телеграм бота на python. Он работает с внешним API, запрашивает результаты футбольных матчей и выводить их в сообщении.

Когда локальная версия будет готова, разместим бота на сервере. Вместо Heroku, я выбрал отдельную виртуальную машину, что бы бот не засыпал. Это ближе к реальности.

Вся разработка разбита на этапы:

  1. Локальная установка библиотек и Redis.
  2. Регистрация и получение токена.
  3. Настройка , подключение к базам данных.
  4. Написание основной функциональности бота.
  5. Регистрации, выбор и настройка внешнего апи футбольных матчей.
  6. Добавление сбора результатов матчей и интеграция в бота.
  7. Деплой, публикация на сервере:
    1. Регистрация дешевого или бесплатного VPS.
    2. Запуск Редис-клиента.
    3. Запуск и настройка бота на сервере.

    Рабочая версия бота запущена в телеграме до конца февраля @FonlineBOT. Бот отключен.

    Вводные данные

    Материал рассчитан на уровень Начинающий+, нужно понимать как работают классы и функции, знать основы базы данных и async/await. Если знаний мало, крайне желательно писать код в Pycharm, бесплатная версия подходит.

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

    Версия Python - 3.8+ aiogram==2.11.2 emoji==1.1.0 redis==3.5.3 ujson==4.0.1 uvloop==0.14.0 # не работает и не требуется на Windows

    Локальная установка библиотек для бота и Redis

    Для начала нужно создать проект «fonlinebot» с виртуальным окружение. В Pycharm это делается так:

    pycharm new project

    Затем установить библиотеки в виртуальном окружении. Сразу понадобятся 4: для бота, работы с 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» снова.

    Футбольный телеграм бот на Python (1/4): Подготовка и настройка бота

    На время разработки сохраним токен в файл. Создайте «config.py» в папке проекта для хранения настроек и запишите токен TOKEN = "ВАШ ТОКЕН"

    Настройка бота

    Теперь нужно связать бота с redis и базой данных, проверить работоспособность.

    Создадим необходимые модули и файлы. В папке «fonlinebot» к созданным ранее «main.py» и «config.py» добавим: «database.py», «requirements.txt» и папку «app». В папку «app» добавьте: «bot.py», «dialogs.py», «service.py». Вот такая структура получится:

    Футбольный телеграм бот на Python (1/4): Подготовка и настройка бота

    Разделив бот на модули, его удобнее поддерживать и дорабатывать.

    • «main.py» — для запуска бота.
    • «config.py» — хранит настройки, ключи доступов и другую статическую информацию.
    • «database.py» — для работы с базой данных и кешем(redis).
    • «requirements.txt» — хранит зависимости проекта, для запуска на сервере.
    • «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

      Так как большая часть программирует на Windows, uvloop мы не устанавливали локально. Установим его на сервере.

      В «config.py» к токену добавим данные бота и подключения к redis.

       
      # fonlinebot/config.py import ujson import logging logging.basicConfig(level=logging.INFO) TOKEN = "здесь должен быть токен" BOT_VERSION = 0.1 # База данных хранит выбранные юзером лиги BOT_DB_NAME = "users_leagues" # Тестовые данные поддерживаемых лиг BOT_LEAGUES = < "1": "Бундеслига", "2": "Серия А", "3": "Ла Лига", "4": "Турецкая Суперлига", "5": "Чемпионат Нидерландов", "6": "Про-лига Бельгии", "7": "Английская Премьер-лига", "8": "Лига 1", ># Флаги для сообщений, emoji-код BOT_LEAGUE_FLAGS = < "1": ":Germany:", "2": ":Italy:", "3": ":Spain:", "4": ":Turkey:", "5": ":Netherlands:", "6": ":Belgium:", "7": ":England:", "8": ":France:", ># Данные redis-клиента REDIS_HOST = 'localhost' REDIS_PORT = 6379 # По умолчанию пароля нет. Он будет на сервере REDIS_PASSWORD = None

      Информацию о лигах в будущем можно будет вынести в отдельный json файл. Эта версия бота будет поддерживать не более 10 вариантов, я явно их записал.

      Добавление базы данных

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

      Юзер будет выбирать 3 чемпионата для отслеживания, бот сохранит их в БД и использует для запроса результатов.

      Кеш(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) logging.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 . Мы добавляем 2 метода jset , jget для сохранения списков и словарей python в хранилище redis. Изначально он не работает с ними.

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

       
      # fonlinebot/database.py #. class Database: """ Класс работы с базой данных """ def __init__(self, name): self.name = name self._conn = self.connection() logging.info("Database connection established") def create_db(self): connection = sqlite3.connect(f".db") logging.info("Database created") 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"Leagues for user updated") async def delete_users(self, user_id: int): delete_query = f"""DELETE FROM users WHERE self._execute_query(delete_query) logging.info(f"User deleted")

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

      Файл базы данных будет создаваться один раз, автоматически. Теперь нужно создать экземпляры классов:

      Источник

      Как интегрировать словарь в json в телеграм бота на python

      Выдает кучу ошибок, как исправить код, чтобы бот доставал ссылки из текстовика посредством json.

      Остановка Бота в телеграм через python
      Не могу понять как остановить бота в телеграм, У меня есть main.js от туда я его запускаю с.

      Разработка бота для Телеграм на Python
      Напишу телеграм бота на языке Python 3 и быстром, современном, асинхронном движке Aiogram. Сферы.

      Разработка сложного Телеграм бота, Python или TypeScript?
      Всем форумчанам ДВС! Вопрос у меня к обществу, скорее стратегический нежели технический. Я.

      Подскажите лучшую библиотеку python для разработки телеграм бота
      Раньше использовал PyTelegramBotAPI или просто TeleBot, но ощущение что чего-то не хватает, а.

      Эксперт Python

      ЦитатаСообщение от pavlishka Посмотреть сообщение

      секретных? или их можно привести?

      почему не пошел сразу в документацию читать про жсон?

      C:\Users\Павел\AppData\Local\Programs\Python\Python39\python.exe C:/Users/Павел/PycharmProjects/sa-bot/sa-bot/sa_bot.py
      Traceback (most recent call last):
      File "C:\Users\Павел\PycharmProjects\sa-bot\sa-bot\sa_bot.py", line 4, in
      import links
      File "C:\Users\Павел\PycharmProjects\sa-bot\sa-bot\links.py", line 3, in
      ls = load(open('links.txt'))
      File "C:\Users\Павел\AppData\Local\Programs\Python\Python39\lib\json\__init__.py" , line 293, in load
      return loads(fp.read(),
      File "C:\Users\Павел\AppData\Local\Programs\Python\Python39\lib\json\__init__.py" , line 346, in loads
      return _default_decoder.decode(s)
      File "C:\Users\Павел\AppData\Local\Programs\Python\Python39\lib\json\decoder.py", line 337, in decode
      obj, end = self.raw_decode(s, idx=_w(s, 0).end())
      File "C:\Users\Павел\AppData\Local\Programs\Python\Python39\lib\json\decoder.py", line 353, in raw_decode
      obj, end = self.scan_once(s, idx)
      json.decoder.JSONDecodeError: Invalid control character at: line 4 column 147 (char 230)

      Process finished with exit code 1

      Эксперт Python

      у меня нет проблем с этим текстом

      Добавлено через 45 секунд

      ЦитатаСообщение от pavlishka Посмотреть сообщение

      там другой текст, в твоем примере 201 символ всего

      Добавлено через 1 минуту
      смотри что там в файле на этой позиции

      ЦитатаСообщение от pavlishka Посмотреть сообщение

      1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
      #обработка сообщений @bot.message_handler(content_types=['text']) def main_menu(message): if message.text == 'Справочник': kb_sprav = telebot.types.InlineKeyboardMarkup(row_width=1) for key in sprav.spr: cur_but = telebot.types.InlineKeyboardButton(text=key, callback_data=key) kb_sprav.add(cur_but) bot.send_message(message.chat.id, 'Справочник:', reply_markup=kb_sprav) elif message.text == 'Ссылки': kb_links = telebot.types.InlineKeyboardMarkup() for text, url in json.load(open('links.txt')).items(): kb_links.add( telebot.types.InlineKeyboardButton( text=text, url=url, callback_data="linked") ) bot.send_message(message.chat.id, 'Ссылки:', reply_markup=kb_links) elif message.text == 'Программы': kb_prog = telebot.types.InlineKeyboardMarkup() for key in prog.pr: cur_but = telebot.types.InlineKeyboardButton(text=key, url=prog.pr[key], callback_data="pr") kb_prog.add(cur_but) bot.send_message(message.chat.id, 'Программы:', reply_markup=kb_prog) elif message.text == 'Расписание МИР-20-1Б': kb_raspis = telebot.types.InlineKeyboardMarkup() for key in raspis.ras: cur_but = telebot.types.InlineKeyboardButton(text=key, url=raspis.ras[key], callback_data="ras") kb_raspis.add(cur_but) file = open('2020-2021 Raspisanie ehkzamenov EHTF MIR -20-1b (vesennijj sessiya).xlsx', 'rb') bot.send_document(message.chat.id, file) elif message.text == 'Расписание МИР-20-2Б': kb_raspis = telebot.types.InlineKeyboardMarkup() for key in raspis.ras: cur_but = telebot.types.InlineKeyboardButton(text=key, url=raspis.ras[key], callback_data="ras") kb_raspis.add(cur_but) file = open('2020-2021 Raspisanie ehkzamenov EHTF MIR -20-2b (vesennijj sessiya).xlsx', 'rb') bot.send_document(message.chat.id, file) elif message.text == 'Тестирования': kb_raspis = telebot.types.InlineKeyboardMarkup() for key in raspis.ras: cur_but = telebot.types.InlineKeyboardButton(text=key, url=raspis.ras[key], callback_data="ras") kb_raspis.add(cur_but) file = open('Raspisanie_rubezhnogo_testir__2_sem_2020_21_uch_g_posle_smeny_ETF_redaktirovannoe.pdf', 'rb') bot.send_document(message.chat.id, file) @bot.callback_query_handler(func=lambda call: True) def callback_inline(call): if call.message.text == "Справочник:": bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.id, text=call.data + '\n' + sprav.spr[call.data], reply_markup=None) elif call.data == "linked": bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.id, text="Ссылки. ", reply_markup=None) #циклическая проверка на новые сообщения боту bot.polling()

      это весь основной код бота

      Добавлено через 2 минуты
      Он цветом не выделяет модуль links

      Источник

      Читайте также:  Php http request parameters
Оцените статью