#python #bots #telegram #python-telegram-bot
Вопрос:
Я новичок в Python и недавно попытал счастья, создав бота (как и вы…), созданного Марком Пауэрсом под названием Telegram Arcade
Как было очевидно, он был построен с использованием фреймворка python-telegram-бота. Несмотря на то, что его настройка выглядела простой (с прилагаемыми инструкциями) Я не могу заставить его работать.
Даже после того, как я обновил часть кода, чтобы соответствовать изменениям в структуре, теперь я получаю ошибку, которая отображается вместе с пользователем, взаимодействующим с ботом: ошибка функции в 0x7fcfa257f790 .
Код на данный момент выглядит следующим образом:
import configparser, threading, requests, json, re, time, sys
from uuid import uuid4
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
from telegram import InlineQueryResultGame, ParseMode, InputTextMessageContent
from telegram.ext import Updater, CommandHandler, CallbackQueryHandler, InlineQueryHandler, CommandHandler
from telegram.ext import CallbackContext
from http.server import HTTPServer, BaseHTTPRequestHandler
import logging
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
class Global:
def __init__(self):
return
class GameHTTPRequestHandler(BaseHTTPRequestHandler):
def __init__(self, *args):
BaseHTTPRequestHandler.__init__(self, *args)
def do_GET(self):
if "#" in self.path:
self.path = self.path.split("#")[0]
if "?" in self.path:
(route, params) = self.path.split("?")
else:
route = self.path
params = ""
route = route[1:]
params = params.split("amp;")
if route in Global.games:
self.send_response(200)
self.end_headers()
self.wfile.write(open(route '.html', 'rb').read())
elif route == "setScore":
params = {}
for item in self.path.split("?")[1].split("amp;"):
if "=" in item:
pair = item.split("=")
params[pair[0]] = pair[1]
print(params)
if "imid" in params:
Global.bot.set_game_score(params["uid"], params["score"], inline_message_id=params["imid"])
else:
Global.bot.set_game_score(params["uid"], params["score"], message_id=params["mid"], chat_id=params["cid"])
self.send_response(200)
self.end_headers()
self.wfile.write(b'Set score')
else:
self.send_response(404)
self.end_headers()
self.wfile.write(b'Invalid game!')
def start(update, context):
bot.send_game(update.message.chat_id, Global.featured)
def error(update, context):
print(update, error)
def button(update, context):
print(update)
query = update.callback_query
game = query.game_short_name
uid = str(query.from_user.id)
if query.message:
mid = str(query.message.message_id)
cid = str(query.message.chat.id)
url = "http://" Global.host ":" Global.port "/" game "?uid=" uid "amp;mid=" mid "amp;cid=" cid
else:
imid = update.callback_query.inline_message_id
url = "http://" Global.host ":" Global.port "/" game "?uid=" uid "amp;imid=" imid
print(url)
bot.answer_callback_query(query.id, text=game, url=url)
def inlinequery(update, context):
query = context.inline_query.query
results = []
for game in Global.games:
if query.lower() in game.lower():
results.append(InlineQueryResultGame(id=str(uuid4()),game_short_name=game))
context.inline_query.answer(results)
def main():
config = configparser.ConfigParser()
config.read('config.ini')
token = config['DEFAULT']['API_KEY']
Global.games = config['DEFAULT']['GAMES'].split(',')
Global.host = config['DEFAULT']['HOST']
Global.port = config['DEFAULT']['PORT']
Global.featured = config['DEFAULT']['FEATURED']
updater = Updater(token=token, use_context=True)
updater.dispatcher.add_handler(CommandHandler('start', start))
updater.dispatcher.add_handler(InlineQueryHandler(inlinequery))
updater.dispatcher.add_handler(CallbackQueryHandler(button))
updater.dispatcher.add_error_handler(error)
Global.bot = updater.bot
print("Polling telegram")
updater.start_polling()
print("Starting http server")
http = HTTPServer((Global.host, int(Global.port)), GameHTTPRequestHandler)
http.serve_forever()
if __name__ == '__main__':
main()
Я читал документ и изучал примеры, и, похоже, не могу найти решение этой проблемы. Даже команды inlineCommands не работают, отображая аналогичную ошибку. Я был бы очень признателен за любой совет, и мне жаль, что я не эксперт, объясняющий мою ситуацию.. Спасибо!
Комментарии:
1. Это не ошибка: это строковое представление функции
error
. Вы переходитеerror
к2. @энцо О… Я понимаю… тогда nvm… До сих пор не могу понять, почему это не работает…
3. Дополнительно: Когда я пытаюсь запустить код «как есть» в исходном git, я получаю следующую ошибку:
File "main.py", line 52, in start bot.send_game(update.message.chat_id, Global.featured) AttributeError: 'Update' object has no attribute 'send_game'
4.
bot.send_game
Работает ли переодеваниеGlobal.bot.send_game
?5. Кроме того, подпись вашей
start
функции не совпадает с подписью исходнойstart
функции . Исправляется ли это, когда вы его меняете?
Ответ №1:
python-telegram-bot
изменилось, как работают обратные вызовы в версии 12, которая была выпущена два года назад. Репо, которое вы используете, похоже, все еще работает со старыми обратными вызовами. Я рекомендую сначала попробовать и заставить его работать с ptb версии 11.1. или 12.0 без передачи use_context=True
(в v12 это по-прежнему по умолчанию False
для обратной совместимости). Если это работает нормально и вы хотите перейти на более новые python-telegram-bot
версии, я настоятельно рекомендую прочитать руководства по переходу для v12 и v13.
Отказ от ответственности: В настоящее время я являюсь сопровождающим python-telegram-bot
.
Комментарии:
1. Спасибо, я буду читать руководства по переходу! Что касается моей проблемы, то, похоже, иногда
context.
все работает не так, как задумывалось. После уведомления об исправлении от @enzo я заглянул в руководство по переходу и соответствующим образом обновил его , но я все еще не мог приступить к работе, пока не вернулся к этому:def inlinequery(update, context): query = update.inline_query.query results = [] for game in Global.games: if query.lower() in game.lower(): results.append(InlineQueryResultGame(id=str(uuid4()),game_short_name=game)) update.inline_query.answer(results)
2. Да, в этом есть смысл.
update
Параметр — это входящее обновление, отправленное сервером API бота, в данном случае оно содержит встроенный запрос.context
параметр содержит «только» удобства, которые связаны с настройкой PTB. вот почему вы не можете ожидатьcontext
, что у вас будетinline_query
атрибут 😉