Python Telegram Bot无法转发群组内图片、贴纸等媒体的修复咨询
我开发了一个Python Telegram Bot,用于将格式化文本、带说明的图片、视频、贴纸等消息转发到已添加该Bot的群组中。但目前遇到图片、贴纸及类似媒体内容无法转发的问题,尝试了所有已知方法仍未解决,以下是我的代码,请问该如何修复?
import telebot from telebot.types import Message bot_token = '(I hide it)' ALLOWED_USER_ID = 746422763 bot = telebot.TeleBot(bot_token) def is_bot_in_group(chat_id): with open('groups.txt', 'r') as file: existing_chat_ids = [line.strip() for line in file.readlines()] return str(chat_id) in existing_chat_ids def add_group(chat_id): with open('groups.txt', 'a') as file: file.write(str(chat_id) + '\n') existing_chat_ids = [] @bot.message_handler(func=lambda message: message.new_chat_members and bot.get_me().id in [user.id for user in message.new_chat_members]) def on_bot_added_to_group(message): chat_id = message.chat.id if not is_bot_in_group(chat_id): add_group(chat_id) @bot.message_handler(commands=['start']) def handle_start_command(message): user_id = message.from_user.id response = f"Бот запущен.\n\nТвой Telegram айди: {user_id}" bot.send_message(message.chat.id, response) @bot.message_handler(commands=['getgroups']) def handle_getgroups_command(message): user_id = message.from_user.id response = "Список групп, в которых находится бот:\n" chat_ids = get_existing_chat_ids() for chat_id in chat_ids: response += f"- Группа с айди {chat_id}\n" bot.send_message(user_id, response) @bot.message_handler(func=lambda message: message.chat.type == 'group') def handle_group_message(message): chat_id = message.chat.id if not is_bot_in_group(chat_id): add_group(chat_id) else: forward_message_to_groups(chat_id, message) @bot.message_handler(func=lambda message: message.chat.type == 'private') def handle_private_message(message): chat_ids = get_existing_chat_ids() for group_id in chat_ids: forward_message(group_id, message) def forward_message_to_groups(source_group_id, message): chat_ids = get_existing_chat_ids() for group_id in chat_ids: if group_id != str(source_group_id): forward_message(group_id, message) def forward_message(chat_id, message): if message.text: bot.send_message(chat_id, message.text, parse_mode='HTML') elif message.photo: for photo in message.photo: bot.send_photo(chat_id, photo.file_id) elif message.caption: for photo in message.photo: bot.send_photo(chat_id, photo.file_id, caption=message.caption) elif message.document: bot.send_document(chat_id, message.document.file_id) elif message.audio: bot.send_audio(chat_id, message.audio.file_id) elif message.voice: bot.send_voice(chat_id, message.voice.file_id) elif message.video: bot.send_video(chat_id, message.video.file_id) elif message.video_note: bot.send_video_note(chat_id, message.video_note.file_id) elif message.sticker: bot.send_sticker(chat_id, message.sticker.file_id) def get_existing_chat_ids(): with open('groups.txt', 'r') as file: existing_chat_ids = [line.strip() for line in file.readlines()] return existing_chat_ids def start_bot_in_groups(): updates = bot.get_updates() for update in updates: chat_id = update.message.chat.id chat_type = update.message.chat.type if chat_type == 'group' and not is_bot_in_group(chat_id): add_group(chat_id) bot.infinity_polling() bot.add_message_handler(on_bot_added_to_group) bot.add_message_handler(handle_start_command) bot.add_message_handler(handle_getgroups_command) bot.add_message_handler(handle_group_message) bot.add_message_handler(handle_private_message) start_bot_in_groups() bot.polling(none_stop=False, interval=0)
问题分析与修复方案
1. 媒体消息转发逻辑错误
原forward_message函数的条件分支顺序存在问题:带说明的图片会先进入message.photo分支,导致后续的message.caption分支永远无法执行;同时发送所有分辨率的图片属于冗余操作,只需选择最高分辨率的图片(列表最后一个元素)。此外,部分媒体类型未携带说明文字转发,需补充caption参数。
修复后的forward_message函数:
def forward_message(chat_id, message): if message.text: bot.send_message(chat_id, message.text, parse_mode='HTML') elif message.photo: # 选择最高分辨率的图片并附带说明文字 bot.send_photo(chat_id, message.photo[-1].file_id, caption=message.caption, parse_mode='HTML') elif message.document: bot.send_document(chat_id, message.document.file_id, caption=message.caption, parse_mode='HTML') elif message.audio: bot.send_audio(chat_id, message.audio.file_id, caption=message.caption, parse_mode='HTML') elif message.voice: bot.send_voice(chat_id, message.voice.file_id) elif message.video: bot.send_video(chat_id, message.video.file_id, caption=message.caption, parse_mode='HTML') elif message.video_note: bot.send_video_note(chat_id, message.video_note.file_id) elif message.sticker: bot.send_sticker(chat_id, message.sticker.file_id)
2. 重复启动Polling导致冲突
原代码中先后调用bot.infinity_polling()和bot.polling(),这会引发运行冲突,只能保留一个Polling启动方式。修改start_bot_in_groups函数并删除多余的Polling调用:
def start_bot_in_groups(): updates = bot.get_updates() for update in updates: if update.message: chat_id = update.message.chat.id chat_type = update.message.chat.type if chat_type == 'group' and not is_bot_in_group(chat_id): add_group(chat_id) # 仅保留一个持久化Polling bot.infinity_polling(none_stop=True, interval=0)
同时删除代码最后一行的bot.polling(none_stop=False, interval=0)。
3. 冗余Handler注册引发逻辑混乱
原代码同时使用@bot.message_handler装饰器和bot.add_message_handler()手动注册Handler,重复注册会导致消息处理逻辑紊乱,需删除所有bot.add_message_handler()调用,仅保留装饰器注册方式。
4. 私人消息权限控制(可选但建议)
原代码中ALLOWED_USER_ID未生效,任何人都能通过私人聊天向群组转发消息,建议在handle_private_message中添加权限验证:
@bot.message_handler(func=lambda message: message.chat.type == 'private') def handle_private_message(message): if message.from_user.id != ALLOWED_USER_ID: bot.send_message(message.chat.id, "你没有权限使用此功能。") return chat_ids = get_existing_chat_ids() for group_id in chat_ids: forward_message(group_id, message)
内容的提问来源于stack exchange,提问作者S1ngle

