Telegram Bot遇Pool timeout问题求助:调超时参数仍无效
Telegram Bot定时任务Pool timeout问题解决方法
问题根源
你用get_updates获取机器人已加入群组的方式是错误的:
get_updates是用于拉取未处理的消息/事件更新,而非获取所有已加入群组的API- 机器人运行
run_polling时会持续调用get_updates拉取更新,定时任务里重复调用会抢占连接池资源,导致所有连接被占满触发Pool timeout - 即便不超时,
get_updates仅返回最近的更新,无法保证覆盖所有机器人加入的群组,会出现遗漏
正确解决方案
改用记录并维护群组ID列表的方式,具体实现:
- 监听机器人被加入群组的事件,自动将群组ID写入本地文件
- 定时任务从本地文件读取所有群组ID,逐个发送消息
修改后的完整代码
from telegram import Update, ChatMemberUpdated from telegram.ext import Application, CommandHandler, ContextTypes, ChatMemberHandler import random import os from dotenv import load_dotenv from datetime import time from telegram.request import HTTPXRequest # 加载环境变量 load_dotenv() TELEGRAM_BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN') GROUP_IDS_FILE = 'group_ids.txt' # 初始化请求配置 trequest = HTTPXRequest( connection_pool_size=10, read_timeout=30, write_timeout=30, connect_timeout=30, pool_timeout=30, media_write_timeout=30 ) application = Application.builder().token(TELEGRAM_BOT_TOKEN).request(request=trequest).build() # 读取本地存储的群组ID def load_group_ids(): if not os.path.exists(GROUP_IDS_FILE): return set() with open(GROUP_IDS_FILE, 'r', encoding='utf-8') as f: return set(map(int, f.read().splitlines())) # 保存群组ID到本地文件 def save_group_id(group_id): group_ids = load_group_ids() if group_id not in group_ids: group_ids.add(group_id) with open(GROUP_IDS_FILE, 'w', encoding='utf-8') as f: f.write('\n'.join(map(str, group_ids))) # 监听机器人被加入群组的事件 async def track_groups(update: Update, context: ContextTypes.DEFAULT_TYPE): chat_member: ChatMemberUpdated = update.chat_member if chat_member.new_chat_member.user.id == context.bot.id and chat_member.new_chat_member.status in ['member', 'administrator']: save_group_id(update.effective_chat.id) print(f"已记录群组: {update.effective_chat.title} ({update.effective_chat.id})") # 发送随机消息函数 async def send_random_message(chat_id: int, context: ContextTypes.DEFAULT_TYPE): print(f"正在给群组 {chat_id} 发送消息...") with open('content.txt', 'r', encoding='utf-8') as file: content = file.read() elements = content.split('~') random_element = random.choice(elements) try: await context.bot.send_message(chat_id=chat_id, text=random_element) print(f"群组 {chat_id} 消息发送成功") except Exception as e: print(f"发送消息到群组 {chat_id} 失败: {str(e)}") # /start命令处理器 async def start_command(update: Update, context: ContextTypes.DEFAULT_TYPE): print("/start command received.") welcome_message = "Hello! I'm your bot. Here are the commands you can use:\n\n" commands = [ "/start - Start the bot and see the available commands", "/new - Get a random message" ] welcome_message += "\n".join(commands) await context.bot.send_message(chat_id=update.effective_chat.id, text=welcome_message) print("Welcome message sent.") # /new命令处理器 async def new_command(update: Update, context: ContextTypes.DEFAULT_TYPE): print("/new command received.") await send_random_message(update.effective_chat.id, context) # 定时任务:给所有群组发消息 async def scheduled_job(context: ContextTypes.DEFAULT_TYPE): print("定时任务启动...") group_ids = load_group_ids() if not group_ids: print("没有记录任何群组") return for group_id in group_ids: await send_random_message(group_id, context) print("定时任务完成.") # 注册处理器 application.add_handler(CommandHandler('start', start_command)) application.add_handler(CommandHandler('new', new_command)) application.add_handler(ChatMemberHandler(track_groups, ChatMemberHandler.CHAT_MEMBER)) # 设置定时任务 job_queue = application.job_queue job_queue.run_daily(scheduled_job, time=time(hour=22, minute=58), days=(0, 1, 2, 3, 4, 5, 6)) # 启动机器人 print("Bot is running...") application.run_polling()
关键修改说明
- 新增
ChatMemberHandler监听机器人入群事件,自动记录群组ID到本地文件,避免依赖get_updates - 定时任务直接读取本地存储的群组ID,不再抢占
run_polling的连接池资源 - 添加异常捕获,单个群组发送失败不会中断整个定时任务
- 调整连接池参数至合理值,避免资源浪费
内容的提问来源于stack exchange,提问作者Pavel Varenik
相关产品推荐
相关产品推荐

