Обновление переменных

Рейтинг: 0Ответов: 1Опубликовано: 23.08.2023

Всем доброго времени суток! Познаю программирование 3 день. Пишу ТГ бота, необходимо чтобы при нажатии на кнопку "Инфо о сервере", выводились актуальные данные из JSON, гугл мне так и не помог. Выводятся только данные полученные при запуске кода. Направьте в верном направлении, куда копать?

   import requests
   import json
   
   
   TOKEN = "`TOKEN`"
   chat_id = "`CHAT ID`"
   message6 = "Выполняется запуск игрового сервера"
   url = f"https://api.telegram.org/bot{TOKEN}/sendMessage?chat_id={chat_id}&text={message6}"
   print(requests.get(url).json()) # Эта строка отсылает сообщение
   
   
   
   import time
   import logging
   import asyncio
   
   from aiogram import Bot, Dispatcher, executor, types
   
   MSG = "Программировал ли ты сегодня, {}?"
   
   logging.basicConfig(level=logging.INFO)
   
   bot = Bot(token=TOKEN)
   dp = Dispatcher(bot=bot)
   
   @dp.message_handler(commands=["ident"])
   async def start_handler(message: types.Message):
       user_full_name = message.from_user.full_name
       await message.reply(f"Привет, {user_full_name}!\nИдентификатор поиска сервера 85568392928905817/101 ")
   
       for i in range(7):
           await asyncio.sleep(60*60*24)
           await bot.send_message(user_id, MSG.format(user_name))
   
           # from aiogram import types
   @dp.message_handler(commands="info")
   async def cmd_start(message: types.Message):
       keyboard = types.ReplyKeyboardMarkup()
       button_1 = types.KeyboardButton(text="Инфо о сервере")
       keyboard.add(button_1)
       button_2 = "Чтение логов"
       keyboard.add(button_2)
       button_3 = "Идентификатор сервера"
       keyboard.add(button_3)
       await message.answer("Что нужно сделать?", reply_markup=keyboard)
       # from aiogram.dispatcher.filters import Text
       
   
   
   
   
   
   @dp.message_handler(lambda message: message.text == "Инфо о сервере")
   async def with_puree(message: types.Message):
       await message.reply(f" {name}\n{addr}\nИгроков: {players} из {max_players}")
   
   def my_func():
       return start_handler
   
   
   
       
   api = "https://api.steampowered.com/IGameServersService/GetServerList/v1/?key=B5582CAD1112CCA94A9524EB72E8D6A4&filter=addr%5C95.165.9.26:27016"  
   response = requests.get(api)
   steam = response.json()
   resp = steam['response']
   tt = resp['servers']
   addr = (tt[0])['addr']
   name = (tt[0])['name']
   players = (tt[0])['players']
   max_players = (tt[0])['max_players']
   
   
   
       
   from aiogram.types import InputFile
   
   path = "C:/Users/kudri/Documents/Euro Truck Simulator 2/server.log.txt" # или "folder/filename.ext"
   
   
   
   @dp.message_handler(lambda message: message.text == "Чтение логов")
   async def with_puree(message: types.Message):
       await message.answer_document(InputFile(path))
   
   
   @dp.message_handler(lambda message: message.text == "Идентификатор сервера")
   async def with_puree(message: types.Message):
       await message.reply(f" Твой идентификатор 85568392928905817/101 ")
   
   if __name__ == "__main__":
       executor.start_polling(dp)

Ответы

▲ 1Принят

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

import requests
import json

TOKEN = "`TOKEN`"
chat_id = "`CHAT ID`"
message6 = "Выполняется запуск игрового сервера"
url = f"https://api.telegram.org/bot{TOKEN}/sendMessage?chat_id={chat_id}&text={message6}"
print(requests.get(url).json())  # Эта строка отсылает сообщение

import time
import logging
import asyncio

from aiogram import Bot, Dispatcher, executor, types

MSG = "Программировал ли ты сегодня, {}?"

logging.basicConfig(level=logging.INFO)

bot = Bot(token=TOKEN)
dp = Dispatcher(bot=bot)


@dp.message_handler(commands=["ident"])
async def start_handler(message: types.Message):
    user_full_name = message.from_user.full_name
    await message.reply(
        f"Привет, {user_full_name}!\nИдентификатор поиска сервера 85568392928905817/101 ")

    for i in range(7):
        await asyncio.sleep(60 * 60 * 24)
        await bot.send_message(user_id, MSG.format(user_name))

        # from aiogram import types


@dp.message_handler(commands="info")
async def cmd_start(message: types.Message):
    keyboard = types.ReplyKeyboardMarkup()
    button_1 = types.KeyboardButton(text="Инфо о сервере")
    keyboard.add(button_1)
    button_2 = "Чтение логов"
    keyboard.add(button_2)
    button_3 = "Идентификатор сервера"
    keyboard.add(button_3)
    await message.answer("Что нужно сделать?", reply_markup=keyboard)
    # from aiogram.dispatcher.filters import Text


@dp.message_handler(lambda message: message.text == "Инфо о сервере")
async def with_puree(message: types.Message):
    api = "https://api.steampowered.com/IGameServersService/GetServerList/v1/?key=B5582CAD1112CCA94A9524EB72E8D6A4&filter=addr%5C95.165.9.26:27016"
    response = requests.get(api)
    steam = response.json()
    resp = steam['response']
    tt = resp['servers']
    addr = (tt[0])['addr']
    name = (tt[0])['name']
    players = (tt[0])['players']
    max_players = (tt[0])['max_players']
    await message.reply(f" {name}\n{addr}\nИгроков: {players} из {max_players}")


def my_func():
    return start_handler


from aiogram.types import InputFile

path = "C:/Users/kudri/Documents/Euro Truck Simulator 2/server.log.txt"  # или "folder/filename.ext"


@dp.message_handler(lambda message: message.text == "Чтение логов")
async def with_puree(message: types.Message):
    await message.answer_document(InputFile(path))


@dp.message_handler(lambda message: message.text == "Идентификатор сервера")
async def with_puree(message: types.Message):
    await message.reply(f" Твой идентификатор 85568392928905817/101 ")


if __name__ == "__main__":
    executor.start_polling(dp)

Здесь твой код получения информации от steam API перенесен в функцию with_puree, теперь каждый раз при запросе информации о сервере, она будет заново спрашиваться у стима, и все будет работать как и ожидается.

P.S От себя добавлю, что использовать requests для получения информации в данном случае плохая практика. Если программирование ты познаешь 3й день, то возможно будет трудно сразу понять, но я объясню (а если ты это и так знаешь, то подумай о будущих читателях):

requests Выполняет весь код синхронно. В обычном не асинхронном коде каждая строчка выполняется последовательно, и каждая следущая строка ждет полного завершения предыдущей. В чем проблема такого подхода? Если одна строка выполняется в данный момент, то другие выполниться не смогут. Что это значит? Запрос в интернет дело не быстрое, может занимать и 3 и 5 и 10 секунд. В случае использования requests на эти 10 секунд бот будет просто стоять, и если им будет пользоваться несколько пользователей, для них это будет выглядеть как лагающий бот.

К счастью как можно видеть по приставке async у всех твоих функций, весь код у тебя Асинхронный, как и вся библиотека aiogram. Поэтому вместо requests можно использовать другую библиотеку: aiohttp

Устанавливать ее уже не нужно, потому что она устанавливается вместе с aiogram, потому что aiogram под капотом использует aiohttp для принятия и отправки сообщений в телеграм.

Код с ней получается чуть более сложным, но зато проблемы с "лагающим" ботом можно будет избежать:

# В начале файла импортируй aiohttp:
import aiohttp

# Создай функцию:

async def fetch_get(req_url: str) -> aiohttp.ClientResponse:
    async with aiohttp.ClientSession() as session:
        async with session.get(req_url) as resp:
            return resp

# Измени Обработчик сообщения "Инфо о сервере":
@dp.message_handler(lambda message: message.text == "Инфо о сервере")
async def with_puree(message: types.Message):
    api = "https://api.steampowered.com/IGameServersService/GetServerList/v1/?key=B5582CAD1112CCA94A9524EB72E8D6A4&filter=addr%5C95.165.9.26:27016"
    response = await fetch_get(api)
    steam = await response.json()
    resp = steam['response']
    tt = resp['servers']
    addr = (tt[0])['addr']
    name = (tt[0])['name']
    players = (tt[0])['players']
    max_players = (tt[0])['max_players']
    await message.reply(f" {name}\n{addr}\nИгроков: {players} из {max_players}")

Теперь запрос к Steam будет выполняться Асинхронно. Что это значит? Когда бот отправит запрос в стим, он не будет ждать 5, 10, или сколько ему нужно секунд до завершения запроса, а будет работать дальше: обрабатывать другие сообщения, выполнять еще какой-то код и т.п. А при получении ответа, бот автоматически вернется к той части, где он его ждал, и отправит ответ уже тому, кто спрашивал инфу о сервере.