Telegram Bot一直显示‘Getting updates...’且无法启动游戏的解决方法
Telegram Bot点击启动按钮无法打开游戏且重复获取更新的问题
我正在开发一款Telegram Bot,它能正常响应命令并发送消息,但点击「Start game」按钮后无法打开游戏,反而Bot一直卡在「Getting updates...」状态,无法处理后续的消息或回调。怀疑是offset变量更新不正确导致重复获取相同更新,求修改代码解决问题。
原代码如下:
import requests import time import json TOKEN = 'TOKEN' GAME_URL = 'https://www.yyyyyyy.info/index.html' URL = f"https://api.telegram.org/bot{TOKEN}" offset = None # Initialized offset def send_message(chat_id, text, keyboard=None): url = f"{URL}/sendMessage" if keyboard: payload = {'chat_id': chat_id, 'text': text, 'reply_markup': json.dumps(keyboard)} else: payload = {'chat_id': chat_id, 'text': text} requests.post(url, json=payload) def answer_callback_query(callback_query_id, url): answer_url = f"{url}?game_url={GAME_URL}" response = requests.get(f"{URL}/answerCallbackQuery", params={'callback_query_id': callback_query_id, 'url': answer_url}) print(f"Answer Callback Query Response: {response.text}") def start_game(chat_id): # Placeholder function for starting the game game_message = "The game is starting! Please wait..." send_message(chat_id, game_message) while True: try: print("Getting updates...") response = requests.get(f"{URL}/getUpdates", params={'offset': offset}).json() if response.get('ok'): updates = response['result'] print(f"Received updates: {updates}") # Debugging line to see received updates for update in updates: print(f"Processing update: {update}") if 'message' in update: chat_id = update['message']['chat']['id'] text = update['message'].get('text', '') keyboard = { 'inline_keyboard': [[{'text': 'Start game', 'callback_data': 'start_game'}]] } if text == '/start' or text.startswith('/'): print(f"Sending welcome message to chat {chat_id}") send_message(chat_id, 'Welcome! Press the button to start the game.', keyboard) else: print(f"Sending unknown command message to chat {chat_id}") send_message(chat_id, 'Unknown command. Press the button to start the game.', keyboard) elif 'callback_query' in update: callback_query_id = update['callback_query']['id'] if update['callback_query']['data'] == 'start_game': print(f"Responding to callback query {callback_query_id} to start the game") start_game(update['callback_query']['message']['chat']['id']) answer_callback_query(callback_query_id, GAME_URL) # Update offset after processing callback_query offset = update['callback_query']['id'] + 1 # Update offset after processing updates offset = update['update_id'] + 1 else: print(f"Failed to fetch updates: {response}") except Exception as e: print(f"Error: {e}") time.sleep(1) # Wait before next request
解决方案
问题修正点
- 修正offset更新逻辑:删除
callback_query分支中错误的offset更新代码,统一使用每个更新的update_id+1来设置offset,确保每次获取更新时跳过已处理的内容。 - 修复
answerCallbackQuery调用:直接传入游戏URL到API的url参数,无需额外拼接参数,同时确保该URL已在BotFather中完成游戏域名配置。 - 优化offset更新时机:在处理完每个更新后统一更新offset,避免重复赋值导致的错误。
修正后的代码
import requests import time import json TOKEN = 'TOKEN' GAME_URL = 'https://www.yyyyyyy.info/index.html' URL = f"https://api.telegram.org/bot{TOKEN}" offset = None # Initialized offset def send_message(chat_id, text, keyboard=None): url = f"{URL}/sendMessage" if keyboard: payload = {'chat_id': chat_id, 'text': text, 'reply_markup': json.dumps(keyboard)} else: payload = {'chat_id': chat_id, 'text': text} requests.post(url, json=payload) def answer_callback_query(callback_query_id): # 直接传入游戏URL,无需额外拼接参数 response = requests.get( f"{URL}/answerCallbackQuery", params={'callback_query_id': callback_query_id, 'url': GAME_URL} ) print(f"Answer Callback Query Response: {response.text}") def start_game(chat_id): # Placeholder function for starting the game game_message = "The game is starting! Please wait..." send_message(chat_id, game_message) while True: try: print("Getting updates...") response = requests.get(f"{URL}/getUpdates", params={'offset': offset}).json() if response.get('ok'): updates = response['result'] print(f"Received updates: {updates}") # Debugging line to see received updates for update in updates: print(f"Processing update: {update}") if 'message' in update: chat_id = update['message']['chat']['id'] text = update['message'].get('text', '') keyboard = { 'inline_keyboard': [[{'text': 'Start game', 'callback_data': 'start_game'}]] } if text == '/start' or text.startswith('/'): print(f"Sending welcome message to chat {chat_id}") send_message(chat_id, 'Welcome! Press the button to start the game.', keyboard) else: print(f"Sending unknown command message to chat {chat_id}") send_message(chat_id, 'Unknown command. Press the button to start the game.', keyboard) elif 'callback_query' in update: callback_query_id = update['callback_query']['id'] if update['callback_query']['data'] == 'start_game': print(f"Responding to callback query {callback_query_id} to start the game") start_game(update['callback_query']['message']['chat']['id']) answer_callback_query(callback_query_id) # 统一使用update_id更新offset,确保跳过已处理的更新 offset = update['update_id'] + 1 else: print(f"Failed to fetch updates: {response}") except Exception as e: print(f"Error: {e}") time.sleep(1) # Wait before next request
额外注意事项
- 确保
GAME_URL对应的域名已在BotFather中通过/setgames命令配置为允许的游戏域名,否则Telegram会拒绝打开该链接。 - 建议使用
long polling的timeout参数替代固定的time.sleep(1),可以减少空轮询次数,提升Bot响应效率,例如:requests.get(f"{URL}/getUpdates", params={'offset': offset, 'timeout': 30}).json()
内容的提问来源于stack exchange,提问作者Daniella Dimitrievna
相关产品推荐
相关产品推荐

