Telegram Bot未按预期重发历史消息问题求助
Telegram Bot无法转发指定用户消息的问题修复
核心问题分析
- 非法方法调用:代码中使用的
bot.get_chat_member_messages并非python-telegram-bot库的有效方法,Telegram Bot API也没有提供直接获取某用户频道消息的接口,这是导致无法获取消息的根本原因。 - 错误的成员判断逻辑:
members.can_send_messages不是ChatMember对象的合法属性,原判断会直接跳过后续代码,应通过members.status验证用户是否为频道成员(如status in ['member', 'administrator', 'creator'])。 - 无错误反馈机制:缺少异常捕获代码,运行出错时无法看到报错信息,难以定位问题。
- 转发目标错误:原代码将消息转发回源频道,不符合“转发至本人及两个频道”的需求,同时重复获取file_id属于冗余操作。
修正后的代码
from telegram import Bot from telegram.ext import Updater import logging # 配置日志,捕获运行错误与状态信息 logging.basicConfig( format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO ) logger = logging.getLogger(__name__) # 填写你的配置信息 TOKEN = '你的Bot令牌' SOURCE_CHANNEL_ID = '源频道ID' # 要提取消息的频道ID TARGET_CHATS = ['你的个人账号ID', '目标频道1ID', '目标频道2ID'] # 转发目标列表 TARGET_USER_ID = '指定用户ID' # 需要提取消息的用户ID def fetch_and_forward_messages(bot: Bot): try: # 验证目标用户是否在源频道内 member = bot.get_chat_member(chat_id=SOURCE_CHANNEL_ID, user_id=TARGET_USER_ID) if member.status not in ['member', 'administrator', 'creator']: logger.error("目标用户不属于该频道") return collected_count = 0 offset_id = 0 # 消息偏移ID,用于分页获取历史消息 # 循环获取历史消息,直到收集够10条目标用户的消息 while collected_count < 10: # 批量获取频道历史消息,每次最多100条 messages = bot.get_chat_history(chat_id=SOURCE_CHANNEL_ID, limit=100, offset_id=offset_id) if not messages: break # 无更多消息时退出循环 for msg in messages: # 确认消息来自目标用户 if msg.from_user and msg.from_user.id == int(TARGET_USER_ID): # 只处理带字幕的图片或视频 if (msg.photo and msg.caption) or (msg.video and msg.caption): caption = msg.caption # 转发到所有目标聊天 for chat_id in TARGET_CHATS: try: if msg.photo: # 发送最高分辨率的图片(取photo列表最后一项) photo_id = msg.photo[-1].file_id bot.send_photo(chat_id=chat_id, photo=photo_id, caption=caption) elif msg.video: video_id = msg.video.file_id bot.send_video(chat_id=chat_id, video=video_id, caption=caption) logger.info(f"消息已转发至 {chat_id}") except Exception as e: logger.error(f"转发到 {chat_id} 失败: {str(e)}") collected_count += 1 if collected_count >= 10: break # 更新偏移ID,避免重复获取同一批消息 offset_id = messages[-1].id except Exception as e: logger.error(f"执行出错: {str(e)}") def start_bot(): try: bot = Bot(token=TOKEN) # 执行消息提取与转发逻辑 fetch_and_forward_messages(bot=bot) # 启动Bot轮询(如果需要Bot持续运行则保留,否则可删除此段) updater = Updater(bot=bot, use_context=True) updater.start_polling() updater.idle() except Exception as e: logger.error(f"Bot启动失败: {str(e)}") if __name__ == '__main__': start_bot()
关键修改说明
- 日志系统:添加logging配置,实时打印运行状态与错误信息,便于排查问题。
- 消息获取逻辑:通过
get_chat_history分页遍历频道历史消息,手动筛选目标用户的消息,解决原代码中非法方法调用的问题。 - 成员验证修正:使用
member.status判断用户是否为频道有效成员,确保后续逻辑正常执行。 - 转发目标调整:将转发目标改为包含个人ID与两个频道的列表,符合需求。
- 异常捕获:在API调用、消息转发等环节添加异常捕获,避免程序静默崩溃。
- 逻辑优化:循环收集消息直到满10条,避免遗漏;复用file_id减少冗余操作。
内容的提问来源于stack exchange,提问作者Uai_rafah
相关产品推荐
相关产品推荐

