python-telegram-bot v20.0定时转发Telegram消息失效求助
问题分析
你的代码存在三个核心问题导致定时转发任务无法执行:
- 事件循环不统一:
asyncio.run(send_message())会创建独立的事件循环,而AsyncIOScheduler默认绑定主线程的事件循环,两者不共享,导致调度任务无法触发。 - 主线程被阻塞:末尾的
while True: pass会彻底卡死主线程,调度器的事件循环完全没有运行任务的机会。 - 静态时间失效:
TIME在程序启动时就固定为某个过去的时间,当每日间隔任务触发时,新添加的date任务因时间已过期被直接跳过。
修复后的代码
from datetime import datetime, timedelta from apscheduler.schedulers.asyncio import AsyncIOScheduler from telegram import Bot import asyncio BOT = Bot("你的Bot Token") CHANNEL_FROM = "源频道ID" CHANNEL_TO = "目标频道ID" MESSAGE_ID = 97 async def prepare_message(): message_status = await BOT.forward_message( chat_id=CHANNEL_TO, from_chat_id=CHANNEL_FROM, message_id=MESSAGE_ID ) if message_status: print(f"Scheduled message {MESSAGE_ID} sent successfully.") async def send_message(): # 每次执行时动态计算10秒后的时间,避免时间过期 TIME = datetime.now() + timedelta(seconds=10) for i in range(2): scheduler.add_job(prepare_message, 'date', run_date=TIME) print(f"Added job to send message {MESSAGE_ID} from channel {CHANNEL_FROM} to channel {CHANNEL_TO} at {TIME}") # 即时转发测试 message_status = await BOT.forward_message( chat_id=CHANNEL_TO, from_chat_id=CHANNEL_FROM, message_id=MESSAGE_ID ) if message_status: print(f"Regular message {MESSAGE_ID} sent successfully") async def main(): global scheduler # 初始化调度器并指定时区,保持和任务时区一致 scheduler = AsyncIOScheduler(timezone="UTC") # 添加每日执行的间隔任务 scheduler.add_job(send_message, "interval", days=1, start_date="2022-01-01 00:00:00") scheduler.start() # 先执行一次send_message初始化任务 await send_message() # 用异步sleep保持程序运行,不阻塞事件循环 while True: await asyncio.sleep(3600) if __name__ == "__main__": asyncio.run(main())
关键修复说明
- 统一事件循环:将所有异步逻辑整合到
main函数中,通过asyncio.run(main())启动,确保调度器和任务在同一个事件循环内运行。 - 替换阻塞逻辑:用
await asyncio.sleep(3600)替代死循环,既维持程序运行,又不占用主线程资源,让调度器能正常执行任务。 - 动态生成时间:把
TIME的定义移到send_message函数内部,每次执行任务时重新计算目标时间,避免因时间过期导致任务被忽略。 - 明确时区配置:初始化调度器时指定
timezone="UTC",和间隔任务的时区保持一致,避免时间解析错误。
内容的提问来源于stack exchange,提问作者Fearless Lark
相关产品推荐
相关产品推荐

