Ошибка функции игрового бота в телеграмме Python на 0x7fcfa257f790

#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 к print вызову внутри него, следовательно, к сообщению.

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 атрибут 😉